home *** CD-ROM | disk | FTP | other *** search
/ Dream 52 / Amiga_Dream_52.iso / Amiga / Workbench / Archivers / mpackWOS.lha / mpackppc / src / unixos.c < prev    next >
C/C++ Source or Header  |  1998-04-08  |  6KB  |  266 lines

  1. /* (C) Copyright 1993,1994 by Carnegie Mellon University
  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 Carnegie
  9.  * Mellon University not be used in advertising or publicity
  10.  * pertaining to distribution of the software without specific,
  11.  * written prior permission.  Carnegie Mellon University makes no
  12.  * representations about the suitability of this software for any
  13.  * purpose.  It is provided "as is" without express or implied
  14.  * warranty.
  15.  *
  16.  * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
  17.  * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  18.  * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
  19.  * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  20.  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
  21.  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
  22.  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  23.  * SOFTWARE.
  24.  */
  25. #include <stdio.h>
  26. #include <ctype.h>
  27. #include <string.h>
  28. #include <errno.h>
  29. #include <sys/types.h>
  30. #include <sys/param.h>
  31. #include <netdb.h>
  32. #include "xmalloc.h"
  33. #include "common.h"
  34.  
  35. #ifndef MAXHOSTNAMELEN
  36. #define MAXHOSTNAMELEN 64
  37. #endif
  38.  
  39. extern int errno;
  40. extern char *malloc();
  41. extern char *getenv();
  42.  
  43. int overwrite_files = 0;
  44. int didchat;
  45.  
  46. /* The name of the file we're writing */
  47. static char *output_fname = 0;
  48.  
  49. /* Characters that shouldn't be in filenames */
  50. #define BADCHARS "!$&*()|\'\";<>[]{}?/`\\ \t"
  51.  
  52. /* Generate a message-id */
  53. char *os_genid()
  54. {
  55.     static int pid = 0;
  56.     static time_t curtime;
  57.     static char hostname[MAXHOSTNAMELEN+1];
  58.     char *result;
  59.     struct hostent *hp;
  60.     
  61.  
  62.     if (pid == 0) {
  63.     pid = getpid();
  64.     time(&curtime);
  65.     gethostname(hostname, sizeof(hostname));
  66.  
  67.     /* If we don't have a FQDN, try canonicalizing with gethostbyname */
  68.     if (!strchr(hostname, '.')) {
  69.         hp = gethostbyname(hostname);
  70.         if (hp) {
  71.         strcpy(hostname, hp->h_name);
  72.         }
  73.     }
  74.     }
  75.  
  76.     result = malloc(25+strlen(hostname));
  77.     sprintf(result, "%d.%d@%s", pid, curtime++, hostname);
  78.     return result;
  79. }
  80.  
  81. /* Create and return directory for a message-id */
  82. char *os_idtodir(id)
  83. char *id;
  84. {
  85.     static char buf[4096];
  86.     char *p;
  87.  
  88.     if (getenv("TMPDIR")) {
  89.     strcpy(buf, getenv("TMPDIR"));
  90.     }
  91.     else {
  92.     strcpy(buf, "/usr/tmp");
  93.     }
  94.     strcat(buf, "/m-prts-");
  95.     p = getenv("USER");
  96.     if (!p) p = getenv("LOGNAME");
  97.     if (!p) p = "x";
  98.     strcat(buf, p);
  99.     
  100.     (void)mkdir(buf, 0700);
  101.  
  102.     p = buf + strlen(buf);
  103.     *p++ = '/';
  104.     while (*id && p < buf+sizeof(buf)-10 ) {
  105.     if (isprint(*id) && !strchr(BADCHARS, *id)) *p++ = *id;
  106.     id++;
  107.     }
  108.     *p = '\0';
  109.     if (mkdir(buf, 0700) == -1 && errno != EEXIST) {
  110.     perror(buf);
  111.     return 0;
  112.     }
  113.     *p++ = '/';
  114.     *p = '\0';
  115.     return buf;
  116. }
  117.  
  118. /*
  119.  * We are done with the directory returned by os_idtodir()
  120.  * Remove it
  121.  */
  122. os_donewithdir(dir)
  123. char *dir;
  124. {
  125.     char *p;
  126.  
  127.     /* Remove trailing slash */
  128.     p = dir + strlen(dir) - 1;
  129.     *p = '\0';
  130.  
  131.     rmdir(dir);
  132. }
  133.  
  134. /*
  135.  * Create a new file, with suggested filename "fname".
  136.  * "fname" may have come from an insecure source, so clean it up first.
  137.  * It may also be null.
  138.  * "contentType" is passed in for use by systems that have typed filesystems.
  139.  * "flags" contains a bit pattern describing attributes of the new file.
  140.  */
  141. FILE *os_newtypedfile(fname, contentType, flags, contentParams)
  142. char *fname;
  143. char *contentType;
  144. int flags;
  145. params contentParams;
  146. {
  147.     char *p;
  148.     static int filesuffix=0;
  149.     char buf[128], *descfname=0;
  150.     FILE *outfile = 0;
  151.  
  152.     if (!fname) fname = "";
  153.  
  154.     /* If absolute path name, chop to tail */
  155.     if (*fname == '/') {
  156.     p = strrchr(fname, '/');
  157.     fname = p+1;
  158.     }
  159.  
  160.     /* Get rid of leading ~ or ~/ */
  161.     while (*fname == '~' || *fname == '/') fname++;
  162.     
  163.     /* Clean out bad characters, create directories along path */
  164.     for (p=fname; *p; p++) {
  165.     if (*p == '/') {
  166.         if (!strncmp(p, "/../", 4)) {
  167.         p[1] = p[2] = 'X';
  168.         }
  169.         *p = '\0';
  170.         (void) mkdir(fname, 0777);
  171.         *p = '/';
  172.     }
  173.     else if (!isprint(*p) || strchr(BADCHARS, *p)) *p = 'X';
  174.     }
  175.  
  176.     if (!fname[0]) {
  177.     do {
  178.         if (outfile) fclose(outfile);
  179.         sprintf(buf, "part%d", ++filesuffix);
  180.     } while (outfile = fopen(buf, "r"));
  181.     fname = buf;
  182.     }
  183.     else if (!overwrite_files && (outfile = fopen(fname, "r"))) {
  184.     do {
  185.         fclose(outfile);
  186.         sprintf(buf, "%s.%d", fname, ++filesuffix);
  187.      
  188.     } while (outfile = fopen(buf, "r"));
  189.     fname = buf;
  190.     }
  191.  
  192.     outfile = fopen(fname, "w");
  193.     if (!outfile) {
  194.     perror(fname);
  195.     }
  196.  
  197.     if (output_fname) free(output_fname);
  198.     output_fname = strsave(fname);
  199.  
  200.     if (strlen(fname) > sizeof(buf)-6) {
  201.     descfname = xmalloc(strlen(fname)+6);
  202.     }
  203.     else {
  204.     descfname = buf;
  205.     }
  206.     strcpy(descfname, fname);
  207.  
  208.     p = strchr(descfname, '/');
  209.     if (!p) p = descfname;
  210.     if (p = strrchr(p, '.')) *p = '\0';
  211.  
  212.     strcat(descfname, ".desc");
  213.     (void) rename(TEMPFILENAME, descfname);
  214.     if (descfname != buf) free(descfname);
  215.     
  216.     fprintf(stdout, "%s (%s)\n", output_fname, contentType);
  217.     didchat = 1;
  218.  
  219.     return outfile;
  220. }
  221.  
  222. /*
  223.  * Close a file opened by os_newTypedFile()
  224.  */
  225. os_closetypedfile(outfile)
  226. FILE *outfile;
  227. {
  228.     fclose(outfile);
  229. }
  230.  
  231. /*
  232.  * (Don't) Handle a BinHex'ed file
  233.  */
  234. int
  235. os_binhex(inpart, part, nparts)
  236. struct part *inpart;
  237. int part;
  238. int nparts;
  239. {
  240.     return 1;
  241. }
  242.  
  243. /*
  244.  * Warn user that the MD5 digest of the last file created by os_newtypedfile()
  245.  * did not match that supplied in the Content-MD5: header.
  246.  */
  247. os_warnMD5mismatch()
  248. {
  249.     char *warning;
  250.  
  251.     warning = xmalloc(strlen(output_fname) + 100);
  252.     sprintf(warning, "%s was corrupted in transit",
  253.         output_fname);
  254.     warn(warning);
  255.     free(warning);
  256. }
  257.  
  258. /*
  259.  * Report an error (in errno) concerning a filename
  260.  */
  261. os_perror(file)
  262. char *file;
  263. {
  264.     perror(file);
  265. }
  266.