home *** CD-ROM | disk | FTP | other *** search
/ back2roots/padua / padua.7z / padua / uucp / MPack1_2_1.lha / MPack / src / unixos.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-01-05  |  5.5 KB  |  237 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 <ctype.h>
  25. #include <string.h>
  26. #include <errno.h>
  27. #include <sys/types.h>
  28. #include <sys/param.h>
  29. #include <netdb.h>
  30. #include "xmalloc.h"
  31. #include "common.h"
  32.  
  33. #ifndef MAXHOSTNAMELEN
  34. #define MAXHOSTNAMELEN 64
  35. #endif
  36.  
  37. extern int errno;
  38. extern char *malloc();
  39. extern char *getenv();
  40.  
  41. int overwrite_files = 0;
  42.  
  43. /* The name of the file we're writing */
  44. static char *output_fname = 0;
  45.  
  46. /* Characters that shouldn't be in filenames */
  47. #define BADCHARS "!$&*()|\'\";<>[]{}?/`\\ \t"
  48.  
  49. /* Generate a message-id */
  50. char *os_genid()
  51. {
  52.     static int pid = 0;
  53.     static time_t curtime;
  54.     static char hostname[MAXHOSTNAMELEN+1];
  55.     char *result;
  56.     struct hostent *hp;
  57.     
  58.  
  59.     if (pid == 0) {
  60.     pid = getpid();
  61.     time(&curtime);
  62.     gethostname(hostname, sizeof(hostname));
  63.  
  64.     /* If we don't have a FQDN, try canonicalizing with gethostbyname */
  65.     if (!strchr(hostname, '.')) {
  66.         hp = gethostbyname(hostname);
  67.         if (hp) {
  68.         strcpy(hostname, hp->h_name);
  69.         }
  70.     }
  71.     }
  72.  
  73.     result = malloc(25+strlen(hostname));
  74.     sprintf(result, "%d.%d@%s", pid, curtime++, hostname);
  75.     return result;
  76. }
  77.  
  78. /* Create and return directory for a message-id */
  79. char *os_idtodir(id)
  80. char *id;
  81. {
  82.     static char buf[4096];
  83.     char *p;
  84.  
  85.     if (getenv("TMPDIR")) {
  86.     strcpy(buf, getenv("TMPDIR"));
  87.     }
  88.     else {
  89.     strcpy(buf, "/tmp");
  90.     }
  91.     strcat(buf, "/message-parts-");
  92.     strcat(buf, getenv("USER"));
  93.     
  94.     (void)mkdir(buf, 0700);
  95.  
  96.     p = buf + strlen(buf);
  97.     *p++ = '/';
  98.     while (*id) {
  99.     if (isprint(*id) && !strchr(BADCHARS, *id)) *p++ = *id;
  100.     id++;
  101.     }
  102.     *p = '\0';
  103.     if (mkdir(buf, 0700) == -1 && errno != EEXIST) {
  104.     perror(buf);
  105.     return 0;
  106.     }
  107.     *p++ = '/';
  108.     *p = '\0';
  109.     return buf;
  110. }
  111.  
  112. /*
  113.  * We are done with the directory returned by os_idtodir()
  114.  * Remove it
  115.  */
  116. os_donewithdir(dir)
  117. char *dir;
  118. {
  119.     char *p;
  120.  
  121.     /* Remove trailing slash */
  122.     p = dir + strlen(dir) - 1;
  123.     *p = '\0';
  124.  
  125.     rmdir(dir);
  126. }
  127.  
  128. /*
  129.  * Create a new file, with suggested filename "fname".
  130.  * "fname" may have come from an insecure source, so clean it up first.
  131.  * It may also be null.
  132.  * "contentType" is passed in for use by systems that have typed filesystems.
  133.  * "binary" is nonzero if the new file should be opened in binary mode.
  134.  */
  135. FILE *os_newtypedfile(fname, contentType, binary)
  136. char *fname;
  137. char *contentType;
  138. int binary;
  139. {
  140.     char *p;
  141.     static int filesuffix=0;
  142.     char buf[128], *descfname=0;
  143.     FILE *outfile = 0;
  144.  
  145.     if (!fname) fname = "";
  146.  
  147.     /* If absolute path name, chop to tail */
  148.     if (*fname == '/') {
  149.     p = strrchr(fname, '/');
  150.     fname = p+1;
  151.     }
  152.  
  153.     /* Get rid of leading ~ or ~/ */
  154.     while (*fname == '~' || *fname == '/') fname++;
  155.     
  156.     /* Clean out bad characters, create directories along path */
  157.     for (p=fname; *p; p++) {
  158.     if (*p == '/') {
  159.         if (!strncmp(p, "/../", 4)) {
  160.         p[1] = p[2] = 'X';
  161.         }
  162.         *p = '\0';
  163.         (void) mkdir(fname, 0777);
  164.         *p = '/';
  165.     }
  166.     else if (!isprint(*p) || strchr(BADCHARS, *p)) *p = 'X';
  167.     }
  168.  
  169.     if (!fname[0]) {
  170.     do {
  171.         if (outfile) fclose(outfile);
  172.         sprintf(buf, "part%d", ++filesuffix);
  173.     } while (outfile = fopen(buf, "r"));
  174.     fname = buf;
  175.     }
  176.     else if (!overwrite_files && (outfile = fopen(fname, "r"))) {
  177.     do {
  178.         fclose(outfile);
  179.         sprintf(buf, "%s.%d", fname, ++filesuffix);
  180.      
  181.     } while (outfile = fopen(buf, "r"));
  182.     fname = buf;
  183.     }
  184.  
  185.     outfile = fopen(fname, "w");
  186.     if (!outfile) {
  187.     perror(fname);
  188.     }
  189.  
  190.     if (output_fname) free(output_fname);
  191.     output_fname = strsave(fname);
  192.  
  193.     if (strlen(fname) > sizeof(buf)-6) {
  194.     descfname = xmalloc(strlen(fname)+6);
  195.     }
  196.     else {
  197.     descfname = buf;
  198.     }
  199.     strcpy(descfname, fname);
  200.  
  201.     p = strchr(descfname, '/');
  202.     if (!p) p = descfname;
  203.     if (p = strrchr(p, '.')) *p = '\0';
  204.  
  205.     strcat(descfname, ".desc");
  206.     (void) rename(TEMPFILENAME, descfname);
  207.     if (descfname != buf) free(descfname);
  208.     
  209.     fprintf(stdout, "%s (%s)\n", output_fname, contentType);
  210.  
  211.     return outfile;
  212. }
  213.  
  214. /*
  215.  * Warn user that the MD5 digest of the last file created by os_newtypedfile()
  216.  * did not match that supplied in the Content-MD5: header.
  217.  */
  218. os_warnMD5mismatch()
  219. {
  220.     char *warning;
  221.  
  222.     warning = xmalloc(strlen(output_fname) + 100);
  223.     sprintf(warning, "%s was corrupted in transit",
  224.         output_fname);
  225.     warn(warning);
  226.     free(warning);
  227. }
  228.  
  229. /*
  230.  * Report an error (in errno) concerning a filename
  231.  */
  232. os_perror(file)
  233. char *file;
  234. {
  235.     perror(file);
  236. }
  237.