Received: by NDSUVM1 (Mailer R2.07) id 8927; Wed, 23 May 90 17:35:36 CDT Date: Wed, 23 May 90 17:47:32 EDT Reply-To: Apple II List Sender: Apple II List From: Grant Delaney Subject: NuLib v2.2 (C NuFX archiver) source (UNIX/IIgs/MS-DOS) [06/06] To: "Steven E. Nelson" ---- Cut Here and unpack ---- #!/bin/sh # This is part 06 of a multipart archive if touch 2>&1 | fgrep '[-amc]' > /dev/null then TOUCH=touch else TOUCH=true fi # ============= nuview.c ============== if test X"$1" != X"-c" -a -f 'nuview.c'; then echo "File already exists: skipping 'nuview.c'" else echo "x - extracting nuview.c (Text)" sed 's/^X//' << 'SHAR_EOF' > nuview.c && X/* X * nuview.c - prints the contents of a NuFX archive X * X * By Andy McFadden (fadden@cory.berkeley.edu) X * NuLib v2.2 April 1990 Freeware (distribute, don't sell) X */ X X#include "nudefs.h" X#include X#ifdef BSD43 X# include X#else /* SYSV, APW, MSC */ X# include X#endif X X#ifdef APW X# include X#endif X X#include "nuview.h" X#include "nuread.h" X#include "nuetc.h" X X X/* X * String definitions for NuView X */ X/* unknown value msg */ Xchar *unknownStr = "[ unknown ]"; X X/* weekDay values */ Xchar *WD[8] = { "[ null ]", "Sunday", "Monday", "Tuesday", "Wednesday", X "Thursday", "Friday", "Saturday" }; X X/* month values */ Xchar *MO[13] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", X "Aug", "Sep", "Oct", "Nov", "Dec" }; X X/* thread_class */ X/*#define TCn 4*/ Xchar *TC[TCn] = { "Message_thread", "Control_thread", "Data_thread", X "Filename_thread" }; X X/*#define TKn 3 /* max #of thread_kinds in a thread_class */ Xchar *TK[TCn][TKn] = { X { "ASCII text", "ASCII text (predef size)", "" }, X { "Create directory", "", "" }, X { "File data_fork", "Disk image", "File resource_fork" }, X { "Generic filename", "", "" } }; X X/* thread_format */ X/*#define TFn 6*/ Xchar *TF[TFn] = { "Uncompressed", "SQueezed (SQ/USQ)", X "Dynamic LZW Type I (ShrinkIt)", X "Dynamic LZW Type II (ShrinkIt)", "12-bit UNIX compress", X "16-bit UNIX compress" }; X X/* quick thread_format */ X/*#define QTFn 6*/ Xchar *QTF[QTFn] = { "unc", "squ", "shk", "sh2", "u12", "u16" }; X X/* file_sys_id */ X/*#define FIDn 14*/ Xchar *FID[FIDn] = { "Reserved/unknown ($00)", "ProDOS/SOS", "DOS 3.3", X "DOS 3.2", "Apple II Pascal", "Macintosh (MFS)", X "Macintosh (HFS)", "LISA file system", "Apple CP/M", X "Reserved ($09)", "MS-DOS", "High-Sierra", "ISO 9660", X "AppleShare" }; X X/* storage_type */ X/*#define STn 14*/ Xchar *ST[STn] = { "Standard file ($00)", "Standard file ($01)", X "Standard file ($02)", "Standard file ($03)", "??? ($04)", X "Extended file ($05)", "??? ($06)", "??? ($07)", "??? ($08)", X "??? ($09)", "??? ($0a)", "??? ($0b)", "??? ($0c)", X "Subdirectory ($0d)" }; X X/* file type names */ Xchar *FT[256] = { X "NON", "BAD", "PCD", "PTX", "TXT", "PDA", "BIN", "CHR", X "PIC", "BA3", "DA3", "WPD", "SOS", "$0D", "$0E", "DIR", X "RPD", "RPI", "$12", "OUT", "$14", "RPT", "$16", "$17", X "$18", "ADB", "AWP", "ASP", "$1C", "$1D", "$1E", "$1F", X "$20", "$21", "$22", "$23", "$24", "$25", "$26", "$27", X "$28", "$29", "$2A", "$2B", "$2C", "$2D", "$2E", "$2F", X "$30", "$31", "$32", "$33", "$34", "$35", "$36", "$37", X "$38", "$39", "$3A", "$3B", "$3C", "$3D", "$3E", "$3F", X "$40", "$41", "$42", "$43", "$44", "$45", "$46", "$47", X "$48", "$49", "$4A", "$4B", "$4C", "$4D", "$4E", "$4F", X "$50", "$51", "$52", "$53", "$54", "$55", "$56", "$57", X "$58", "$59", "$5A", "$5B", "$5C", "$5D", "$5E", "$5F", X "PRE", "$61", "$62", "$63", "$64", "$65", "$66", "$67", X "$68", "$69", "$6A", "NIO", "$6C", "DVR", "$6E", "HDV", X "$70", "$71", "$72", "$73", "$74", "$75", "$76", "$77", X "$78", "$79", "$7A", "$7B", "$7C", "$7D", "$7E", "$7F", X "$80", "$81", "$82", "$83", "$84", "$85", "$86", "$87", X "$88", "$89", "$8A", "$8B", "$8C", "$8D", "$8E", "$8F", X "$90", "$91", "$92", "$93", "$94", "$95", "$96", "$97", X "$98", "$99", "$9A", "$9B", "$9C", "$9D", "$9E", "$9F", X "WPF", "MAC", "HLP", "DAT", "$A4", "LEX", "$A6", "$A7", X "$A8", "$A9", "$AA", "GSB", "ARC", "$AD", "$AE", "$AF", X "SRC", "OBJ", "LIB", "S16", "RTL", "EXE", "STR", "TSF", X "NDA", "CDA", "TOL", "DRV", "$BC", "FST", "$BE", "DOC", X "PNT", "SCR", "ANI", "$C3", "$C4", "$C5", "$C6", "$C7", X "FON", "FND", "ICN", "$CB", "$CC", "$CD", "$CE", "$CF", X "$D0", "$D1", "$D2", "$D3", "$D4", "$D5", "$D6", "$D7", X "$D8", "$D9", "$DA", "$DB", "$DC", "DDD", "$DE", "$DF", X "LBR", "$E1", "ATI", "$E3", "$E4", "$E5", "$E6", "$E7", X "$E8", "$E9", "$EA", "$EB", "$EC", "$ED", "$EE", "PAS", X "CMD", "$F1", "$F2", "$F3", "$F4", "$F5", "$F6", "$F7", X "$F8", "IMG", "INT", "IVR", "BAS", "VAR", "REL", "SYS" }; X X X/* X * NuView program X */ X X/* print date from Time structure */ Xchar *PrintDate(tptr, brief) XTime *tptr; XBOOLEAN brief; X{ X static char buf[64]; /* holds final date string; must be static */ X char buf2[64]; /* space to hold string while building it */ X X /* check for validity */ X if ( (tptr->day > 30) || (tptr->month > 11) || (tptr->hour > 24) || X (tptr->minute > 59) ) { X strcpy(buf, " "); X return (buf); X } X X if (!tptr->second && !tptr->minute && !tptr->hour && !tptr->day && X !tptr->month && !tptr->year && !tptr->weekDay && !tptr->extra) { X strcpy(buf, " [No Date] "); X return (buf); X } X X /* only print weekDay if one was stored and if we're in FULL mode */ X if (!brief && tptr->weekDay) { X (void) sprintf(buf, "%s, ", WD[tptr->weekDay]); X } else { X buf[0] = '\0'; X } X (void) sprintf(buf2, "%.2d-%s-%.2d %.2d:%.2d", X (tptr->day)+1, MO[tptr->month], tptr->year, X tptr->hour, tptr->minute); X (void) strcat(buf, buf2); X if (!brief) { /* add seconds to long output */ X (void) sprintf(buf2, ":%.2d", tptr->second); X (void) strcat(buf, buf2); X } X return (buf); X} X X X/* X * Dump contents of the threads (used by FULL view mode) X */ Xstatic void DumpThreads(RNodePtr) XRNode *RNodePtr; X{ X int i; X fourbyt count = RNodePtr->RHptr->total_threads; X static char ind[4] = " "; /* indentation */ X THblock *THptr; X TNode *TNodePtr; X X /* go through all threads, printing as we go */ X TNodePtr = RNodePtr->TNodePtr; X for (i = 0; (fourbyt) i < count; i++) { X if (TNodePtr == (TNode *) NULL) { X fprintf(stderr, "WARNING: fewer threads than expected\n"); X return; X } X THptr = TNodePtr->THptr; X X printf("%s --> Information for thread %d\n", ind, i); X printf("%s thread_class: %s\n", ind, THptr->thread_class < TCn ? X TC[THptr->thread_class] : unknownStr); X printf("%s thread_format: %s\n", ind, THptr->thread_format < TFn ? X TF[THptr->thread_format] : unknownStr); X printf("%s thread_kind: %s ($%.2X)\n", ind, X (THptr->thread_kind < TKn && THptr->thread_class < TCn) ? X TK[THptr->thread_class][THptr->thread_kind] : unknownStr, X THptr->thread_kind); X printf("%s thread_crc: $%.4x\n", ind, THptr->thread_crc); X printf("%s thread_eof: %lu ", ind, THptr->thread_eof); X printf("comp_thread_eof: %lu\n", THptr->comp_thread_eof); X printf("%s * position within file: %ld\n", ind, TNodePtr->fileposn); X X TNodePtr = TNodePtr->TNext; X } X /* after all info printed, show sum total of thread lengths */ X printf("%s * total thread_eof: %lu ", ind, RNodePtr->unc_len); X printf("total comp_thread_eof: %lu\n", RNodePtr->comp_len); X} X X X/* X * Scan contents of the threads for certain things (for PROSHK view mode) X * Returns 65535 as error code (-1 in an unsigned short). X * Places the format, compressed EOF, and uncompressed EOF in the location X * pointed to by the appropriate variables. X * X * This will probably fail if there are > 32767 threads. X */ Xstatic twobyt ScanThreads(RNodePtr, format, dataCEOF, dataEOF) XRNode *RNodePtr; Xtwobyt *format; /* format of the data_fork thread */ Xlong *dataCEOF; /* length of the data_fork thread (compressed) */ Xlong *dataEOF; /* length of the data_fork thread (uncompressed) */ X{ X int i; X int count; X THblock *THptr; X TNode *TNodePtr; X X count = (int) RNodePtr->RHptr->total_threads; X *format = 65535; /* default = error */ X *dataCEOF = 0L; X *dataEOF = 0L; X TNodePtr = RNodePtr->TNodePtr; X for (i = 0; i < count; i++) { X if (TNodePtr == (TNode *) NULL) { X fprintf(stderr, "WARNING: fewer threads than expected\n"); X return (65535); X } X THptr = TNodePtr->THptr; X X if (THptr->thread_class == 2) { /* data thread? */ X *format = THptr->thread_format; X *dataCEOF = THptr->comp_thread_eof; X *dataEOF = THptr->thread_eof; X return (THptr->thread_kind); X } X TNodePtr = TNodePtr->TNext; X } X return (65535); /* no data thread found */ X} X X X/* X * View archive contents X * X * Format types: X * T: NAMEONLY - Brief output of filenames only (good for pipes) X * V: PROSHK - ProDOS ShrinkIt format X * Z: FULL - Fully detailed output X */ Xvoid NuView(filename, options) Xchar *filename; Xchar *options; X{ X ListHdr *archive; X MHblock *MHptr; X RHblock *RHptr; X RNode *RNodePtr; X outtype prtform; X int rec; X char tmpbuf[80]; /* temporary buffer for sprintf + printf */ X twobyt format, datakind; /* PROSHK */ X int percent; /* PROSHK */ X long dataCEOF, dataEOF; /* PROSHK */ X#ifdef APW /* kill "not used" messages */ X char *ptr; X#endif X static char *procName = "NuView"; X X /* process options ourselves */ X switch (options[0]) { X case 't': X if (INDEX(options+1, 'v')) prtform = PROSHK; /* -tv is same as -v */ X if (INDEX(options+1, 'z')) prtform = FULL; X else prtform = NAMEONLY; X break; X case 'v': X prtform = PROSHK; X break; X default: X fprintf(stderr, "%s internal error: unknown output format\n", prgName); X Quit (-1); X } X X archive = NuRead(filename); X MHptr = archive->MHptr; X X /* Print master header info */ X if (prtform == NAMEONLY) { X /* don't print any info from master header for NAMEONLY */ X } else if (prtform == PROSHK) { X#ifdef APW X /* strip partial paths from APW filename (if any) */ X ptr = RINDEX(archive->arc_name, '/'); X printf(" %-15.15s ", ptr ? ptr+1 : archive->arc_name); X#else X printf(" %-15.15s ", archive->arc_name); X#endif X printf("Created:%s ", PrintDate(&MHptr->arc_create_when, TRUE)); X printf("Mod:%s ", PrintDate(&MHptr->arc_mod_when, TRUE)); X printf("Recs:%5lu\n\n", MHptr->total_records); X printf(" Name Kind Typ Auxtyp Archived"); X printf(" Fmat Size Un-Length\n"); X printf("-------------------------------------------------") ; X printf("----------------------------\n"); X } else if (prtform == FULL) { X printf("Now processing archive '%s'\n", archive->arc_name); X printf("---> Master header information:\n"); X printf("master ID: '%.6s' ", MHptr->ID); X printf("master_version: $%.4x ", MHptr->master_version); X printf("master_crc: $%.4X\n", MHptr->master_crc); X printf("total_records: %lu ", MHptr->total_records); X if (MHptr->master_version >= 0x0001) { X printf("master_eof: %lu\n", MHptr->master_eof); X } else { X printf("\n"); X } X printf("created: %s ", PrintDate(&MHptr->arc_create_when, FALSE)); X printf("mod: %s\n", PrintDate(&MHptr->arc_mod_when, FALSE)); X } else { X printf("NuView internal error: undefined output format\n"); X Quit (-1); X } X X /* Print record info */ X RNodePtr = archive->RNodePtr; X for (rec = 0; (fourbyt) rec < MHptr->total_records; rec++) { X if (RNodePtr == (RNode *) NULL) { X fprintf(stderr, "WARNING: fewer records than expected\n"); X return; X } X RHptr = RNodePtr->RHptr; X X if (prtform == NAMEONLY) { X printf("%.79s\n", RNodePtr->filename); /* max 79 chars */ X } else if (prtform == PROSHK) { X printf("%c", (RHptr->access == 0xE3L || RHptr->access == 0xC3L) ? X ' ' : '+'); X printf("%-21.21s ", RNodePtr->filename); X /* get info on data_fork thread */ X datakind = ScanThreads(RNodePtr, &format, &dataCEOF, &dataEOF); X if (datakind == 65535) { /* no data thread... */ X printf("???? "); X printf("%s ", RHptr->file_type < 256L ? FT[RHptr->file_type] : X "???"); X printf("$%.4X ", (twobyt) RHptr->extra_type); X } else if (datakind == 1) { /* disk */ X printf("Disk "); X printf("--- "); X (void) sprintf(tmpbuf, "%dk", (twobyt) RHptr->extra_type / 2); X printf("%-5s ", tmpbuf); X } else { /* must be a file */ X printf("File "); X printf("%s ", RHptr->file_type < 256L ? FT[RHptr->file_type] : X "???"); X printf("$%.4X ", (twobyt) RHptr->extra_type); X } X printf("%s ", PrintDate(&RHptr->archive_when, TRUE)); X printf("%s ", format < QTFn ? QTF[format] : "???"); X X /* figure out the percent size, and format it appropriately */ X /* Note RNodePtr->comp_len corresponds to dataCEOF, and */ X /* RNodePtr->unc_len corresponds to dataEOF. */ X if (!dataCEOF && !dataEOF) { X printf("100%% "); /* file is 0 bytes long */ X } else if ((!dataEOF && dataCEOF) || (dataEOF && !dataCEOF)) { X printf("--- "); /* something weird happened */ X } else if (dataEOF < dataCEOF) { X printf(">100%% "); /* compression failed?!? */ X } else { /* compute from sum of thread lengths (use only data?) */ X percent = (((float) dataCEOF / X (float) dataEOF) * 100.0) /*+ 0.5*/ ; X (void) sprintf(tmpbuf, "%.2d%%", percent); X printf("%-4s ", tmpbuf); X } X if (!dataEOF && dataCEOF) /* weird */ X printf(" ????\n"); X else X printf("%8ld\n", dataEOF); X } else if (prtform == FULL) { X printf("\n---> Information for record %d:\n", rec); X printf("Filename: (%d) '%s'\n", X RNodePtr->filename_length, RNodePtr->filename); X printf("header ID: '%.4s' ", RHptr->ID); X printf("version_number: $%.4X ", RHptr->version_number); X printf("header_crc: $%.4X\n", RHptr->header_crc); X printf("attrib_count: %u ", RHptr->attrib_count); X printf("total_threads: %u\n", RHptr->total_threads); X printf("file_sys_id: %s ", RHptr->file_sys_id < FIDn ? X FID[RHptr->file_sys_id] : unknownStr); X printf("sep: '%c'\n", RHptr->file_sys_info); X if (RHptr->file_sys_id == 0x0001) { /* ProDOS-specific */ X printf("access: %s ($%.8lX) ", (RHptr->access == 0xE3L || X RHptr->access == 0xC3L) ? "Unlocked" : "Locked", RHptr->access); X printf("file_type: %s ($%.8lX)\n", RHptr->file_type < 256L ? X FT[RHptr->file_type] : "???", RHptr->file_type); X } else { /* all other filesystems */ X printf("access: $%.8lX ", RHptr->access); X printf("file_type: $%.8lX\n", RHptr->file_type); X } X printf("extra_type: $%.8lX ", RHptr->extra_type); X printf("storage_type: %s\n", RHptr->storage_type < STn ? X ST[RHptr->storage_type] : unknownStr); X printf("created: %s ", PrintDate(&RHptr->create_when, FALSE)); X printf("mod: %s\n", PrintDate(&RHptr->mod_when, FALSE)); X printf("archived: %s\n", PrintDate(&RHptr->archive_when, X FALSE)); X printf("GS/OS option_size: %.4x\n", RHptr->option_size); X /* future expansion... */ X } else { X printf("%s internal error: undefined output format\n", prgName); X Quit (-1); X } X X /* Print thread info */ X if (prtform == FULL) DumpThreads(RNodePtr); X RNodePtr = RNodePtr->RNext; /* advance to next record */ X#ifdef APW X if (STOP()) Quit (1); /* check for OA-period */ X#endif X } X if (prtform == FULL) X printf("\n*** end of file position: %ld\n", archive->nextposn); X} SHAR_EOF $TOUCH -am 0422130690 nuview.c && chmod 0644 nuview.c || echo "restore of nuview.c failed" set `wc -c nuview.c`;Wc_c=$1 if test "$Wc_c" != "14550"; then echo original size 14550, current size $Wc_c fi fi exit 0