Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!tut.cis.ohio-state.edu!ucbvax!pasteur!cory.Berkeley.EDU!fadden From: fadden@cory.Berkeley.EDU (Andy McFadden) Newsgroups: comp.binaries.apple2 Subject: NuLib v2.1.1 NuFX archiver (UNIX/APW) shar format 2/5 Message-ID: <19356@pasteur.Berkeley.EDU> Date: 9 Nov 89 09:17:33 GMT Sender: news@pasteur.Berkeley.EDU Reply-To: fadden@cory.Berkeley.EDU (Andy McFadden) Organization: University of California, Berkeley Lines: 1745 NuLib part 2/5 ----- #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create: # nuadd.c # nublu.c # nuetc.c # This archive created: Thu Nov 9 01:07:18 1989 # By: Andy McFadden () export PATH; PATH=/bin:/usr/bin:$PATH echo shar: "extracting 'nuadd.c'" '(19636 characters)' if test -f 'nuadd.c' then echo shar: "will not over-write existing file 'nuadd.c'" else cat << \!Funky!Stuff! > 'nuadd.c' /* * nuadd.c - operations which add to a NuFX archive (add) * * By Andy McFadden (fadden@cory.berkeley.edu) * NuLib v2.1 November 1989 Freeware (distribute, don't sell) */ #include "nudefs.h" #include #include #include #include #ifdef BSD43 # include #else # include #endif #ifdef UNIX # include # include # include #endif #ifdef APW # include # include # include # include #endif #ifdef MSDOS # include # include # include # include # include # include #endif #include "nuread.h" #include "nuadd.h" #include "nupak.h" #include "nuetc.h" #define MAXGSPREFIX 64 static BOOLEAN domove; /* are we M)oving the files in? */ static BOOLEAN docreate; /* using the 'C' option? */ /* * Expand command args into filenames * Stuff number of names into int; build File Information Array. * (this routine is heavily implementation-specific, since no two systems * expand wildcards or deal with subdirectories in the same way). * * Recursively expands subdirectories, unless doSubdir is FALSE. */ int EvalArgs(count, names, FIArray, first) int count; /* #of filenames */ char **names; /* array of file names */ file_info *FIArray[]; /* array to fill with file info */ BOOLEAN first; /* first time through? */ { static char *procName = "EvalArgs"; #ifdef UNIX /* UNIX shells (sh, csh) won't expand subdirectories, but they do * expand wildcards in arguments before we get them */ static int idx; struct stat st; char *cp; /* temp char pointer */ /* dir stuff */ int newcount; char **newnames; DIR *dirp; struct direct *dp; int nmlen; if (first) idx = 0; while (count--) { FIArray[idx] = (file_info *) Malloc(sizeof(file_info)); if (stat(*names, &st) < 0) { /* get file info */ if (errno == ENOENT) { fprintf(stderr, "%s: '%s' not found\n", prgName, *names); names++; continue; /* with while */ } Fatal("Bad stat()", procName); } if ((st.st_mode & S_IFDIR) && doSubdir) { /* is it a directory? */ newnames = (char **) Malloc(MAXARGS * sizeof(char *)); strcpy(tmpNameBuf, *names); /* earlier dir stuff */ strcat(tmpNameBuf, "/"); nmlen = strlen(tmpNameBuf); if ((dirp = opendir(*names)) == NULL) Fatal("Unable to open subdirectory", procName); for (newcount=0, dp=readdir(dirp); dp != NULL; dp=readdir(dirp)) { if ((!strcmp(dp->d_name, ".")) || (!strcmp(dp->d_name, ".."))) continue; /* with for */ newnames[newcount] = (char *) Malloc(nmlen + dp->d_namlen +1); strcpy(newnames[newcount], tmpNameBuf); strcat(newnames[newcount], dp->d_name); /* append the name */ newcount++; } closedir(dirp); EvalArgs(newcount, newnames, FIArray, FALSE); /* do subdir */ while (newcount-- > 0) /* free up the space we allocated */ free(newnames[newcount]); free(newnames); names++; } else if ((st.st_mode & S_IFDIR) && !doSubdir) { /* maybe print message? */ names++; continue; /* with while */ } else if (st.st_mode & S_IFREG) { FIArray[idx]->eof = (long) st.st_size; if (st.st_mode & S_IWRITE) /* write permission enabled? */ FIArray[idx]->fAccess = (fourbyt) 0x00e3; /* locked */ else FIArray[idx]->fAccess = (fourbyt) 0x0021; /* unlocked */ FIArray[idx]->fileType = defFileType; FIArray[idx]->auxType = defAuxType; FIArray[idx]->fileSysID = 0x0001; /* ProDOS */ FIArray[idx]->fileSysInfo = 0x002f; /* not sparse; '/' */ ExpandTime(&st.st_mtime, &FIArray[idx]->create_dt); /*use mod.. */ ExpandTime(&st.st_mtime, &FIArray[idx]->mod_dt); /*time for both */ FIArray[idx]->marked = FALSE; FIArray[idx]->pathname = (char *) Malloc(strlen(*names)+1); strcpy(FIArray[idx]->pathname, *names); FIArray[idx]->store_name = (char *) Malloc(strlen(*names)+1); cp = *names; while (*cp == '/') cp++; /* advance past leading '/' */ strcpy(FIArray[idx]->store_name, cp); /* can't otherwise fix */ names++; idx++; } else { printf("Unknown storage type for '%s'\n", *names); names++; continue; /* with while */ } } return (idx); #else /* UNIX */ # ifdef APW static int idx; /* will eventually hold the total #of filenames */ char *nextname = (char *) Malloc(MAXFILENAME); /* for subdir expand */ char prefix[MAXGSPREFIX+1]; /* Max ProDOS prefix size; now 64 */ char *fnptr; FileRec finfo_p; PrefixRec prefix_p; OpenRec open_p; EOFRec eof_p; if (first) idx = 0; prefix_p.prefixNum = 0; /* current dir */ prefix_p.prefix = prefix; /* prefix buffer */ GET_PREFIX( &prefix_p ); ToolErrChk(); p2cstr(prefix); while (count) { strcpy(tmpNameBuf, *names); c2pstr(tmpNameBuf); INIT_WILDCARD(tmpNameBuf, 0); ToolErrChk(); while (*NEXT_WILDCARD(tmpNameBuf)) { if (idx >= MAXARGS) { fprintf(stderr, "Too many files (%d, %d max)\n", idx, MAXARGS); Quit (-1); } finfo_p.pathname = tmpNameBuf; GET_FILE_INFO( &finfo_p ); ToolErrChk(); open_p.openPathname = tmpNameBuf; OPEN( &open_p ); ToolErrChk(); eof_p.eofRefNum = open_p.openRefNum; GET_EOF( &eof_p ); ToolErrChk(); CLOSE( &open_p ); ToolErrChk(); p2cstr(tmpNameBuf); /* also does p2cstr(finfo_p.pathname) */ switch (finfo_p.storageType) { case 0x00: /* standard ProDOS storage types */ case 0x01: case 0x02: case 0x03: FIArray[idx] = (file_info *) Malloc(sizeof(file_info)); FIArray[idx]->eof = eof_p.eofPosition; FIArray[idx]->fAccess = finfo_p.fAccess; FIArray[idx]->fileType = (fourbyt) finfo_p.fileType; FIArray[idx]->auxType = (fourbyt) finfo_p.auxType; FIArray[idx]->storageType = finfo_p.storageType; FIArray[idx]->fileSysID = 0x0001; /* ProDOS */ FIArray[idx]->fileSysInfo = 0x002f; /* not sparse, '/' */ ExpandTime(&finfo_p.createDate, &FIArray[idx]->create_dt); ExpandTime(&finfo_p.modDate, &FIArray[idx]->mod_dt); FIArray[idx]->marked = FALSE; FIArray[idx]->pathname = (char *) Malloc(strlen(tmpNameBuf)+1); strcpy(FIArray[idx]->pathname, tmpNameBuf); /* are we adding from current directory? */ if (!strncmp(tmpNameBuf, prefix, strlen(prefix))) { FIArray[idx]->store_name = /* yes */ (char *) Malloc(strlen(tmpNameBuf) - strlen(prefix) +1); strcpy(FIArray[idx]->store_name, tmpNameBuf+ strlen(prefix)); } else { fnptr = RINDEX(tmpNameBuf, '/') + 1; /* no */ FIArray[idx]->store_name = (char *)Malloc(strlen(fnptr)+1); strcpy(FIArray[idx]->store_name, fnptr); } idx++; break; case 0x05: printf("Can't handle Extended file '%s'\n", tmpNameBuf); break; case 0x0d: if (doSubdir) { strcpy(nextname, tmpNameBuf); /* make new copy */ strcat(nextname, "/="); /* APW-only wildcard */ EvalArgs(1, &nextname, FIArray, FALSE); /* read subdir */ } break; default: printf("Unknown storage type for '%s'\n", tmpNameBuf); break; } } /* inner while */ names++, count--; } /* outer while */ free (nextname); return (idx); # endif /* APW */ # ifdef MSDOS /* MS-DOS or other shell wildcard expansion here */ int idx, error; struct stat fStat; idx = 0; while (count--) { error = stat (*names, &fStat); /* If the filename is a directory, we need to expand that too! */ if (!error) { FIArray[idx] = (file_info *) Malloc(sizeof(file_info)); FIArray[idx]->pathname = (char *) Malloc(strlen(*names)+1); strcpy(FIArray[idx]->pathname, *names); FIArray[idx]->store_name = (char *) Malloc(strlen(*names)+1); strcpy(FIArray[idx]->store_name, *names); FIArray[idx]->fAccess = 0x00e3L; /* unlocked */ FIArray[idx]->fileType = defFileType; FIArray[idx]->auxType = defAuxType; FIArray[idx]->storageType = 0x0000; FIArray[idx]->fileSysID = 0x0001; /* ProDOS */ FIArray[idx]->fileSysInfo = 0x001c; /* not sparse, '\' */ ExpandTime(&fStat.st_ctime, &FIArray[idx]->create_dt); ExpandTime(&fStat.st_mtime, &FIArray[idx]->mod_dt); FIArray[idx]->eof = fStat.st_size; FIArray[idx]->marked = FALSE; idx++; } names++; } return (idx); # endif /* MDOS */ # ifndef APW # ifndef MSDOS /* nothing else defined */ /* +PORT+ */ printf("\n[other] wildcard expansion/file info needs work\n"); while (count--) { FIArray[count] = (file_info *) Malloc(sizeof(file_info)); FIArray[count]->pathname = (char *) Malloc(strlen(*names)+1); strcpy(FIArray[count]->pathname, *names); FIArray[count]->store_name = (char *) Malloc(strlen(*names)+1); strcpy(FIArray[count]->store_name, *names); FIArray[count]->fAccess = 0x00e3L; /* unlocked */ FIArray[count]->fileType = 0x0006L; /* BIN */ FIArray[count]->auxType = 0L; FIArray[count]->storageType = 0x0000; FIArray[count]->fileSysID = 0x0001; /* ProDOS */ FIArray[count]->fileSysInfo = 0x001c; /* not sparse, '\' */ ExpandTime((char *) NULL, &FIArray[count]->create_dt); ExpandTime((char *) NULL, &FIArray[count]->mod_dt); FIArray[count]->marked = FALSE; names++; } return (count); # endif /* none2 */ # endif /* none1 */ #endif /* UNIX */ } /* * Add a file onto the end of an archive; does not check to see if an entry * already exists. * * This creates the record entry, and calls subroutines to add the various * threads. The archive fd should be open, the file fd should not. */ void AddFile(arcfd, infoptr) int arcfd; file_info *infoptr; { int srcfd; /* file to add */ onebyt *recBuf; /* record header block */ twobyt *twoptr; THblock thread[1]; /* thread block */ twobyt CRC; int idx; fourbyt total_threads; long recposn; /* file posn for record entry */ long thposn; /* file posn for last thread */ long tmpposn; /* temporary file posn */ static char *procName = "AddFile"; if (verbose) { printf("Adding '%s' (data)...", infoptr->store_name, infoptr->eof); fflush(stdout); } recBuf = (onebyt *) Malloc(ATTSIZE); for (idx = 0; idx < ATTSIZE; idx++) /* zero the buffer */ *(recBuf+idx) = 0; total_threads = 0; strncpy((char *) recBuf+0, (char *) RecordID, 4); twoptr = (twobyt *) (recBuf+6); *twoptr = ATTSIZE; /* don't use older attrib_count... */ HiSwap(recBuf, 6, 7); twoptr = (twobyt *) (recBuf+8); *twoptr = OURVERS; /* store new record with our rec vers */ HiSwap(recBuf, 8, 9); /* BCopy(&total_threads, recBuf+10, 4, TRUE); */ BCopy(&infoptr->fileSysID, recBuf+14, 2, TRUE); BCopy(&infoptr->fileSysInfo, recBuf+16, 2, TRUE); BCopy(&infoptr->fAccess, recBuf+18, 4, TRUE); BCopy(&infoptr->fileType, recBuf+22, 4, TRUE); BCopy(&infoptr->auxType, recBuf+26, 4, TRUE); BCopy(&infoptr->create_dt, recBuf+32, sizeof(Time), FALSE); BCopy(&infoptr->mod_dt, recBuf+40, sizeof(Time), FALSE); BCopy(GetTime(), recBuf+48, sizeof(Time), FALSE); twoptr = (twobyt *) (recBuf + (ATTSIZE - 2)); *twoptr = strlen(infoptr->store_name); HiSwap(recBuf, ATTSIZE-2, ATTSIZE-1); /* correct strlen ordering */ thread[0].thread_class = 0x0002; /* data */ HiSwap(&thread[0].thread_class, 0, 1); thread[0].thread_kind = 0x0000; /* data fork */ HiSwap(&thread[0].thread_kind, 0, 1); thread[0].thread_format = 0x0000; /* filled in later */ thread[0].reserved = 0x0000; HiSwap(&thread[0].reserved, 0, 1); /* so I don't forget later on... */ thread[0].thread_eof = infoptr->eof; HiSwap(&thread[0].thread_eof, 0, 3); HiSwap(&thread[0].thread_eof, 1, 2); thread[0].comp_thread_eof = -1L; /* filled in later */ total_threads++; BCopy(&total_threads, recBuf+10, 4, TRUE); /* * Because we don't know CRCs or compressed size yet, we must: * skip record entry and filename. * for each thread: * skip thread entry, write data, move back, write thread entry. * move back, write record entry and filename. * move forward to next position. */ if ((srcfd = open(infoptr->pathname, O_RDONLY | O_BINARY)) < 0) Fatal("Unable to open file", procName); recposn = lseek(arcfd, 0L, S_REL); /* save record posn */ if (lseek(arcfd, (long) (ATTSIZE + strlen(infoptr->store_name)), S_REL)<0) Fatal("Bad seek (R.rel)", procName); /* loop... */ thposn = lseek(arcfd, 0L, S_REL); /* save thread posn */ if (lseek(arcfd, (long) THsize, S_REL) < 0) Fatal("Bad seek (Th)", procName); /* since we can store files as being packed without actually packing them, * we need to check "dopack" to see if we want packMethod or zero. Note * that packing can fail for various reasons; the value returned by * PackFile() is the actual algorithm used to pack the file. */ thread[0].thread_format = PackFile(srcfd,arcfd, infoptr->eof, dopack ? packMethod:0, pakbuf); if (!dopack) thread[0].thread_format = packMethod; /* for S subopt */ HiSwap(&thread[0].thread_format, 0, 1); thread[0].comp_thread_eof = (fourbyt) packedSize; HiSwap(&thread[0].comp_thread_eof, 0, 3); /* correct ordering */ HiSwap(&thread[0].comp_thread_eof, 1, 2); tmpposn = lseek(arcfd, 0L, S_REL); if (lseek(arcfd, thposn, S_ABS) < 0) /* seek back to thread posn */ Fatal("Bad seek (Th2)", procName); if (write(arcfd, &thread[0], THsize) < THsize) /* write updated thread */ Fatal("Unable to write thread", procName); if (lseek(arcfd, tmpposn, S_ABS) < 0) /* seek back to where we were */ Fatal("Bad seek (TmpA)", procName); /* ...loop end */ if (close(srcfd) < 0) Fatal("Unable to close file", procName); CRC = CalcCRC(0, recBuf+6, ATTSIZE-6); CRC = CalcCRC(CRC, infoptr->store_name, strlen(infoptr->store_name)); CRC = CalcCRC(CRC, &thread[0], THsize); twoptr = (twobyt *) (recBuf+4); *twoptr = CRC; HiSwap(recBuf, 4, 5); tmpposn = lseek(arcfd, 0L, S_REL); /* record posn (next posn) */ if (lseek(arcfd, recposn, S_ABS) < 0) /* seek back to record entry */ Fatal("Bad seek (R.abs)", procName); if (write(arcfd, recBuf, ATTSIZE) < ATTSIZE) Fatal("Unable to write record", procName); if (write(arcfd, infoptr->store_name, strlen(infoptr->store_name)) < strlen(infoptr->store_name)) Fatal("Unable to store filename", procName); if (lseek(arcfd, tmpposn, S_ABS) < 0) /* seek back to where we were */ Fatal("Bad seek (TmpB)", procName); if (verbose) printf("done.\n"); free(recBuf); /* return ( (long) (THsize * total_threads) + (long) (ATTSIZE) + */ /* (long) strlen(infoptr->store_name) + thread[0].comp_thread_eof ); */ return; } /* * Certain options can cause an archive to be created (add, create, move). * If the archive does not already exist, then an empty file is created (of * type $e0/8002 under ProDOS) and an empty archive struct is built. * * Note that this requires certain options to deal with archive structures that * do not have any records, and archive files that are empty. * * If the file exists, this will call NuRead() to read it; otherwise, it will * create it. */ static ListHdr *CreateMaybe(filename) char *filename; { ListHdr *archive; onebyt *bufPtr; twobyt *twoptr; int idx; #ifdef APW FileRec create_p; #endif static char *procName = "CreateMaybe"; if (Exists(filename)) { archive = NuRead(filename); return (archive); } if (!docreate) printf("Archive does not exist; creating archive file...\n"); archive = (ListHdr *) Malloc(sizeof(ListHdr)); archive->arc_name = (char *) Malloc(strlen(filename)+1); strcpy(archive->arc_name, filename); archive->MHptr = (MHblock *) Malloc(sizeof(MHblock)); archive->RNodePtr = (RNode *) NULL; archive->nextposn = (long) MHsize; bufPtr = (onebyt *) archive->MHptr; for (idx = 0; idx < MHsize; idx++) *(bufPtr+idx) = '\0'; /* total_records -> zero */ strncpy((char *) bufPtr+0, (char *) MasterID, 6); BCopy(GetTime(), bufPtr+12, 8, FALSE); BCopy(bufPtr+12, bufPtr+20, 8, FALSE); twoptr = (twobyt *) (bufPtr+6); *twoptr = CalcCRC(0, bufPtr+8, MHsize-8); ArcfiCreate(filename); /* create SHK file */ return (archive); } /* * Return a pointer to a valid Master Header block * Anything that isn't set to a default value needs to be passed as a * parameter. */ onebyt *MakeMHblock(archive, total_records) ListHdr *archive; fourbyt total_records; { static onebyt buf[MHsize]; /* must be static */ twobyt *twoptr; int idx; static char *procName = "MakeMHblock"; for (idx = 0; idx < MHsize ; idx++) buf[idx] = '\0'; strncpy((char *) buf, (char *) MasterID, 6); BCopy(&total_records, &buf[8], 4, TRUE); BCopy(&archive->MHptr->arc_create_when, &buf[12], sizeof(Time), FALSE); BCopy(GetTime(), &buf[20], sizeof(Time), FALSE); twoptr = (twobyt *) &buf[6]; *twoptr = CalcCRC(0, &buf[8], MHsize-8); HiSwap(buf, 6, 7); /* correct byte ordering */ return (buf); } /* * Add files to archive * * Read files from disk, adding them to the end of the archive as we go. * Update the master header block after all files have been added. */ static void Add(filename, namecount, names) char *filename; int namecount; char **names; { ListHdr *archive; int arcfd; file_info *FIArray[MAXARGS]; /* entries malloc()ed by EvalArgs */ int idx; onebyt *mptr; /* points to a MHblock suitable for writing */ static char *procName = "Add"; /* expand wildcards/subdirectories, and get file info */ namecount = EvalArgs(namecount, names, FIArray, TRUE); if (!namecount) { if (verbose) printf("No files selected.\n"); Quit (0); } archive = CreateMaybe(filename); if ((arcfd = open(archive->arc_name, O_RDWR | O_BINARY)) < 0) Fatal("Unable to open archive", procName); if (lseek(arcfd, archive->nextposn, S_ABS) < 0) /* seek to end */ Fatal("Unable to seek in archive", procName); for (idx = 0 ; idx < namecount; idx++) { #ifdef APW if (STOP()) Quit(1); /* check for OA-. */ #endif AddFile(arcfd, FIArray[idx]); archive->MHptr->total_records++; } mptr = MakeMHblock(archive, archive->MHptr->total_records); if (lseek(arcfd, 0L, S_ABS) < 0) Fatal("Unable to rewind archive for master header", procName); if (write(arcfd, mptr, MHsize) < MHsize) Fatal("Unable to update master header", procName); if (close(arcfd) < 0) Fatal("Unable to close archive", procName); if (domove) { if (verbose) printf("Deleteing files...\n"); for (idx = 0; idx < namecount; idx++) { if (verbose) { printf("%s...", FIArray[idx]->pathname); fflush(stdout); } if (unlink(FIArray[idx]->pathname) < 0) { if (verbose) printf("failed.\n"); } else { if (verbose) printf("done.\n"); } } } } /* * Main entry point for adding files. */ void NuAdd(filename, namecount, names, options) char *filename; int namecount; char **names; char *options; { char *optr; int idx; char type[5]; static char *procName = "NuAdd"; if (*options == 'm') domove = TRUE; if (*options == 'c') docreate = TRUE; /* change T subopt to convert FROM current system TO */ if (transfrom >= 0) { transto = transfrom; transfrom = -1; } Add(filename, namecount, names); /* do main processing */ } !Funky!Stuff! fi # end of overwriting check echo shar: "extracting 'nublu.c'" '(11007 characters)' if test -f 'nublu.c' then echo shar: "will not over-write existing file 'nublu.c'" else cat << \!Funky!Stuff! > 'nublu.c' /* * nublu.c - operations on Binary II archives * * By Andy McFadden (fadden@cory.berkeley.edu) * NuLib v2.1 November 1989 Freeware (distribute, don't sell) */ #ifndef NO_BLU /***********************************/ #include "nudefs.h" #include #include #ifdef UNIX # include # include # include #endif #ifdef APW # include #endif #ifdef MSDOS # include # include # include # include # include #endif #include "nuview.h" /* file types for BLU */ #include "nuadd.h" /* need OptNum() */ #include "nupak.h" /* need unpak_SQU */ #include "nuetc.h" /* Binary II extraction routines are adapted from: */ /************************************************************************* ** ** ** Name : unblu ** ** Author : Marcel J.E. Mol ** ** Date : 10/05/88 (first release) ** ** Version : 2.20 ** ** Files : unblu.c Main source file ** ** ** ** ------------------------- Revision List ------------------------- ** ** Ver Date Name Remarks ** ** 1.00 10/05/88 Marcel Mol Raw copy of a basic program** ** 2.00 03/06/88 Marcel Mol Rewrite after blu info ** ** was send to the net ** ** 2.10 18/06/88 Marcel Mol Added filetype texts ** ** 2.20 23/09/88 Marcel Mol Show mod and creation time ** ** ** ************************************************************************/ /*char * copyright = "@(#) unblu.c 2.1 18/06/88 (c) M.J.E. Mol";*/ #define BUFSIZE 128 /* Blu block length */ /* global variables */ static char *progname; static char *blufile; static BOOLEAN extract = FALSE; /* extract (as opposed to just listing) */ /* * extract_file -- extract file fname from the archive fd. Fname * contains filelen bytes. * * If the first block has the .QQ magic numbers, go ahead and try to * unsqueeze it. Not the best way to go about it, but it works. */ static void extract_file(fd, fname, filelen) int fd; char *fname; /* 64 bytes */ long filelen; { int ofd; int n, i; onebyt buf[BUFSIZE]; long full_len; int offset; static char *procName = "extract_file"; /*n = */ read(fd, buf, 70); /* read first few bytes */ lseek(fd, -70L, S_REL); /* back up */ if ((buf[0] == 0x76) && (buf[1] == 0xff)) { /* is it squeezed? */ i = 0; /* get the original file name */ while ((fname[i] = buf[4+i]) != '\0') i++; offset = 5+i; /* how far into file is end of filename? */ if (verbose) { printf("(as %s)...", fname); fflush(stdout); } } if (Exists(fname)) { if (interact) { if (verbose) printf("file exists, overwite"); else printf("%s exists, overwite", fname); if (!AskYesNo()) { /* return w/o overwriting */ full_len = ( (filelen / 128L) +1 ) * 128L; lseek(fd, full_len, S_REL); return; } } if (verbose) { printf("overwriting..."); fflush(stdout); } if (unlink(fname) < 0) Fatal("Unable to remove existing file", procName); } if ((ofd = open(fname, O_BINARY|O_CREAT|O_WRONLY|O_TRUNC, 0644)) < 0) { Fatal("Can't open destination file", "extract_file"); } if ((buf[0] == 0x76) && (buf[1] == 0xff)) { /* is it squeezed? */ if (verbose) { printf("unsqueezing..."); fflush(stdout); } full_len = ( (filelen / 128L) +1 ) * 128L; lseek(fd, (long) offset, S_REL); full_len -= offset; /* send unpak_SQU everything past fname */ unpak_SQU(fd, ofd, full_len); /* unsqueeze it */ } else { /* extract uncompressed */ lastseen = '\0'; /* used by crlf() translator */ while (filelen > 0L) { n = read(fd, buf, BUFSIZE); /* Read 128 bytes */ if (n != BUFSIZE) { fprintf(stderr, "Extract_BNY: %s file size broken\n", blufile); Quit(-1); } if (crlf(ofd, buf, (filelen >= BUFSIZE ? BUFSIZE : filelen)) != (filelen >= BUFSIZE ? BUFSIZE : filelen)) Fatal("Bad write", procName); filelen -= (long) BUFSIZE; } } close(ofd); /* Close destination file */ } /* * print_header -- print global information of the binary II file */ static void print_header(buf) onebyt *buf; { long disk_blocks; disk_blocks = buf[117] + (buf[118]<<8) + (buf[119]<<16) + (buf[120]<<24); printf("Listing %-40.40s ", blufile); printf("Blocks used: %-5ld", disk_blocks); printf("Files: %d\n", buf[127]+1); printf("\nFilename Type Blocks Modified "); printf("Created Length Subtype\n\n"); } /* * want -- return TRUE if name exists in array wantlist, * else return FALSE */ static BOOLEAN want(name, wantlist) char *name; char **wantlist; { while (*wantlist != NULL) { if (strcasecmp(name, *wantlist++) == NULL) return (TRUE); } return (FALSE); } /* * process_file -- retrieve or print file information of file given * in buf */ static void process_file(fd, buf, count, wanted) int fd; onebyt *buf; int count; char **wanted; { int ftype, auxtype; int fnamelen; long filelen; char fname[64]; char outbuf[16]; /* temp for sprintf */ int nblocks, problocks; Time create_dt; Time mod_dt; #ifdef APW FileRec frec; #endif #ifdef UNIX struct stat st; #endif #ifdef MSDOS struct stat st; #endif /* +PORT+ */ /* int tf; * int dflags; */ static char *procName = "process_file"; /* Get file info */ ftype = buf[4]; /* File type */ auxtype = (int) buf[5] + ((int)buf[6] << 8); fnamelen = buf[23]; /* filename */ strncpy(fname, &buf[24], fnamelen); fname[fnamelen] = '\0'; /* dflags = buf[125]; /* Data flags */ /* tf = buf[127]; /* Number of files to follow */ filelen = (long) buf[20] + ((long) buf[21] << 8) + ((long) buf[22] << 16); /* calculate file len */ nblocks = (filelen + BUFSIZE-1) / BUFSIZE; /* #of BNY blocks */ problocks = buf[8] + ((int) buf[9] << 8); mod_dt.second = 0; mod_dt.minute = buf[12] & 0x3f; mod_dt.hour = buf[13] & 0x1f; mod_dt.day = (buf[10] & 0x1f) -1; mod_dt.month = (((buf[11] & 0x01) << 3) + (buf[10] >> 5)) -1; mod_dt.year = buf[11] >> 1; mod_dt.weekDay= 0; create_dt.second = 0; create_dt.minute = buf[16] & 0x3f; create_dt.hour = buf[17] & 0x1f; create_dt.day = (buf[14] & 0x1f) -1; create_dt.month = (((buf[15] & 0x01) << 3) + (buf[14] >> 5)) -1; create_dt.year = buf[15] >> 1; create_dt.weekDay= 0; if (!count || want(fname, wanted)) { if (!extract) { /* print file information ONLY */ printf("%-15.15s %-3.3s ", fname, FT[ftype]); printf("%6d ", problocks); printf("%-16.16s ", PrintDate(&mod_dt, TRUE)); printf("%-16.16s ", PrintDate(&create_dt, TRUE)); if (filelen < 0x100L) sprintf(outbuf, "$%.2lx", filelen); else if (filelen < 0x10000L) sprintf(outbuf, "$%.4lx", filelen); else sprintf(outbuf, "$%.6lx", filelen); printf("%7s ", outbuf); printf("$%.4x\n", auxtype); /* if (dflags == 0) * printf("stored"); * else { * if (dflags & 128) { * printf("squeezed"); * } * if (dflags & 64) { * printf("encrypted"); * } * if (dflags & 1) * printf("packed"); * } * putchar('\n'); */ if (ftype != 15) { /* If not a directory */ lseek(fd, (long) BUFSIZE*nblocks, S_REL); /*Seek to next file*/ } } else { /* extract is TRUE */ if (verbose) { printf("Extracting %s...", fname); fflush(stdout); } #ifdef UNIX if (ftype != 15) extract_file(fd, fname, filelen); /* note dates etc not set */ else { /* if no directory exists, then make one */ if (stat(fname, &st) < 0) if (errno == ENOENT) { sprintf(tmpNameBuf, "mkdir %s", fname); if (system(tmpNameBuf) != 0) /* call UNIX mkdir */ Fatal("Unable to create subdir", procName); } else { Fatal("Unable to create dir", procName); } } #else # ifdef APW /* create file/directory , with appropriate type/auxtype stuff */ c2pstr(fname); frec.pathname = fname; frec.fAccess = 0x00e3; /* unlocked */ frec.fileType = ftype; frec.auxType = (unsigned long) auxtype; frec.storageType = (int) buf[7]; frec.createDate = 0x0000; /* set later */ frec.createTime = 0x0000; CREATE( &frec ); ToolErrChk(); p2cstr(fname); extract_file(fd, fname, filelen); /* set file attributes */ c2pstr(fname); frec.fAccess = (word) buf[3]; frec.modDate = (word) buf[10] + ((word)buf[11] << 8); frec.modTime = (word) buf[12] + ((word)buf[13] << 8); frec.createDate = (word) buf[14] + ((word)buf[15] << 8); frec.createTime = (word) buf[16] + ((word)buf[17] << 8); SET_FILE_INFO( &frec ); ToolErrChk(); p2cstr(fname); # else if (ftype != 15) extract_file(fd, fname, filelen); else /* +PORT+ */ printf("[ need [other] subdir create for UnBNY ]\n"); # endif /* APW */ #endif /* UNIX */ if (verbose) printf("done.\n"); } } else if (ftype != 15) { /* This file not wanted; if not a directory */ lseek(fd, (long) BUFSIZE*nblocks, S_REL); /* Seek to next file */ } } /* * unblu -- process a binary II file fd, and process the filenames * listed in wanted. If wanted is \0, all files are processed. */ static void unblu(fd, count, wanted) int fd; int count; char **wanted; { onebyt buf[BUFSIZE]; int firstblock = 1; /* First block needs special processing */ int tofollow = 1; /* Files to follow in the archive */ int n; while (tofollow && ((n = read(fd, buf, BUFSIZE)) > 0)) { /* If there is a header block */ if (n != BUFSIZE) { fprintf(stderr, "UnBNY: %s file size is broken\n", blufile); Quit(-1); } if ((buf[0] != 10) || (buf[1] != 71) || (buf[2] != 76) || (buf[18] != 2)) { fprintf(stderr, "UnBNY: %s not a Binary II file or bad record\n", blufile); Quit(-1); } tofollow = buf[127]; /* How many files to follow */ if (firstblock && !extract) { print_header(buf); } firstblock = 0; process_file(fd, buf, count, wanted); /* process the file for it */ } if (firstblock && (n < 0)) /* length < 128 */ fprintf(stderr, "UnBNY: Not a Binary II file"); } /* * Main entry point from CShrink */ void NuBNY(filename, argc, argv, options) char *filename; int argc; char **argv; char *options; { int bfd; /* File descriptor for blu file */ char *optr; /* process X subopt ourselves */ if (INDEX(options+1, 'x')) extract = TRUE; else extract = FALSE; blufile = filename; /* Make it global */ if ((bfd = open(filename, O_RDONLY | O_BINARY)) < 0) Fatal("Unable to open Binary II archive", "NuBNY"); unblu(bfd, argc, argv); /* Process wanted files */ close(bfd); Quit(0); } #endif /*NO_BLU*/ /***********************************/ !Funky!Stuff! fi # end of overwriting check echo shar: "extracting 'nuetc.c'" '(15995 characters)' if test -f 'nuetc.c' then echo shar: "will not over-write existing file 'nuetc.c'" else cat << \!Funky!Stuff! > 'nuetc.c' /* * nuetc.c - extra stuff; most is #ifdefed to death (mostly time routines * and file stuff that are highly system dependent) * * By Andy McFadden (fadden@cory.berkeley.edu) * NuLib v2.1 November 1989 Freeware (distribute, don't sell) */ #include "nudefs.h" #include #include #include /* errno declarations */ #include /* for tolower(), isupper() */ #ifdef UNIX # include /* need localtime() */ # include /* defn of time_t */ # include #endif #ifdef APW # include /* exit(), etc. */ # include /* has _toolErr in it */ # include # include "apwerr.h" /* APW/ProDOS error codes */ #endif #ifdef MSDOS # include # include # include # include # include # include #endif #include "nuetc.h" /* note "nuread.h" is not included... none of the routines here assume */ /* any knowledge of NuFX archives. */ #ifndef MSDOS extern char *malloc(); /* all systems ... except DOS : RBH */ #endif /* +PORT+ */ extern void free(); extern char *getenv(); #ifdef APW extern Time ReadTimeHex(); /* should be TimeRec, from misctool.h */ #endif /* This is a generally available TEMPORARY filename buffer */ char tmpNameBuf[MAXFILENAME]; /******************** general misc routines ********************/ /* * Fatal error handler */ void Fatal(deathstr, procName) char *deathstr, *procName; { fflush(stdout); fprintf(stderr, "\n%s: fatal error: %s\n--- ", prgName, deathstr); perror(procName); Quit (-1); } /* * Quit can be used to perform cleanup operations before exiting. */ void Quit(val) int val; { exit(val); } /* * Safe malloc()... checks return value */ char *Malloc(size) int size; { char *ptr = (char *) malloc(size); if (ptr != (char *) NULL) { return(ptr); } else { /* 8910.31 - RBH: report byte size that failed */ printf("Malloc: memory alloc error [%u : bytes]\n", size); #ifdef MSDOS printf("(Largest Available Block: %u)\n", _memmax()); #endif Quit (-1); } } /******************** UNIX compatibility routines ********************/ #ifdef UNIX /* * Convert expanded date to a number of seconds for UNIX systems. * * Remember that *atime follows the NuFX docs for time values, which * don't necessarily match those in UNIX manual pages. * Adapted from _Advanced UNIX Programming_ by Marc J. Rochkind. */ long timecvt(atime) Time *atime; { long tm; int days; BOOLEAN isleapyear; int tzone; char *getenv(), *tz; if ((tz = getenv("TZ")) == NULL) tzone = 8; /* pacific std time */ else tzone = atoi(&tz[3]); isleapyear = (atime->year != 0) && (atime->year%4 == 0); /* 2000 isn't */ if (atime->year < 70) atime->year += 100; /* years after 2000 */ days = (atime->year - 70) * 365L; days += ((atime->year - 69L) / 4); /* previous years' leap days */ switch (atime->month +1) { /* month is 0-11 */ case 12: days += 30; /* Nov */ case 11: days += 31; /* Oct */ case 10: days += 30; /* Sep */ case 9: days += 31; /* Aug */ case 8: days += 31; /* Jul */ case 7: days += 30; /* Jun */ case 6: days += 31; /* May */ case 5: days += 30; /* Apr */ case 4: days += 31; /* Mar */ case 3: days += (isleapyear ? 29 : 28); /* Feb */ case 2: days += 31; /* Jan */ case 1: break; default: printf("Invalid month\n"); return (0L); } if (atime->day > 31) { printf("Invalid day\n"); return (0L); } tm = (days + atime->day) * 24L * 60L * 60L; if (atime->hour > 23) { printf("Invalid hour\n"); return (0L); } atime->hour += tzone; /* correct for time zone */ tm += atime->hour * 60L * 60L; if (atime->minute > 59) { printf("Invalid minute\n"); return (0L); } tm += atime->minute * 60L; if (atime->second > 59) { printf("Invalid second\n"); return (0L); } tm += atime->second; if (localtime(&tm)->tm_isdst) /* was that day in dst? */ tm -= 60L * 60L; /* adjust for daylight savings */ return (tm); } #endif /* UNIX */ /******************** APW compatibility routines ********************/ #ifdef APW /* * Normally a C library function to print out a description of the most * recent system (non-toolbox, non-ProDOS) error. Exists under UNIX and * MS C 5.1, so I'm assuming it exists most everywhere else... */ void perror(errstr) char *errstr; { fflush(stdout); if ( (errno > 0) && (errno < sys_nerr) ) { /* known APW error? */ fprintf(stderr, "%s: %s\n", errstr, sys_errlist[errno]); } else { fprintf(stderr, "%s: ", errstr); fflush(stderr); ERROR( errno ); } Quit (-1); } /* Check for //gs toolbox errors; all are fatal */ void ToolErrChk() { if (_toolErr) { if (_toolErr < MPErr) { /* was a ProDOS error? */ fprintf(stderr, "Error: $%.2x %s\n", (char) _toolErr, ProDOSErr[_toolErr]); } else { fprintf(stderr, "Tool err: "); fflush(stderr); ERROR( _toolErr ); } Quit (-1); } } #endif /* APW */ /******************** miscellaneous string routines ********************/ /* * Compare strings, ignoring case (may be in standard C lib; stricmp()?) */ int strcasecmp(str1, str2) register char *str1, *str2; { register char one, two; register int val; for ( ; *str1 && *str2; str1++, str2++) { one = (isupper(*str1) ? tolower(*str1) : *str1); two = (isupper(*str2) ? tolower(*str2) : *str2); if (val = two - one) return (val); } if (!(*str1) && !(*str2)) /* both zero -> equivalent */ return (0); else { /* one is shorter; return result */ one = (isupper(*str1) ? tolower(*str1) : *str1); two = (isupper(*str2) ? tolower(*str2) : *str2); return (two - one); } } int strncasecmp(str1, str2, num) register char *str1, *str2; int num; { register int i; register char one, two; register int val; /* keep going 'til no more registers... */ for (i = 0; (i < num) && (*str1) && (*str2); i++, str1++, str2++) { one = (isupper(*str1) ? tolower(*str1) : *str1); two = (isupper(*str2) ? tolower(*str2) : *str2); if (val = two - one) return (val); } if (i == num) /* first num characters are equal, so return zero */ return (0); else { /* one ended early; return result */ one = (isupper(*str1) ? tolower(*str1) : *str1); two = (isupper(*str2) ? tolower(*str2) : *str2); return (two - one); } } /******************* file-related routines ********************/ /* * Do operating system-dependent CREATE stuff * * Creates a NuFX archive file, with type info where necessary. * Does not leave file open. */ void ArcfiCreate(filename) char *filename; { static char *procName = "ArcfiCreate"; #ifdef UNIX int fd; if ((fd = open(filename, O_CREAT|O_RDWR, WPERMS)) < 0) Fatal("Unable to create file", procName); close(fd); #else # ifdef APW FileRec create_p; c2pstr(filename); create_p.pathname = filename; create_p.fAccess = 0x00e3; create_p.fileType = 0x00e0; /* LBR */ create_p.auxType = 0x8002; /* SHK */ create_p.storageType = 0x0001; create_p.createDate = 0x0000; /* let ProDOS fill in the blanks */ create_p.createTime = 0x0000; CREATE( &create_p ); ToolErrChk(); p2cstr(filename); # endif /* APW */ # ifdef MSDOS int fd; if ((fd = open(filename, O_CREAT|O_RDWR, WPERMS)) < 0) Fatal("Unable to create file", procName); close(fd); # endif /* MSDOS */ # ifndef APW # ifndef MSDOS int fd; if ((fd = open(filename, O_CREAT|O_RDWR, WPERMS)) < 0) Fatal("Unable to create file", procName); close(fd); # endif /* none2 */ # endif /* none1 */ #endif /* UNIX */ } /* * Determine if a file already exists. */ BOOLEAN Exists(filename) char *filename; { static char *procName = "Exists"; #ifdef UNIX struct stat sm; if (stat(filename, &sm) < 0) { if (errno == ENOENT) /* if doesn't exist, then okay */ return (FALSE); else /* some other problem killed stat(), probably serious */ fprintf(stderr, "Unable to stat() '%s'\n", filename); Fatal("Bad stat()", procName); /*serious prob*/ } else /* successful call - file exists */ return (TRUE); #else # ifdef APW FileRec info_p; /* check if file exists, is dir */ int err; c2pstr(filename); info_p.pathname = filename; GET_FILE_INFO( &info_p ); err = _toolErr; p2cstr(filename); if (err == pathNotFound || err == fileNotFound) return (FALSE); else if (!err) return (TRUE); else { _toolErr = err; ToolErrChk(); return (TRUE); } # endif /* APW */ # ifdef MSDOS struct stat sm; if (stat(filename, &sm) < 0) { if (errno == ENOENT) /* if doesn't exist, then okay */ return (FALSE); else /* some other problem killed stat(), probably serious */ fprintf(stderr, "Unable to stat() '%s'\n", filename); Fatal("Bad stat()", procName); /*serious prob*/ } else /* successful call - file exists */ return (TRUE); # endif /* MSDOS */ # ifndef APW # ifndef MSDOS printf("Need [other] Exists()\n"); /* +PORT+ */ return (FALSE); # endif /* none2 */ # endif /* none1 */ #endif /* UNIX */ } /* * Generate a temporary file name (system dependent). * Assumes space is allocated for buffer. */ char *MakeTemp(buffer) char *buffer; { static char *procName = "MakeTemp"; #ifdef UNIX extern char *mktemp(); strcpy(buffer, "cshk.tmpXXXXXX"); return (mktemp(buffer)); #else # ifdef APW int idx = 0; do { sprintf(buffer, "cshk.tmp%d", idx++); } while (Exists(buffer)); return (buffer); # endif /* APW */ # ifdef MSDOS extern char *mktemp(); strcpy(buffer, "cshkXXXX.tmp"); return (mktemp(buffer)); # endif /* MSDOS */ # ifndef APW # ifndef MSDOS strcpy(buffer, "cshk.tmp"); /* +PORT+ */ return (buffer); # endif /* none2 */ # endif /* none1 */ #endif /* UNIX */ } /* * Rename a file. */ void Rename(fromname, toname) char *fromname, *toname; { static char *procName = "Rename"; #ifdef UNIX if (Exists(toname)) { fprintf(stderr, "\n%s: WARNING: Unable to rename '%s' as '%s'\n", prgName, fromname, toname); fflush(stderr); } else { if (rename(fromname, toname) < 0) { /* this should "never" fail */ fprintf(stderr, "\n%s: WARNING: Unable to rename '%s' as '%s'\n", prgName, fromname, toname); Fatal("Bad rename()", procName); /*serious prob*/ } } #else # ifdef APW PathNameRec cpath_p; if (Exists(toname)) { fprintf(stderr, "\n%s: WARNING: Unable to rename '%s' as '%s'\n", prgName, fromname, toname); fflush(stderr); return; } cpath_p.pathname = fromname; cpath_p.newPathname = toname; c2pstr(fromname); c2pstr(toname); CHANGE_PATH( &cpath_p ); ToolErrChk(); p2cstr(fromname); p2cstr(toname); # endif /* APW */ # ifdef MSDOS if (Exists(toname)) { fprintf(stderr, "\n%s: WARNING: Unable to rename '%s' as '%s'\n", prgName, fromname, toname); fflush(stderr); return; } printf("Work on MSDOS rename command\n"); # endif /* MSDOS */ # ifndef APW # ifndef MSDOS if (Exists(toname)) { fprintf(stderr, "\n%s: WARNING: Unable to rename '%s' as '%s'\n", prgName, fromname, toname); fflush(stderr); return; } printf("Need [other] rename command\n"); /* +PORT+ */ # endif /* none2 */ # endif /* none1 */ #endif /*UNIX*/ } /******************** date/time routines ********************/ /* * Expand date/time from file-sys dependent format to eight byte NuFX format. * tptr is filesys format, TimePtr is NuFX format */ void ExpandTime(tptr, TimePtr) /* (BSD) UNIX version */ onebyt *tptr; /* usually points to a time_t (long) */ Time *TimePtr; { #ifdef UNIX time_t *tp = (time_t *) tptr; struct tm *unixt; unixt = localtime(tp); /* expand time_t into components */ TimePtr->second = unixt->tm_sec; TimePtr->minute = unixt->tm_min; TimePtr->hour = unixt->tm_hour; TimePtr->year = unixt->tm_year; TimePtr->day = unixt->tm_mday -1; /* want 0-xx, not 1-xx */ TimePtr->month = unixt->tm_mon; TimePtr->extra = 0; TimePtr->weekDay = unixt->tm_wday +1; /* Sunday = 1, not 0 like UNIX */ #else # ifdef APW /* APW version */ twobyt date, time; date = (twobyt)tptr[0] + ((twobyt)tptr[1] << 8); time = (twobyt)tptr[2] + ((twobyt)tptr[3] << 8); TimePtr->second = 0; /* not stored in ProDOS file info */ TimePtr->minute = (char) time; /* truncated to char */ TimePtr->hour = time >> 8; TimePtr->year = date >> 9; TimePtr->day = (date & 0x1f) - 1; TimePtr->month = ((date & 0x01e0) >> 5) - 1; TimePtr->extra = 0; TimePtr->weekDay = 0; # endif /* APW */ # ifdef MSDOS struct tm *newtime; time_t *tp = (time_t *) tptr; newtime = localtime (tp); TimePtr->second = (onebyt)newtime->tm_sec; TimePtr->minute = (onebyt)newtime->tm_min; TimePtr->hour = (onebyt)newtime->tm_hour; TimePtr->year = (onebyt)newtime->tm_year; TimePtr->day = (onebyt)newtime->tm_mday - 1; TimePtr->month = (onebyt)newtime->tm_mon; TimePtr->extra = 0; TimePtr->weekDay= (onebyt)newtime->tm_wday + 1; # endif /* MSDOS */ # ifndef APW # ifndef MSDOS printf("Need [other] time-expander\n"); /* +PORT+ */ TimePtr->second = 0; TimePtr->minute = 0; TimePtr->hour = 0; TimePtr->year = 0; TimePtr->day = 0; TimePtr->month = 0; TimePtr->extra = 0; TimePtr->weekDay = 0; # endif /* none1 */ # endif /* none2 */ #endif /* UNIX */ } /* * Get current time, put in struct */ Time *GetTime() { static Time t; #ifdef UNIX struct tm *unixt; time_t now = time(NULL); unixt = localtime(&now); t.second = unixt->tm_sec; t.minute = unixt->tm_min; t.hour = unixt->tm_hour; t.year = unixt->tm_year; t.day = unixt->tm_mday -1; /* want 0-xx, not 1-xx */ t.month = unixt->tm_mon; t.extra = 0; t.weekDay = unixt->tm_wday +1; /* Sunday = 1, not 0 like UNIX */ /* return (&t) */ #else # ifdef APW t = ReadTimeHex(t); /* return (&t) */ # endif /* APW */ # ifdef MSDOS struct tm *pctime; time_t now = time(NULL); pctime = localtime(&now); t.second = (onebyt)pctime->tm_sec; t.minute = (onebyt)pctime->tm_min; t.hour = (onebyt)pctime->tm_hour; t.year = (onebyt)pctime->tm_year; t.day = (onebyt)pctime->tm_mday -1; /* want 0-xx, not 1-xx */ t.month = (onebyt)pctime->tm_mon; t.extra = 0; t.weekDay= (onebyt)pctime->tm_wday +1; /* Sunday = 1, not 0 */ /* return (&t) */ # endif /* MSDOS */ # ifndef APW # ifndef MSDOS printf("\nNeed [other] GetTime\n"); /* +PORT+ */ t->second = 0; t->minute = 0; t->hour = 0; t->year = 0; t->day = 0; t->month = 0; t->filler = 0; t->weekDay = 0; /* return (&t) */ # endif /* none1 */ # endif /* none2 */ #endif /* UNIX */ return (&t); } /* * Convert a NuFX Time struct to a compact system-dependent format * * This is used to set a file's date when extracting. Most systems don't * dedicate 8 bytes to storing the date; this reduces it to the format * used by a "set_file_date" command. */ long ReduceTime(tptr) Time *tptr; { #ifdef UNIX return (timecvt(tptr)); #else # ifdef APW twobyt date, time; long val; date = ((twobyt)tptr->year << 9) | ((((twobyt)tptr->month)+1) << 5) | (((twobyt)tptr->day)+1); time = ((twobyt)tptr->hour << 8) | ((twobyt)tptr->minute); val = (long) date + ((long) time << 16); return (val); # endif /* APW */ # ifdef MSDOS return (time(NULL)); /* not sure what to do, return current : RBH */ # endif /* MSDOS */ #ifndef APW #ifndef MSDOS printf("Need [other] ReduceTime\n"); /* +PORT+ */ # endif /* none2 */ # endif /* none1 */ #endif /* UNIX */ } !Funky!Stuff! fi # end of overwriting check exit 0 # End of shell archive