Back to home page

MITgcm

 
 

    


File indexing completed on 2018-03-02 18:44:56 UTC

view on githubraw file Latest commit ec6cf3b0 on 2003-08-26 20:45:25 UTC
ec6cf3b09d Ed H*0001 /* macos.c -- operating system dependant mpack code for the Macintosh
                0002  */
                0003 /* (C) Copyright 1993-1995 by Carnegie Mellon University
                0004  * All Rights Reserved.
                0005  *
                0006  * Permission to use, copy, modify, distribute, and sell this software
                0007  * and its documentation for any purpose is hereby granted without fee,
                0008  * provided that the above copyright notice appear in all copies and
                0009  * that both that copyright notice and this permission notice appear in
                0010  * supporting documentation, and that the name of Carnegie Mellon University
                0011  * not be used in advertising or publicity pertaining to distribution of the
                0012  * software without specific, written prior permission.  Carnegie
                0013  * Mellon University makes no representations about the suitability of
                0014  * this software for any purpose.  It is provided "as is" without
                0015  * express or implied warranty.
                0016  *
                0017  * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
                0018  * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
                0019  * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
                0020  * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
                0021  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
                0022  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
                0023  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
                0024  * SOFTWARE.
                0025  */
                0026 
                0027 #include <stdio.h>
                0028 #include <ctype.h>
                0029 #include <string.h>
                0030 #include <errno.h>
                0031 #include "common.h"
                0032 #include "macnapp.h"
                0033 #include "macmpack.h"
                0034 
                0035 extern char *malloc(), *realloc();
                0036 
                0037 char copy_buf[COPY_BUFSIZE];
                0038 
                0039 char *xmalloc(unsigned size)
                0040 {
                0041     char *ret;
                0042 
                0043     if (ret = malloc((unsigned) size))
                0044       return ret;
                0045 
                0046     yell("Not enough memory available.");
                0047     maccleanup();
                0048     exit(1);
                0049 }
                0050 
                0051 char *xrealloc (char *ptr, unsigned size)
                0052 {
                0053     char *ret;
                0054 
                0055     /* xrealloc (NULL, size) behaves like xmalloc (size), as in ANSI C */
                0056     if (ret = !ptr ? malloc ((unsigned) size) : realloc (ptr, (unsigned) size))
                0057       return ret;
                0058 
                0059     yell("Not enough memory available");
                0060     maccleanup();
                0061     exit(1);
                0062 }
                0063 
                0064 char *strsave(char *str)
                0065 {
                0066     char *p = xmalloc(strlen(str)+1);
                0067     strcpy(p, str);
                0068     return p;
                0069 }
                0070 
                0071 /* save output filename buffer */
                0072 static char *output_fname = NULL;
                0073 static short applefile_flag = 0;
                0074 static FSSpec fspec;
                0075 
                0076 /* rename or copy a file to a new location
                0077  */
                0078 static void rename_or_copy(srcfname, dstfname, dstvol, dirid)
                0079     char *srcfname;
                0080     PCstr *dstfname;
                0081     short dstvol;
                0082     long dirid;
                0083 {
                0084     PCstr tstr[257];
                0085     short srefnum, drefnum;
                0086     long count;
                0087     WDPBRec wdpb;
                0088     HParamBlockRec hpb;
                0089     CMovePBRec cpb;
                0090     
                0091     wdpb.ioNamePtr = P(tstr);
                0092     if (PBHGetVol(&wdpb, FALSE) != noErr) return;
                0093     CtoPCstrcpy(tstr, srcfname);
                0094     if (HOpen(0, 0, P(tstr), fsRdPerm, &srefnum) != noErr) return;
                0095     if (GetEOF(srefnum, &count) == noErr && !count) {
                0096         FSClose(srefnum);
                0097         return;
                0098     }
                0099     if (wdpb.ioWDVRefNum == dstvol) {
                0100         /* files on same drive -- do a rename/move */
                0101         FSClose(srefnum);
                0102         hpb.fileParam.ioNamePtr = P(tstr);
                0103         hpb.fileParam.ioVRefNum = 0;
                0104         hpb.ioParam.ioMisc = (Ptr) P(dstfname);
                0105         hpb.fileParam.ioDirID = 0;
                0106         if (PBHRenameSync(&hpb) == noErr && wdpb.ioWDDirID != dirid) {
                0107             cpb.ioNamePtr = P(dstfname);
                0108             cpb.ioVRefNum = 0;
                0109             cpb.ioNewName = NULL;
                0110             cpb.ioNewDirID = dirid;
                0111             cpb.ioDirID = 0;
                0112             PBCatMoveSync(&cpb);
                0113         }
                0114     } else {
                0115         /* files on different drive -- do a copy */
                0116         if (HCreate(dstvol, dirid, P(dstfname), _fcreator, _ftype) != noErr) {
                0117             FSClose(srefnum);
                0118             return;
                0119         }
                0120         if (HOpen(dstvol, dirid, P(dstfname), fsWrPerm, &drefnum) != noErr) {
                0121             FSClose(srefnum);
                0122             HDelete(dstvol, dirid, P(dstfname));
                0123             return;
                0124         }
                0125         count = sizeof (copy_buf);
                0126         while (FSRead(srefnum, &count, (Ptr) copy_buf) != noErr && count > 0) {
                0127             FSWrite(drefnum, &count, (Ptr) copy_buf);
                0128             count = sizeof (copy_buf);
                0129         }
                0130         FSClose(srefnum);
                0131         FSClose(drefnum);
                0132     }
                0133 }
                0134 
                0135 /* Generate a message-id */
                0136 char *os_genid()
                0137 {
                0138     char *result;
                0139     long tick;
                0140     unsigned long time;
                0141 
                0142     tick = TickCount();
                0143     result = malloc(64);
                0144     GetDateTime(&time);
                0145     HLock((Handle) mpack_prefs);
                0146     sprintf(result, "%lu.%lu@%s", tick, time, (*mpack_prefs)->internet_host);
                0147     HUnlock((Handle) mpack_prefs);
                0148     
                0149     /* make sure tick count is bumped before we return... */
                0150     while (tick == TickCount());
                0151     
                0152     return (result);
                0153 }
                0154 
                0155 /* Create and return directory for a message-id
                0156  */
                0157 char *os_idtodir(id)
                0158 char *id;
                0159 {
                0160     static PCstr buf[257];
                0161     PCstr idbuf[257];
                0162     char *fname;
                0163     short uqid;
                0164     OSErr err;
                0165     long dirID;
                0166     Handle h;
                0167     ResType type = 'IDna';
                0168 
                0169     /* prepare filename */
                0170     PtoPCstrcpy(buf, (char *) P(pfolder->prefs));
                0171     fname = C(buf) + PCstrlen(buf);
                0172     
                0173     /* is there a mapping for the id? */
                0174     CtoPCstrcpy(idbuf, id);
                0175     h = GetNamedResource(type, P(idbuf));
                0176     
                0177     /* no mapping -- create one */
                0178     if (!h) {
                0179         while ((uqid = UniqueID(type)) < 128);
                0180         h = NewHandle(sizeof (short));
                0181         if (h) (**(short **)h) = uqid;
                0182         AddResource(h, type, uqid, P(idbuf));
                0183         if ((err = ResError()) != noErr) {
                0184             return (NULL);
                0185         }
                0186     } else {
                0187         uqid = ** (short **) h;
                0188     }
                0189     
                0190     /* set directory name & create it */
                0191     sprintf(fname, "%d:", uqid);
                0192     SetPlen(buf);
                0193     err = DirCreate(pfolder->fspec.vRefNum, 0, P(buf), &dirID);
                0194     if (err != noErr && err != dupFNErr) {
                0195         RmveResource(h);
                0196         DisposHandle(h);
                0197         h = NULL;
                0198     }
                0199     
                0200     return (h ? C(buf) : NULL);
                0201 }
                0202 
                0203 /*
                0204  * We are done with the directory returned by os_idtodir()
                0205  * Remove it
                0206  */
                0207 os_donewithdir(dir)
                0208 char *dir;
                0209 {
                0210     PCstr buf[257];
                0211     short uqid;
                0212     char *fname;
                0213     Handle h;
                0214     
                0215     CtoPCstrcpy(buf, dir);
                0216     HDelete(0, 0, P(buf));
                0217     fname = strrchr(C(buf), ':');
                0218     while (fname > C(buf) && *--fname != ':');
                0219     if (fname > C(buf)) {
                0220         uqid = atoi(fname + 1);
                0221         h = GetResource('IDna', uqid);
                0222         if (h) {
                0223             RmveResource(h);
                0224             DisposHandle(h);
                0225         }
                0226     }
                0227 }
                0228 
                0229 /* rename the description file
                0230  */
                0231 void renameDescFile(char *fname, short vRefNum, long dirid)
                0232 {
                0233     PCstr tstr[65];
                0234     char *p;
                0235 
                0236     MapTypeCreator("text/plain", 0);
                0237 
                0238     /* save description file */
                0239     CtoPCstrcpy(tstr, fname);
                0240     if (p = strrchr(C(tstr), '.')) *p = '\0';
                0241     strcat(C(tstr), ".desc");
                0242     SetPlen(tstr);
                0243     rename_or_copy(TEMPFILENAME, tstr, vRefNum, dirid);
                0244     (void) remove(TEMPFILENAME);
                0245 }
                0246 
                0247 FILE *os_createnewfile(fname) 
                0248 char *fname;
                0249 {
                0250     return fopen(fname, "w");
                0251 }
                0252 
                0253 /*
                0254  * Create a new file, with suggested filename "fname".
                0255  * "fname" may have come from an insecure source, so clean it up first.
                0256  * It may also be null.
                0257  * "contentType" is passed in for use by systems that have typed filesystems.
                0258  * "flags" contains a bit pattern describing attributes of the new file.
                0259  */
                0260 FILE *os_newtypedfile(fname, contentType, flags, contentParams)
                0261 char *fname;
                0262 char *contentType;
                0263 int flags;
                0264 params *contentParams;
                0265 {
                0266     char *p;
                0267     int applefile;
                0268     FILE *outfile = 0, *tmpf;
                0269     StandardFileReply reply;
                0270     PCstr tstr[257];
                0271 
                0272     if (!fname) fname = "";
                0273     
                0274     /* Translate ':' to underscore */
                0275     for (p=fname; *p; p++) {
                0276         if (*p == ':' || !isprint(*p)) *p = '_';
                0277     }
                0278     
                0279     /* chop filename to length */
                0280     if (strlen(fname) > 31) {
                0281         fname += strlen(fname) - 31;
                0282     }
                0283     
                0284     /* remove leading periods, to protect from ".SONY" attacks */
                0285     while (*fname == '.') ++fname;
                0286 
                0287     /* get filename from user */
                0288     applefile = !strcmp(contentType, "application/applefile");
                0289     if (!applefile || !(flags & FILE_INAPPLEDOUBLE)) {
                0290         sprintf(C(tstr), "Found file: %s (%s)",
                0291             fname[0] ? fname : "Untitled", contentType);
                0292         SetPlen(tstr);
                0293         stattext(P(tstr), 1);
                0294     }
                0295     if (!applefile && (!applefile_flag || !(flags & FILE_INAPPLEDOUBLE))) {
                0296         SetCursor(&arrow);
                0297         CtoPstr(fname);
                0298         NAputFile("\pSave decoded file as:",
                0299             fname[0] ? (unsigned char *) fname : "\pUntitled", &reply);
                0300         PtoCstr((unsigned char *) fname);
                0301         SetCursor(&watch);
                0302         statrefresh();
                0303         if (!reply.sfGood) {
                0304             didchat = -1;
                0305             return (NULL);
                0306         }
                0307     }
                0308 
                0309     /* set the type */
                0310     MapTypeCreator(contentType, 0);
                0311 
                0312     /* save file */
                0313     tmpf = tmpfile();
                0314     if (applefile) {
                0315         outfile = tmpf;
                0316         tmpf = NULL;
                0317     } else if ((flags & FILE_INAPPLEDOUBLE) && applefile_flag) {
                0318         outfile = Macopen(tmpf, fspec.name, fspec.vRefNum, fspec.parID,
                0319             flags & FILE_BINARY, 0, fsWrPerm);
                0320     } else {
                0321         HCreate(reply.sfFile.vRefNum, reply.sfFile.parID, reply.sfFile.name, _fcreator, _ftype);
                0322         outfile = Macopen(tmpf, reply.sfFile.name, reply.sfFile.vRefNum, reply.sfFile.parID,
                0323             flags & FILE_BINARY, 0, fsWrPerm);
                0324     }
                0325     applefile_flag = applefile;
                0326     if (tmpf) fclose(tmpf);
                0327     PtoCstr(reply.sfFile.name);
                0328     fname = (char *) reply.sfFile.name;
                0329     if (!outfile) {
                0330         sprintf(C(tstr), "Couldn't open file %s", fname);
                0331         warn(C(tstr));
                0332         return (0);
                0333     }
                0334     
                0335     if (output_fname) free(output_fname);
                0336     output_fname = strsave(fname);
                0337     
                0338     renameDescFile(fname, reply.sfFile.vRefNum, reply.sfFile.parID);
                0339 
                0340     return outfile;
                0341 }
                0342 
                0343 /*
                0344  * Close a file opened by os_newTypedFile()
                0345  */
                0346 os_closetypedfile(outfile)
                0347 FILE *outfile;
                0348 {
                0349     char buf[128];
                0350     
                0351     if (applefile_flag) {
                0352         rewind(outfile);
                0353         if (decode_applefile(outfile, &fspec) < 0) {
                0354             sprintf(buf, "Failed to decode file %s", output_fname);
                0355             if (didchat >= 0) warn(buf);
                0356             applefile_flag = 0;
                0357         }
                0358     }
                0359 
                0360     /* close file */
                0361     fclose(outfile);
                0362 }
                0363 
                0364 /*
                0365  * Warn user that the MD5 digest of the last file created by os_newtypedfile()
                0366  * did not match that supplied in the Content-MD5: header.
                0367  */
                0368 os_warnMD5mismatch()
                0369 {
                0370     char *warning;
                0371 
                0372     warning = xmalloc(strlen(output_fname) + 100);
                0373     sprintf(warning, "%s was corrupted in transit",
                0374         output_fname);
                0375     warn(warning);
                0376     free(warning);
                0377 }
                0378 
                0379 /* bring up an error dialog for a file error
                0380  */
                0381 void os_perror(char *str)
                0382 {
                0383     extern int errno;
                0384     char *err = strerror(errno), *scan;
                0385     char msg[256];
                0386     short maxflen;
                0387     
                0388     maxflen = 255 - (strlen(err) + 2);
                0389     if (strlen(str) > maxflen) {
                0390         str += strlen(str) - maxflen;
                0391         for (scan = str; *scan && *scan++ != ':';);
                0392         if (*scan) str = scan;
                0393     }
                0394     sprintf(msg, "%s: %s", str, err);
                0395     yell(msg);
                0396 }