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

  1. /* macos.c -- operating system dependant mpack code for the Macintosh
  2.  *
  3.  * (C) Copyright 1993 by Christopher J. Newman
  4.  * All Rights Reserved.
  5.  *
  6.  * Permission to use, copy, modify, distribute, and sell this software and its
  7.  * documentation for any purpose is hereby granted without fee, provided that
  8.  * the above copyright notice appear in all copies and that both that
  9.  * copyright notice and this permission notice appear in supporting
  10.  * documentation, and that the name of Christopher J. Newman not be used in
  11.  * advertising or publicity pertaining to distribution of the software without
  12.  * specific, written prior permission.  Christopher J. Newman makes no
  13.  * representations about the suitability of this software for any purpose.  It
  14.  * is provided "as is" without express or implied warranty.
  15.  *
  16.  * CHRISTOPHER J. NEWMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  17.  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
  18.  * SHALL CHRISTOPHER J. NEWMAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  19.  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
  20.  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  21.  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
  22.  * OF THIS SOFTWARE.
  23.  */
  24.  
  25. #include <stdio.h>
  26. #include <ctype.h>
  27. #include <string.h>
  28. #include <errno.h>
  29. #include "common.h"
  30. #include "macnapp.h"
  31. #include "macmpack.h"
  32.  
  33. extern char *malloc(), *realloc();
  34.  
  35. char *xmalloc(unsigned size)
  36. {
  37.     char *ret;
  38.  
  39.     if (ret = malloc((unsigned) size))
  40.       return ret;
  41.  
  42.     yell("Virtual memory exhausted");
  43.     exit(1);
  44. }
  45.  
  46. char *xrealloc (char *ptr, unsigned size)
  47. {
  48.     char *ret;
  49.  
  50.     /* xrealloc (NULL, size) behaves like xmalloc (size), as in ANSI C */
  51.     if (ret = !ptr ? malloc ((unsigned) size) : realloc (ptr, (unsigned) size))
  52.       return ret;
  53.  
  54.     yell("Virtual memory exhausted");
  55.     exit(1);
  56. }
  57.  
  58. char *strsave(char *str)
  59. {
  60.     char *p = xmalloc(strlen(str)+1);
  61.     strcpy(p, str);
  62.     return p;
  63. }
  64.  
  65. /* save output filename buffer */
  66. static char *output_fname = NULL;
  67.  
  68. /* TMPL resource for IDna -- ID to name mappings
  69.  */
  70. char TMPL[] = {
  71.     16 , 'D', 'i', 'r', 'e', 'c', 't', 'o',
  72.     'r', 'y', ' ', 'N', 'u', 'm', 'b', 'e',
  73.     'r', 'D', 'W', 'R', 'D'
  74. };
  75.  
  76. /* Generate a message-id */
  77. char *os_genid()
  78. {
  79.     char *result;
  80.     long tick;
  81.     unsigned long time;
  82.  
  83.     tick = TickCount();
  84.     result = malloc(64);
  85.     GetDateTime(&time);
  86.     HLock((Handle) mpack_prefs);
  87.     sprintf(result, "%lu.%lu@%s", tick, time, (*mpack_prefs)->internet_host);
  88.     HUnlock((Handle) mpack_prefs);
  89.     
  90.     /* make sure tick count is bumped before we return... */
  91.     while (tick == TickCount());
  92.     
  93.     return (result);
  94. }
  95.  
  96. /* Create and return directory for a message-id
  97.  */
  98. char *os_idtodir(id)
  99. char *id;
  100. {
  101.     static PCstr buf[257];
  102.     static unsigned char mpackdir[] = "\pmpack-tmp";
  103.     PCstr idbuf[257];
  104.     char *fname;
  105.     short wrefnum, vrefnum, resfile, uqid, createflag = 0;
  106.     long dirid, procid;
  107.     OSErr err;
  108.     Handle h;
  109.     ResType type = 'IDna';
  110.     FInfo finfo;
  111.  
  112.     /* get name of default volume */
  113.     if (GetVol(P(buf), &wrefnum) != noErr) return (NULL);
  114.     procid = 0;
  115.     if (GetWDInfo(wrefnum, &vrefnum, &dirid, &procid) != noErr) return (NULL);
  116.     
  117.     /* try creating tmp dir */
  118.     err = DirCreate(vrefnum, 0, mpackdir, &dirid);
  119.     if (err != noErr && err != dupFNErr) return (NULL);
  120.     CtoPCstrcat(buf, ":");
  121.     PtoPCstrcat(buf, (char *) mpackdir);
  122.     CtoPCstrcat(buf, ":");
  123.     fname = C(buf) + PCstrlen(buf);
  124.     
  125.     /* open the map file */
  126.     strcpy(fname, "map");
  127.     SetPlen(buf);
  128.     CreateResFile(P(buf));
  129.     if ((err = ResError()) == noErr && GetFInfo(P(buf), vrefnum, &finfo) == noErr) {
  130.         finfo.fdType = 'rsrc';
  131.         finfo.fdCreator = 'RSED';
  132.         SetFInfo(P(buf), vrefnum, &finfo);
  133.     }
  134.     if ((resfile = OpenResFile(P(buf))) < 0) return (NULL);
  135.     if (err == noErr && PtrToHand((Ptr) TMPL, &h, sizeof (TMPL)) == noErr) {
  136.         AddResource(h, 'TMPL', 1000, "\pIDna");
  137.     }
  138.     
  139.     /* is there a mapping for the id? */
  140.     CtoPCstrcpy(idbuf, id);
  141.     h = GetNamedResource(type, P(idbuf));
  142.     
  143.     /* no mapping -- create one */
  144.     if (!h) {
  145.         createflag = 1;
  146.         while ((uqid = UniqueID(type)) < 128);
  147.         h = NewHandle(sizeof (short));
  148.         if (h) (**(short **)h) = uqid;
  149.         AddResource(h, type, uqid, P(idbuf));
  150.         if ((err = ResError()) != noErr) {
  151.             CloseResFile(resfile);
  152.             return (NULL);
  153.         }
  154.     } else {
  155.         uqid = ** (short **) h;
  156.     }
  157.     
  158.     /* set directory name & create it */
  159.     sprintf(fname, "%d:", uqid);
  160.     SetPlen(buf);
  161.     err = DirCreate(vrefnum, 0, P(buf), &dirid);
  162.     if (err != noErr && err != dupFNErr) {
  163.         RmveResource(h);
  164.         DisposHandle(h);
  165.         h = NULL;
  166.     }
  167.  
  168.     /* done with map file */
  169.     CloseResFile(resfile);
  170.     
  171.     return (h ? C(buf) : NULL);
  172. }
  173.  
  174. /*
  175.  * We are done with the directory returned by os_idtodir()
  176.  * Remove it
  177.  */
  178. os_donewithdir(dir)
  179. char *dir;
  180. {
  181.     PCstr buf[257];
  182.     short uqid, resfile;
  183.     char *fname;
  184.     Handle h;
  185.     
  186.     CtoPCstrcpy(buf, dir);
  187.     HDelete(0, 0, P(buf));
  188.     fname = strchr(C(buf), ':');
  189.     if (fname && (fname = strchr(fname + 1, ':'))) {
  190.         uqid = atoi(fname + 1);
  191.         strcpy(fname, ":map");
  192.         SetPlen(buf);
  193.         if ((resfile = OpenResFile(P(buf))) >= 0) {
  194.             h = GetResource('IDna', uqid);
  195.             if (h) {
  196.                 RmveResource(h);
  197.                 DisposHandle(h);
  198.             }
  199.             CloseResFile(resfile);
  200.         }
  201.     }
  202. }
  203.  
  204. /*
  205.  * Create a new file, with suggested filename "fname".
  206.  * "fname" may have come from an insecure source, so clean it up first.
  207.  * It may also be null.
  208.  * "contentType" is passed in for use by systems that have typed filesystems.
  209.  * "binary" is nonzero if the new file should be opened in binary mode.
  210.  */
  211. FILE *os_newtypedfile(fname, contentType, binary)
  212. char *fname;
  213. char *contentType;
  214. int binary;
  215. {
  216.     char *p;
  217.     static int filesuffix=0;
  218.     char buf[128], *descfname=0;
  219.     FILE *outfile = 0;
  220.     extern long _ftype, _fcreator;
  221.     extern Cursor watch;
  222.     Handle h;
  223.     PCstr tstr[257];
  224.  
  225.     if (!fname) fname = "";
  226.     
  227.     /* Translate ':' to underscore */
  228.     for (p=fname; *p; p++) {
  229.         if (*p == ':' || !isprint(*p)) *p = '_';
  230.     }
  231.     
  232.     /* chop filename to length */
  233.     if (strlen(fname) > 31) {
  234.         fname += strlen(fname) - 31;
  235.     }
  236.  
  237.     if (!fname[0]) {
  238.         do {
  239.             if (outfile) fclose(outfile);
  240.             sprintf(buf, "part%d", ++filesuffix);
  241.         } while (outfile = fopen(buf, "r"));
  242.         fname = buf;
  243.     }
  244.     else if (outfile = fopen(fname, "r")) {
  245.         CtoPCstrcpy(tstr, fname);
  246.         ParamText(P(tstr), NULL, NULL, NULL);
  247.         SetCursor(&arrow);
  248.         if (NAalert(replaceALRT) != iReplace) {
  249.             do {
  250.                 fclose(outfile);
  251.                 sprintf(buf, "%s.%d", fname, ++filesuffix);
  252.              
  253.             } while (outfile = fopen(buf, "r"));
  254.             fname = buf;
  255.         } else {
  256.             fclose(outfile);
  257.         }
  258.         SetCursor(&watch);
  259.     }
  260.  
  261.     /* set the type */
  262.     CtoPCstrcpy(tstr, contentType);
  263.     h = GetNamedResource('TyCr', P(tstr));
  264.     if (h) {
  265.         _ftype = (*(OSType **)h)[0];
  266.         _fcreator = (*(OSType **)h)[1];
  267.     } else {
  268.         _ftype = '????';
  269.     }
  270.  
  271.     /* save file */
  272.     outfile = fopen(fname, "wb");
  273.     if (!outfile) {
  274.         sprintf(buf, "Couldn't open file %s", fname);
  275.         warn(buf);
  276.         return (0);
  277.     }
  278.  
  279.     if (output_fname) free(output_fname);
  280.     output_fname = strsave(fname);
  281.  
  282.     if (strlen(fname) > sizeof(buf)-6) {
  283.         descfname = xmalloc(strlen(fname)+6);
  284.     }
  285.     else {
  286.         descfname = buf;
  287.     }
  288.     strcpy(descfname, fname);
  289.  
  290.     if (p = strrchr(descfname, '.')) *p = '\0';
  291.  
  292.     strcat(descfname, ".desc");
  293.     (void) rename(TEMPFILENAME, descfname);
  294.     if (descfname != buf) free(descfname);
  295.     CtoPstr(descfname);
  296.     _ftype = 'TEXT';
  297.     _fcreator = 'mPAK';
  298.  
  299.     return outfile;
  300. }
  301.  
  302. /*
  303.  * Warn user that the MD5 digest of the last file created by os_newtypedfile()
  304.  * did not match that supplied in the Content-MD5: header.
  305.  */
  306. os_warnMD5mismatch()
  307. {
  308.     char *warning;
  309.  
  310.     warning = xmalloc(strlen(output_fname) + 100);
  311.     sprintf(warning, "%s was corrupted in transit",
  312.         output_fname);
  313.     warn(warning);
  314.     free(warning);
  315. }
  316.  
  317. /* bring up an error dialog for a file error
  318.  */
  319. void os_perror(char *str)
  320. {
  321.     extern int errno;
  322.     char *err = strerror(errno), *scan;
  323.     char msg[256];
  324.     short maxflen;
  325.     
  326.     maxflen = 255 - (strlen(err) + 2);
  327.     if (strlen(str) > maxflen) {
  328.         str += strlen(str) - maxflen;
  329.         for (scan = str; *scan && *scan++ != ':';);
  330.         if (*scan) str = scan;
  331.     }
  332.     sprintf(msg, "%s: %s", str, err);
  333.     yell(msg);
  334. }
  335.