home *** CD-ROM | disk | FTP | other *** search
/ back2roots/padua / padua.7z / padua / uucp / MPack1_2_1.lha / MPack / src / dosos.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-01-05  |  5.6 KB  |  243 lines

  1. /* (C) Copyright 1993 by John G. Myers
  2.  * All Rights Reserved.
  3.  *
  4.  * Permission to use, copy, modify, distribute, and sell this software
  5.  * and its documentation for any purpose is hereby granted without
  6.  * fee, provided that the above copyright notice appear in all copies
  7.  * and that both that copyright notice and this permission notice
  8.  * appear in supporting documentation, and that the name of John G.
  9.  * Myers not be used in advertising or publicity pertaining to
  10.  * distribution of the software without specific, written prior
  11.  * permission.  John G. Myers makes no representations about the
  12.  * suitability of this software for any purpose.  It is provided "as
  13.  * is" without express or implied warranty.
  14.  *
  15.  * JOHN G. MYERS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
  16.  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  17.  * FITNESS, IN NO EVENT SHALL JOHN G. MYERS BE LIABLE FOR ANY SPECIAL,
  18.  * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
  19.  * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  20.  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
  21.  * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  22.  */
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include <ctype.h>
  26. #include <string.h>
  27. #include <errno.h>
  28. #include <sys/types.h>
  29. #include "xmalloc.h"
  30. #include "common.h"
  31.  
  32. extern int errno;
  33.  
  34. int overwrite_files = 0;
  35.  
  36. /* The name of the file we're writing */
  37. static char *output_fname = 0;
  38.  
  39. /* Characters that can be in filenames */
  40. #define GOODCHARS "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"
  41.  
  42. /* Generate a message-id */
  43. char *os_genid()
  44. {
  45.     static time_t curtime;
  46.     static char *hostname;
  47.     char *result;
  48.  
  49.     if (curtime == 0) {
  50.     time(&curtime);
  51.  
  52.     hostname = getenv("HOSTNAME");
  53.     if (!hostname) hostname="random-pc";
  54.     }
  55.  
  56.     result = xmalloc(25+strlen(hostname));
  57.     sprintf(result, "%lu@%s", curtime++, hostname);
  58.     return result;
  59. }
  60.  
  61. /* Create and return directory for a message-id */
  62. char *os_idtodir(id)
  63. char *id;
  64. {
  65.     static char buf[4096];
  66.     int len = 0;
  67.     char *p;
  68.  
  69.     if (getenv("TMP")) {
  70.     strcpy(buf, getenv("TMP"));
  71.     }
  72.     else {
  73.     strcpy(buf, "\\tmp");
  74.     (void)mkdir(buf);
  75.     }
  76.     strcat(buf, "\\parts");
  77.     (void)mkdir(buf);
  78.  
  79.     p = buf + strlen(buf);
  80.     *p++ = '\\';
  81.  
  82.     while (*id && len < 11) {
  83.     if (strchr(GOODCHARS, *id)) {
  84.         if (len++ == 8) *p++ = '.';
  85.         *p++ = *id;
  86.     }
  87.     id++;
  88.     }
  89.     *p = '\0';
  90.     if (mkdir(buf) == -1 && errno != EACCES) {
  91.     perror(buf);
  92.     return 0;
  93.     }
  94.     *p++ = '\\';
  95.     *p = '\0';
  96.     return buf;
  97. }
  98.  
  99. /*
  100.  * We are done with the directory returned by os_idtodir()
  101.  * Remove it
  102.  */
  103. os_donewithdir(dir)
  104. char *dir;
  105. {
  106.     char *p;
  107.  
  108.     /* Remove trailing slash */
  109.     p = dir + strlen(dir) - 1;
  110.     *p = '\0';
  111.  
  112.     rmdir(dir);
  113. }
  114.  
  115. /*
  116.  * Create a new file, with suggested filename "fname".
  117.  * "fname" may have come from an insecure source, so clean it up first.
  118.  * It may also be null.
  119.  * "contentType" is passed in for use by systems that have typed filesystems.
  120.  * "binary" is nonzero if the new file should be opened in binary mode.
  121.  */
  122. FILE *os_newtypedfile(fname, contentType, binary)
  123. char *fname;
  124. char *contentType;
  125. int binary;
  126. {
  127.     char *p, *q;
  128.     int len, sawdot;
  129.     static int filesuffix=0;
  130.     char buf[128], *descfname=0;
  131.     FILE *outfile = 0;
  132.  
  133.     if (!fname) fname = "";
  134.  
  135.     /* Chop off any drive specifier, convert / to \ */
  136.     if (*fname && fname[1] == ':') fname +=2;
  137.     for (p = fname; *p; p++) if (*p == '/') *p = '\\';
  138.  
  139.     /* If absolute path name, chop to tail */
  140.     if (*fname == '\\') {
  141.     p = strrchr(fname, '\\');
  142.     fname = p+1;
  143.     }
  144.  
  145.     /* Clean out bad characters, create directories along path */
  146.     for (p=q=fname, len=sawdot=0; *p; p++) {
  147.     if (*p == '\\') {
  148.         if (!strncmp(p, "\\..\\", 4)) {
  149.         p[1] = p[2] = 'X';
  150.         }
  151.         *q = '\0';
  152.         (void) mkdir(fname);
  153.         *q++ = '\\';
  154.         len = sawdot = 0;
  155.     }
  156.     else if (*p == '.' && !sawdot) {
  157.         *q++ = '.';
  158.         sawdot++;
  159.         len = 0;
  160.     }
  161.     else if (len < (sawdot ? 3 : 8) && strchr(GOODCHARS, *p)) {
  162.         *q++ = *p;
  163.         len++;
  164.     }
  165.     }
  166.     *q = '\0';
  167.  
  168.     if (!fname[0]) {
  169.     do {
  170.         if (outfile) fclose(outfile);
  171.         sprintf(buf, "part%d", ++filesuffix);
  172.     } while (outfile = fopen(buf, "r"));
  173.     fname = buf;
  174.     }
  175.     else if (!overwrite_files && (outfile = fopen(fname, "r"))) {
  176.     /* chop off suffix */
  177.     p = strrchr(fname, '\\');
  178.     if (!p) p = fname;
  179.     p = strchr(p, '.');
  180.     if (*p) *p = '\0';
  181.  
  182.     /* append unique number */
  183.     do {
  184.         fclose(outfile);
  185.         sprintf(buf, "%s.%d", fname, ++filesuffix);
  186.      
  187.     } while (outfile = fopen(buf, "r"));
  188.     fname = buf;
  189.     }
  190.  
  191.     outfile = fopen(fname, binary ? "wb" : "w");
  192.     if (!outfile) {
  193.     perror(fname);
  194.     }
  195.  
  196.     if (output_fname) free(output_fname);
  197.     output_fname = strsave(fname);
  198.  
  199.     if (strlen(fname) > sizeof(buf)-6) {
  200.     descfname = xmalloc(strlen(fname)+6);
  201.     }
  202.     else {
  203.     descfname = buf;
  204.     }
  205.     strcpy(descfname, fname);
  206.  
  207.     p = strrchr(descfname, '\\');
  208.     if (!p) p = descfname;
  209.     if (p = strrchr(p, '.')) *p = '\0';
  210.  
  211.     strcat(descfname, ".dsc");
  212.     (void) rename(TEMPFILENAME, descfname);
  213.     if (descfname != buf) free(descfname);
  214.     
  215.     fprintf(stdout, "%s (%s)\n", output_fname, contentType);
  216.  
  217.     return outfile;
  218. }
  219.  
  220. /*
  221.  * Warn user that the MD5 digest of the last file created by os_newtypedfile()
  222.  * did not match that supplied in the Content-MD5: header.
  223.  */
  224. os_warnMD5mismatch()
  225. {
  226.     char *warning;
  227.  
  228.     warning = xmalloc(strlen(output_fname) + 100);
  229.     sprintf(warning, "%s was corrupted in transit",
  230.         output_fname);
  231.     warn(warning);
  232.     free(warning);
  233. }
  234.  
  235. /*
  236.  * Report an error (in errno) concerning a filename
  237.  */
  238. os_perror(file)
  239. char *file;
  240. {
  241.     perror(file);
  242. }
  243.