home *** CD-ROM | disk | FTP | other *** search
- From: zip-bugs@wkuvx1.wku.edu (Info-ZIP group)
- Newsgroups: comp.sources.misc
- Subject: v44i075: unzip - Info-ZIP portable UnZip, version 5.12, Part10/20
- Date: 18 Sep 1994 23:15:39 -0500
- Organization: Sterling Software
- Sender: kent@sparky.sterling.com
- Approved: kent@sparky.sterling.com
- Message-ID: <35j39b$qoo@sparky.sterling.com>
- X-Md4-Signature: 12240212bb0bb59b8042f362e7312e91
-
- Submitted-by: zip-bugs@wkuvx1.wku.edu (Info-ZIP group)
- Posting-number: Volume 44, Issue 75
- Archive-name: unzip/part10
- Environment: UNIX, VMS, OS/2, MS-DOS, MACINTOSH, WIN-NT, LINUX, MINIX, COHERENT, AMIGA?, ATARI TOS, SGI, DEC, Cray, Convex, Amdahl, Sun
- Supersedes: unzip50: Volume 31, Issue 104-117
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then feed it
- # into a shell via "sh file" or similar. To overwrite existing files,
- # type "sh file -c".
- # Contents: unzip-5.12/file_io.c unzip-5.12/tops20/make.mic
- # unzip-5.12/unix/unix.c
- # Wrapped by kent@sparky on Sat Sep 17 23:33:41 1994
- PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
- echo If this archive is complete, you will see the following message:
- echo ' "shar: End of archive 10 (of 20)."'
- if test -f 'unzip-5.12/file_io.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'unzip-5.12/file_io.c'\"
- else
- echo shar: Extracting \"'unzip-5.12/file_io.c'\" \(35360 characters\)
- sed "s/^X//" >'unzip-5.12/file_io.c' <<'END_OF_FILE'
- X/*---------------------------------------------------------------------------
- X
- X file_io.c
- X
- X This file contains routines for doing direct but relatively generic input/
- X output, file-related sorts of things, plus some miscellaneous stuff. Most
- X of the stuff has to do with opening, closing, reading and/or writing files.
- X
- X Contains: open_input_file()
- X open_outfile() (non-VMS)
- X readbuf()
- X readbyte()
- X flush() (non-VMS)
- X disk_error() (non-VMS)
- X handler()
- X dos_to_unix_time() (non-VMS, non-OS/2)
- X check_for_newer() (non-VMS, non-OS/2)
- X find_ecrec()
- X get_cdir_ent()
- X do_string()
- X makeword()
- X makelong()
- X memset() (ZMEM only)
- X memcpy() (ZMEM only)
- X zstrnicmp()
- X zstat() (REGULUS only)
- X LoadFarString() (SMALL_MEM only)
- X LoadFarStringSmall() (SMALL_MEM only)
- X LoadFarStringSmall2() (SMALL_MEM only)
- X
- X ---------------------------------------------------------------------------*/
- X
- X
- X#define FILE_IO_C
- X#include "unzip.h"
- X#include "crypt.h"
- X#include "tables.h" /* definition/initialization of ebcdic[] */
- X
- X#ifdef USE_FWRITE
- X# define WriteError(buf,len,strm) \
- X ((extent)fwrite((char *)(buf),1,(extent)(len),strm) != (extent)(len))
- X#else
- X# define WriteError(buf,len,strm) \
- X ((extent)write(fileno(strm),(char *)(buf),(extent)(len)) != (extent)(len))
- X#endif
- X
- Xstatic int disk_error OF((void));
- X
- X
- X
- X/*****************************/
- X/* Strings used in file_io.c */
- X/*****************************/
- X
- X#ifdef UNIX
- X static char Far CannotDeleteOldFile[] = "\nerror: cannot delete old %s\n";
- X#endif
- X
- Xstatic char Far CantOpenZipfile[] = "error: can't open zipfile [ %s ]\n";
- Xstatic char Far CannotCreateFile[] = "\nerror: cannot create %s\n";
- Xstatic char Far ReadError[] = "error: zipfile read error\n";
- Xstatic char Far DiskFull[] =
- X "\n%s: write error (disk full?). Continue? (y/n/^C) ";
- Xstatic char Far ZipfileCorrupt[] = "error: zipfile probably corrupt (%s)\n";
- Xstatic char Far CentDirEndSigNotFound[] = "\
- X End-of-central-directory signature not found. Either this file is not\n\
- X a zipfile, or it constitutes one disk of a multi-part archive. In the\n\
- X latter case the central directory and zipfile comment will be found on\n\
- X the last disk(s) of this archive.\n";
- Xstatic char Far FilenameTooLongTrunc[] =
- X "warning: filename too long--truncating.\n";
- Xstatic char Far ExtraFieldTooLong[] =
- X "warning: extra field too long (%d). Ignoring...\n";
- X
- X
- X
- X
- X
- X/******************************/
- X/* Function open_input_file() */
- X/******************************/
- X
- Xint open_input_file() /* return 1 if open failed */
- X{
- X /*
- X * open the zipfile for reading and in BINARY mode to prevent cr/lf
- X * translation, which would corrupt the bitstreams
- X */
- X
- X#if defined(UNIX) || defined(TOPS20) || defined(ATARI_ST)
- X zipfd = open(zipfn, O_RDONLY);
- X#else /* !(UNIX || TOPS20) */
- X#ifdef VMS
- X zipfd = open(zipfn, O_RDONLY, 0, "ctx=stm");
- X#else /* !VMS */
- X#ifdef MACOS
- X zipfd = open(zipfn, 0);
- X#else /* !MACOS */
- X zipfd = open(zipfn, O_RDONLY | O_BINARY);
- X#endif /* ?MACOS */
- X#endif /* ?VMS */
- X#endif /* ?(UNIX || TOPS20) */
- X if (zipfd < 0) {
- X FPRINTF(stderr, LoadFarString(CantOpenZipfile), zipfn);
- X return 1;
- X }
- X return 0;
- X
- X} /* end function open_input_file() */
- X
- X
- X
- X
- X#ifndef VMS /* for VMS use code in vms.c */
- X
- X/***************************/
- X/* Function open_outfile() */
- X/***************************/
- X
- Xint open_outfile() /* return 1 if fail */
- X{
- X#ifdef DOS_NT_OS2
- X if (stat(filename, &statbuf) == 0 && !(statbuf.st_mode & S_IWRITE))
- X chmod(filename, S_IREAD | S_IWRITE);
- X#endif
- X#ifdef UNIX
- X if (stat(filename, &statbuf) == 0 && unlink(filename) < 0) {
- X FPRINTF(stderr, LoadFarString(CannotDeleteOldFile), filename);
- X return 1;
- X }
- X#endif
- X#ifdef TOPS20
- X char *tfilnam;
- X
- X if ((tfilnam = (char *)malloc(2*strlen(filename)+1)) == (char *)NULL)
- X return 1;
- X strcpy(tfilnam, filename);
- X upper(tfilnam);
- X enquote(tfilnam);
- X if ((outfile = fopen(tfilnam, FOPW)) == (FILE *)NULL) {
- X FPRINTF(stderr, LoadFarString(CannotCreateFile), tfilnam);
- X free(tfilnam);
- X return 1;
- X }
- X free(tfilnam);
- X#else
- X#ifdef MTS
- X if (aflag)
- X outfile = fopen(filename, FOPWT);
- X else
- X outfile = fopen(filename, FOPW);
- X if (outfile == (FILE *)NULL) {
- X FPRINTF(stderr, LoadFarString(CannotCreateFile), filename);
- X return 1;
- X }
- X#else
- X if ((outfile = fopen(filename, FOPW)) == (FILE *)NULL) {
- X FPRINTF(stderr, LoadFarString(CannotCreateFile), filename);
- X return 1;
- X }
- X#endif
- X#endif
- X
- X#if 0 /* this SUCKS! on Ultrix, it must be writing a byte at a time... */
- X setbuf(outfile, (char *)NULL); /* make output unbuffered */
- X#endif
- X
- X#ifdef USE_FWRITE
- X#ifdef DOS_NT_OS2
- X /* 16-bit MSC: buffer size must be strictly LESS than 32K (WSIZE): bogus */
- X setbuf(outfile, (char *)NULL); /* make output unbuffered */
- X#else /* !DOS_NT_OS2 */
- X#ifdef _IOFBF /* make output fully buffered (works just about like write()) */
- X setvbuf(outfile, (char *)slide, _IOFBF, WSIZE);
- X#else
- X setbuf(outfile, (char *)slide);
- X#endif
- X#endif /* ?DOS_NT_OS2 */
- X#endif /* USE_FWRITE */
- X return 0;
- X
- X} /* end function open_outfile() */
- X
- X#endif /* !VMS */
- X
- X
- X
- X
- X
- X/**********************/
- X/* Function readbuf() */
- X/**********************/
- X
- Xunsigned readbuf(buf, size) /* return number of bytes read into buf */
- X char *buf;
- X register unsigned size;
- X{
- X register unsigned count;
- X unsigned n;
- X
- X n = size;
- X while (size) {
- X if (incnt == 0) {
- X#ifdef OLD_READBUF
- X if ((incnt = read(zipfd, (char *)inbuf, INBUFSIZ)) <= 0)
- X return (n-size);
- X#else
- X if ((incnt = read(zipfd, (char *)inbuf, INBUFSIZ)) == 0)
- X return (n-size);
- X else if (incnt < 0) {
- X FPRINTF(stderr, LoadFarString(ReadError));
- X return 0; /* discarding some data; better than lock-up */
- X }
- X#endif
- X /* buffer ALWAYS starts on a block boundary: */
- X cur_zipfile_bufstart += INBUFSIZ;
- X inptr = inbuf;
- X }
- X count = MIN(size, (unsigned)incnt);
- X memcpy(buf, inptr, count);
- X buf += count;
- X inptr += count;
- X incnt -= count;
- X size -= count;
- X }
- X return n;
- X
- X} /* end function readbuf() */
- X
- X
- X
- X
- X
- X/***********************/
- X/* Function readbyte() */
- X/***********************/
- X
- Xint readbyte() /* refill inbuf and return a byte if available, else EOF */
- X{
- X if (mem_mode || (incnt = read(zipfd,(char *)inbuf,INBUFSIZ)) <= 0)
- X return EOF;
- X cur_zipfile_bufstart += INBUFSIZ; /* always starts on a block boundary */
- X inptr = inbuf;
- X
- X#ifdef CRYPT
- X if (pInfo->encrypted) {
- X uch *p;
- X int n;
- X
- X for (n = (long)incnt > csize + 1 ? (int)csize + 1 : incnt,
- X p = inptr; n--; p++)
- X zdecode(*p);
- X }
- X#endif /* CRYPT */
- X
- X --incnt;
- X return *inptr++;
- X
- X} /* end function readbyte() */
- X
- X
- X
- X
- X
- X#ifndef VMS /* for VMS use code in vms.c */
- X
- X/********************/
- X/* Function flush() */
- X/********************/
- X
- Xint flush(rawbuf, size, unshrink) /* cflag => always 0; 50 if write error */
- X uch *rawbuf;
- X ulg size;
- X int unshrink;
- X{
- X#ifdef ASM_CRC
- X ulg CalcCRC(ulg *crc_table, ulg crcval, uch *rawbuf, ulg rawbufsize);
- X#else
- X register ulg crcval = crc32val;
- X register ulg n = size;
- X#endif
- X register uch *p, *q;
- X uch *transbuf;
- X ulg transbufsiz;
- X static int didCRlast = FALSE;
- X
- X
- X/*---------------------------------------------------------------------------
- X Compute the CRC first; if testing or if disk is full, that's it.
- X ---------------------------------------------------------------------------*/
- X
- X#ifdef ASM_CRC
- X crc32val = CalcCRC(crc_32_tab, crc32val, rawbuf, size);
- X#else
- X p = rawbuf;
- X while (n--)
- X crcval = crc_32_tab[((uch)crcval ^ (*p++)) & 0xff] ^ (crcval >> 8);
- X crc32val = crcval;
- X#endif /* ?ASM_CRC */
- X
- X if (tflag || size == 0L) /* testing or nothing to write: all done */
- X return 0;
- X
- X if (disk_full)
- X return 50; /* disk already full: ignore rest of file */
- X
- X/*---------------------------------------------------------------------------
- X Write the bytes rawbuf[0..size-1] to the output device, first converting
- X end-of-lines and ASCII/EBCDIC as needed. If SMALL_MEM or MED_MEM are NOT
- X defined, outbuf is assumed to be at least as large as rawbuf and is not
- X necessarily checked for overflow.
- X ---------------------------------------------------------------------------*/
- X
- X if (!pInfo->textmode) {
- X /* GRR: note that for standard MS-DOS compilers, size argument to
- X * fwrite() can never be more than 65534, so WriteError macro will
- X * have to be rewritten if size can ever be that large. For now,
- X * never more than 32K. Also note that write() returns an int, which
- X * doesn't necessarily limit size to 32767 bytes if write() is used
- X * on 16-bit systems but does make it more of a pain; however, because
- X * at least MSC 5.1 has a lousy implementation of fwrite() (as does
- X * DEC Ultrix cc), write() is used anyway.
- X */
- X if (WriteError(rawbuf, size, outfile)) /* write raw binary data */
- X return cflag? 0 : disk_error();
- X } else {
- X if (unshrink) {
- X /* rawbuf = outbuf */
- X transbuf = outbuf2;
- X transbufsiz = TRANSBUFSIZ;
- X } else {
- X /* rawbuf = slide */
- X transbuf = outbuf;
- X transbufsiz = OUTBUFSIZ;
- X Trace((stderr, "\ntransbufsiz = OUTBUFSIZ = %u\n", OUTBUFSIZ));
- X }
- X if (newfile) {
- X didCRlast = FALSE; /* no previous buffers written */
- X newfile = FALSE;
- X }
- X p = rawbuf;
- X if (*p == LF && didCRlast)
- X ++p;
- X
- X /*-----------------------------------------------------------------------
- X Algorithm: CR/LF => native; lone CR => native; lone LF => native.
- X This routine is only for non-raw-VMS, non-raw-VM/CMS files (i.e.,
- X stream-oriented files, not record-oriented).
- X -----------------------------------------------------------------------*/
- X
- X for (didCRlast = FALSE, q = transbuf; p < rawbuf+size; ++p) {
- X if (*p == CR) { /* lone CR or CR/LF: EOL either way */
- X PutNativeEOL
- X if (p == rawbuf+size-1) /* last char in buffer */
- X didCRlast = TRUE;
- X else if (p[1] == LF) /* get rid of accompanying LF */
- X ++p;
- X } else if (*p == LF) /* lone LF */
- X PutNativeEOL
- X else
- X#ifndef DOS_NT_OS2
- X if (*p != CTRLZ) /* lose all ^Z's */
- X#endif
- X *q++ = native(*p);
- X
- X#if (defined(SMALL_MEM) || defined(MED_MEM))
- X# if (lenEOL == 1) /* don't check unshrink: both buffers small but equal */
- X if (!unshrink)
- X# endif
- X /* check for danger of buffer overflow and flush */
- X if (q > transbuf+transbufsiz-lenEOL) {
- X Trace((stderr,
- X "p - rawbuf = %u q-transbuf = %u size = %lu\n",
- X (unsigned)(p-rawbuf), (unsigned)(q-transbuf), size));
- X if (WriteError(transbuf, (unsigned)(q-transbuf), outfile))
- X return cflag? 0 : disk_error();
- X q = transbuf;
- X continue;
- X }
- X#endif /* SMALL_MEM || MED_MEM */
- X }
- X
- X /*-----------------------------------------------------------------------
- X Done translating: write whatever we've got to file.
- X -----------------------------------------------------------------------*/
- X
- X Trace((stderr, "p - rawbuf = %u q-transbuf = %u size = %lu\n",
- X (unsigned)(p-rawbuf), (unsigned)(q-transbuf), size));
- X if (q > transbuf &&
- X WriteError(transbuf, (unsigned)(q-transbuf), outfile))
- X return cflag? 0 : disk_error();
- X }
- X
- X return 0;
- X
- X} /* end function flush() */
- X
- X
- X
- X
- X
- X/*************************/
- X/* Function disk_error() */
- X/*************************/
- X
- Xstatic int disk_error()
- X{
- X FPRINTF(stderr, LoadFarString(DiskFull), filename);
- X FFLUSH(stderr);
- X
- X#ifndef MSWIN
- X fgets(answerbuf, 9, stdin);
- X if (*answerbuf == 'y') /* stop writing to this file */
- X disk_full = 1; /* (outfile bad?), but new OK */
- X else
- X#endif
- X disk_full = 2; /* no: exit program */
- X
- X return 50; /* 50: disk full */
- X
- X} /* end function disk_error() */
- X
- X#endif /* !VMS */
- X
- X
- X
- X
- X
- X/**********************/
- X/* Function handler() */
- X/**********************/
- X
- Xvoid handler(signal) /* upon interrupt, turn on echo and exit cleanly */
- X int signal;
- X{
- X#if defined(SIGBUS) || defined(SIGSEGV)
- X# ifdef SMALL_MEM
- X static char *corrupt;
- X corrupt = LoadFarString(ZipfileCorrupt);
- X# else
- X static char *corrupt = LoadFarString(ZipfileCorrupt);
- X# endif
- X#endif
- X
- X#if !defined(DOS_NT_OS2) && !defined(MACOS)
- X echon();
- X PUTC('\n', stderr);
- X#endif /* !DOS_NT_OS2 && !MACOS */
- X#ifdef SIGBUS
- X if (signal == SIGBUS) {
- X FPRINTF(stderr, corrupt, "bus error");
- X exit(3);
- X }
- X#endif /* SIGBUS */
- X#ifdef SIGSEGV
- X if (signal == SIGSEGV) {
- X FPRINTF(stderr, corrupt, "segmentation violation");
- X exit(3);
- X }
- X#endif /* SIGSEGV */
- X exit(0);
- X}
- X
- X
- X
- X
- X
- X#ifdef DEBUG_TIME
- X# define TTrace(x) FPRINTF x
- X#else
- X# define TTrace(x)
- X#endif
- X
- X#if !defined(VMS) && !defined(OS2)
- X
- X/*******************************/
- X/* Function dos_to_unix_time() */ /* only used for freshening/updating */
- X/*******************************/
- X
- Xtime_t dos_to_unix_time(ddate, dtime)
- X unsigned ddate, dtime;
- X{
- X int yr, mo, dy, hh, mm, ss;
- X#ifdef TOPS20
- X# define YRBASE 1900
- X struct tmx *tmx;
- X char temp[20];
- X time_t retval;
- X#else /* !TOPS20 */
- X# define YRBASE 1970
- X static short yday[]={0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
- X int leap;
- X long m_time, days=0;
- X#if (!defined(MACOS) && !defined(MSC))
- X#if (defined(BSD) || defined(MTS) || defined(__GO32__))
- X#ifndef BSD4_4
- X static struct timeb tbp;
- X#endif /* !BSD4_4 */
- X#else /* !(BSD || MTS || __GO32__) */
- X#ifdef ATARI_ST
- X extern long _timezone;
- X# define timezone _timezone; /* a whoops in our library... */
- X#else /* !ATARI_ST */
- X extern long timezone; /* declared in <time.h> for MSC (& Borland?) */
- X#endif /* ?ATARI_ST */
- X#endif /* ?(BSD || MTS || __GO32__) */
- X#endif /* !MACOS && !MSC */
- X#endif /* ?TOPS20 */
- X
- X
- X /* dissect date */
- X yr = ((ddate >> 9) & 0x7f) + (1980 - YRBASE);
- X mo = ((ddate >> 5) & 0x0f) - 1;
- X dy = (ddate & 0x1f) - 1;
- X
- X /* dissect time */
- X hh = (dtime >> 11) & 0x1f;
- X mm = (dtime >> 5) & 0x3f;
- X ss = (dtime & 0x1f) * 2;
- X
- X#ifdef TOPS20
- X tmx = (struct tmx *)malloc(sizeof(struct tmx));
- X sprintf (temp, "%02d/%02d/%02d %02d:%02d:%02d", mo+1, dy+1, yr, hh, mm, ss);
- X time_parse(temp, tmx, (char *)0);
- X retval = time_make(tmx);
- X free(tmx);
- X return retval;
- X
- X#else /* !TOPS20 */
- X /* leap = # of leap years from BASE up to but not including current year */
- X leap = ((yr + YRBASE - 1) / 4); /* leap year base factor */
- X
- X /* calculate days from BASE to this year and add expired days this year */
- X days = (yr * 365) + (leap - 492) + yday[mo];
- X
- X /* if year is a leap year and month is after February, add another day */
- X if ((mo > 1) && ((yr+YRBASE)%4 == 0) && ((yr+YRBASE) != 2100))
- X ++days; /* OK through 2199 */
- X
- X /* convert date & time to seconds relative to 00:00:00, 01/01/YRBASE */
- X m_time = ((long)(days + dy) * 86400L) + ((long)hh * 3600) + (mm * 60) + ss;
- X /* - 1; MS-DOS times always rounded up to nearest even second */
- X TTrace((stderr, "dos_to_unix_time:\n"));
- X TTrace((stderr, " m_time before timezone = %ld\n", m_time));
- X
- X#ifndef MACOS
- X#if (defined(BSD) || defined(MTS) || defined(__GO32__))
- X#ifndef BSD4_4
- X ftime(&tbp);
- X m_time += tbp.timezone * 60L;
- X#endif
- X#else /* !(BSD || MTS || __GO32__) */
- X#ifdef WIN32
- X {
- X TIME_ZONE_INFORMATION tzinfo;
- X DWORD res;
- X
- X /* account for timezone differences */
- X res = GetTimeZoneInformation(&tzinfo);
- X if (res == TIME_ZONE_ID_STANDARD)
- X m_time += 60*(tzinfo.Bias + tzinfo.StandardBias);
- X else if (res == TIME_ZONE_ID_DAYLIGHT)
- X m_time += 60*(tzinfo.Bias + tzinfo.DaylightBias);
- X /* GRR: are other return-values possible? */
- X }
- X#else /* !WIN32 */
- X tzset(); /* set `timezone' variable */
- X m_time += timezone;
- X#endif /* ?WIN32 */
- X#endif /* ?(BSD || MTS || __GO32__) */
- X#endif /* !MACOS */
- X TTrace((stderr, " m_time after timezone = %ld\n", m_time));
- X
- X#ifdef BSD4_4 /* see comments in unix.c */
- X m_time -= localtime((time_t *) &m_time)->tm_gmtoff;
- X#else /* !BSD4_4 */
- X#ifndef WIN32
- X if (localtime((time_t *)&m_time)->tm_isdst)
- X m_time -= 60L * 60L; /* adjust for daylight savings time */
- X#endif /* !WIN32 */
- X#endif /* ?BSD4_4 */
- X TTrace((stderr, " m_time after DST = %ld\n", m_time));
- X
- X return m_time;
- X#endif /* ?TOPS20 */
- X
- X} /* end function dos_to_unix_time() */
- X
- X
- X
- X
- X
- X/******************************/
- X/* Function check_for_newer() */ /* only used for freshening/updating */
- X/******************************/
- X
- Xint check_for_newer(filename) /* return 1 if existing file newer or equal; */
- X char *filename; /* 0 if older; -1 if doesn't exist yet */
- X{
- X time_t existing, archive;
- X
- X if (stat(filename, &statbuf))
- X return DOES_NOT_EXIST;
- X
- X /* round up existing filetime to nearest 2 seconds for comparison */
- X existing = (statbuf.st_mtime & 1) ? statbuf.st_mtime+1 : statbuf.st_mtime;
- X archive = dos_to_unix_time(lrec.last_mod_file_date,
- X lrec.last_mod_file_time);
- X
- X TTrace((stderr, "check_for_newer: existing %ld, archive %ld, e-a %ld\n",
- X existing, archive, existing-archive));
- X
- X return (existing >= archive);
- X
- X} /* end function check_for_newer() */
- X
- X#endif /* !VMS && !OS2 */
- X
- X
- X
- X
- X
- X/*************************/
- X/* Function find_ecrec() */
- X/*************************/
- X
- Xint find_ecrec(searchlen) /* return PK-class error */
- X long searchlen;
- X{
- X int i, numblks, found=FALSE;
- X LONGINT tail_len;
- X ec_byte_rec byterec;
- X
- X
- X/*---------------------------------------------------------------------------
- X Treat case of short zipfile separately.
- X ---------------------------------------------------------------------------*/
- X
- X if (ziplen <= INBUFSIZ) {
- X lseek(zipfd, 0L, SEEK_SET);
- X if ((incnt = read(zipfd,(char *)inbuf,(unsigned int)ziplen)) ==
- X (int)ziplen)
- X
- X /* 'P' must be at least 22 bytes from end of zipfile */
- X for (inptr = inbuf+(int)ziplen-22; inptr >= inbuf; --inptr)
- X if ((native(*inptr) == 'P') &&
- X !strncmp((char *)inptr, end_central_sig, 4)) {
- X incnt -= inptr - inbuf;
- X found = TRUE;
- X break;
- X }
- X
- X/*---------------------------------------------------------------------------
- X Zipfile is longer than INBUFSIZ: may need to loop. Start with short
- X block at end of zipfile (if not TOO short).
- X ---------------------------------------------------------------------------*/
- X
- X } else {
- X if ((tail_len = ziplen % INBUFSIZ) > ECREC_SIZE) {
- X cur_zipfile_bufstart = lseek(zipfd, ziplen-tail_len, SEEK_SET);
- X if ((incnt = read(zipfd,(char *)inbuf,(unsigned int)tail_len)) !=
- X (int)tail_len)
- X goto fail; /* shut up; it's expedient */
- X
- X /* 'P' must be at least 22 bytes from end of zipfile */
- X for (inptr = inbuf+(int)tail_len-22; inptr >= inbuf; --inptr)
- X if ((native(*inptr) == 'P') &&
- X !strncmp((char *)inptr, end_central_sig, 4)) {
- X incnt -= inptr - inbuf;
- X found = TRUE;
- X break;
- X }
- X /* sig may span block boundary: */
- X strncpy((char *)hold, (char *)inbuf, 3);
- X } else
- X cur_zipfile_bufstart = ziplen - tail_len;
- X
- X /*-----------------------------------------------------------------------
- X Loop through blocks of zipfile data, starting at the end and going
- X toward the beginning. In general, need not check whole zipfile for
- X signature, but may want to do so if testing.
- X -----------------------------------------------------------------------*/
- X
- X numblks = (int)((searchlen - tail_len + (INBUFSIZ-1)) / INBUFSIZ);
- X /* ==amount= ==done== ==rounding== =blksiz= */
- X
- X for (i = 1; !found && (i <= numblks); ++i) {
- X cur_zipfile_bufstart -= INBUFSIZ;
- X lseek(zipfd, cur_zipfile_bufstart, SEEK_SET);
- X if ((incnt = read(zipfd,(char *)inbuf,INBUFSIZ)) != INBUFSIZ)
- X break; /* fall through and fail */
- X
- X for (inptr = inbuf+INBUFSIZ-1; inptr >= inbuf; --inptr)
- X if ((native(*inptr) == 'P') &&
- X !strncmp((char *)inptr, end_central_sig, 4)) {
- X incnt -= inptr - inbuf;
- X found = TRUE;
- X break;
- X }
- X /* sig may span block boundary: */
- X strncpy((char *)hold, (char *)inbuf, 3);
- X }
- X } /* end if (ziplen > INBUFSIZ) */
- X
- X/*---------------------------------------------------------------------------
- X Searched through whole region where signature should be without finding
- X it. Print informational message and die a horrible death.
- X ---------------------------------------------------------------------------*/
- X
- Xfail:
- X if (!found) {
- X#ifdef MSWIN
- X MessageBeep(1);
- X#endif
- X if (qflag || (zipinfo_mode && !hflag))
- X FPRINTF(stderr, "[%s]\n", zipfn);
- X FPRINTF(stderr, LoadFarString(CentDirEndSigNotFound));
- X return PK_ERR; /* failed */
- X }
- X
- X/*---------------------------------------------------------------------------
- X Found the signature, so get the end-central data before returning. Do
- X any necessary machine-type conversions (byte ordering, structure padding
- X compensation) by reading data into character array and copying to struct.
- X ---------------------------------------------------------------------------*/
- X
- X real_ecrec_offset = cur_zipfile_bufstart + (inptr-inbuf);
- X#ifdef TEST
- X printf("\n found end-of-central-dir signature at offset %ld (%.8lXh)\n",
- X real_ecrec_offset, real_ecrec_offset);
- X printf(" from beginning of file; offset %d (%.4Xh) within block\n",
- X inptr-inbuf, inptr-inbuf);
- X#endif
- X
- X if (readbuf((char *)byterec, ECREC_SIZE+4) == 0)
- X return PK_EOF;
- X
- X ecrec.number_this_disk =
- X makeword(&byterec[NUMBER_THIS_DISK]);
- X ecrec.num_disk_with_start_central_dir =
- X makeword(&byterec[NUM_DISK_WITH_START_CENTRAL_DIR]);
- X ecrec.num_entries_centrl_dir_ths_disk =
- X makeword(&byterec[NUM_ENTRIES_CENTRL_DIR_THS_DISK]);
- X ecrec.total_entries_central_dir =
- X makeword(&byterec[TOTAL_ENTRIES_CENTRAL_DIR]);
- X ecrec.size_central_directory =
- X makelong(&byterec[SIZE_CENTRAL_DIRECTORY]);
- X ecrec.offset_start_central_directory =
- X makelong(&byterec[OFFSET_START_CENTRAL_DIRECTORY]);
- X ecrec.zipfile_comment_length =
- X makeword(&byterec[ZIPFILE_COMMENT_LENGTH]);
- X
- X expect_ecrec_offset = ecrec.offset_start_central_directory +
- X ecrec.size_central_directory;
- X return PK_COOL;
- X
- X} /* end function find_ecrec() */
- X
- X
- X
- X
- X
- X/***************************/
- X/* Function get_cdir_ent() */
- X/***************************/
- X
- Xint get_cdir_ent() /* return PK-type error code */
- X{
- X cdir_byte_hdr byterec;
- X
- X
- X/*---------------------------------------------------------------------------
- X Read the next central directory entry and do any necessary machine-type
- X conversions (byte ordering, structure padding compensation--do so by
- X copying the data from the array into which it was read (byterec) to the
- X usable struct (crec)).
- X ---------------------------------------------------------------------------*/
- X
- X if (readbuf((char *)byterec, CREC_SIZE) == 0)
- X return PK_EOF;
- X
- X crec.version_made_by[0] = byterec[C_VERSION_MADE_BY_0];
- X crec.version_made_by[1] = byterec[C_VERSION_MADE_BY_1];
- X crec.version_needed_to_extract[0] = byterec[C_VERSION_NEEDED_TO_EXTRACT_0];
- X crec.version_needed_to_extract[1] = byterec[C_VERSION_NEEDED_TO_EXTRACT_1];
- X
- X crec.general_purpose_bit_flag =
- X makeword(&byterec[C_GENERAL_PURPOSE_BIT_FLAG]);
- X crec.compression_method =
- X makeword(&byterec[C_COMPRESSION_METHOD]);
- X crec.last_mod_file_time =
- X makeword(&byterec[C_LAST_MOD_FILE_TIME]);
- X crec.last_mod_file_date =
- X makeword(&byterec[C_LAST_MOD_FILE_DATE]);
- X crec.crc32 =
- X makelong(&byterec[C_CRC32]);
- X crec.csize =
- X makelong(&byterec[C_COMPRESSED_SIZE]);
- X crec.ucsize =
- X makelong(&byterec[C_UNCOMPRESSED_SIZE]);
- X crec.filename_length =
- X makeword(&byterec[C_FILENAME_LENGTH]);
- X crec.extra_field_length =
- X makeword(&byterec[C_EXTRA_FIELD_LENGTH]);
- X crec.file_comment_length =
- X makeword(&byterec[C_FILE_COMMENT_LENGTH]);
- X crec.disk_number_start =
- X makeword(&byterec[C_DISK_NUMBER_START]);
- X crec.internal_file_attributes =
- X makeword(&byterec[C_INTERNAL_FILE_ATTRIBUTES]);
- X crec.external_file_attributes =
- X makelong(&byterec[C_EXTERNAL_FILE_ATTRIBUTES]); /* LONG, not word! */
- X crec.relative_offset_local_header =
- X makelong(&byterec[C_RELATIVE_OFFSET_LOCAL_HEADER]);
- X
- X return PK_COOL;
- X
- X} /* end function get_cdir_ent() */
- X
- X
- X
- X
- X
- X/************************/
- X/* Function do_string() */
- X/************************/
- X
- Xint do_string(len, option) /* return PK-type error code */
- X unsigned int len; /* without prototype, ush converted to this */
- X int option;
- X{
- X long comment_bytes_left, block_length;
- X int error=PK_OK;
- X ush extra_len;
- X
- X
- X/*---------------------------------------------------------------------------
- X This function processes arbitrary-length (well, usually) strings. Three
- X options are allowed: SKIP, wherein the string is skipped (pretty logical,
- X eh?); DISPLAY, wherein the string is printed to standard output after un-
- X dergoing any necessary or unnecessary character conversions; and FILENAME,
- X wherein the string is put into the filename[] array after undergoing ap-
- X propriate conversions (including case-conversion, if that is indicated:
- X see the global variable pInfo->lcflag). The latter option should be OK,
- X since filename is now dimensioned at 1025, but we check anyway.
- X
- X The string, by the way, is assumed to start at the current file-pointer
- X position; its length is given by len. So start off by checking length
- X of string: if zero, we're already done.
- X ---------------------------------------------------------------------------*/
- X
- X if (!len)
- X return PK_COOL;
- X
- X switch (option) {
- X
- X /*
- X * First case: print string on standard output. First set loop vari-
- X * ables, then loop through the comment in chunks of OUTBUFSIZ bytes,
- X * converting formats and printing as we go. The second half of the
- X * loop conditional was added because the file might be truncated, in
- X * which case comment_bytes_left will remain at some non-zero value for
- X * all time. outbuf and slide are used as scratch buffers because they
- X * are available (we should be either before or in between any file pro-
- X * cessing).
- X */
- X
- X case DISPLAY:
- X comment_bytes_left = len;
- X block_length = OUTBUFSIZ; /* for the while statement, first time */
- X while (comment_bytes_left > 0 && block_length > 0) {
- X#ifndef MSWIN
- X register uch *p = outbuf;
- X register uch *q = outbuf;
- X#endif
- X if ((block_length = readbuf((char *)outbuf,
- X (unsigned) MIN((long)OUTBUFSIZ, comment_bytes_left))) == 0)
- X return PK_EOF;
- X comment_bytes_left -= block_length;
- X
- X /* this is why we allocated an extra byte for outbuf: */
- X outbuf[block_length] = '\0'; /* terminate w/zero: ASCIIZ */
- X
- X /* remove all ASCII carriage returns comment before printing
- X * (since used before A_TO_N(), check for CR instead of '\r')
- X */
- X while (*p) {
- X while (*p == CR)
- X ++p;
- X *q++ = *p++;
- X }
- X /* could check whether (p - outbuf) == block_length here */
- X *q = '\0';
- X
- X A_TO_N(outbuf); /* translate string to native */
- X
- X#ifdef MSWIN
- X /* ran out of local mem -- had to cheat */
- X WriteStringToMsgWin(outbuf, bRealTimeMsgUpdate);
- X#else /* !MSWIN */
- X#ifdef NATIVE
- X PRINTF("%s", outbuf); /* GRR: can ANSI be used with EBCDIC? */
- X#else /* ASCII */
- X p = outbuf - 1;
- X q = slide;
- X while (*++p) {
- X if (*p == 0x1B) { /* ASCII escape char */
- X *q++ = '^';
- X *q++ = '[';
- X } else
- X *q++ = *p;
- X if ((unsigned)(q-slide) > WSIZE-3) { /* time to flush */
- X *q = '\0';
- X PRINTF("%s", slide);
- X q = slide;
- X }
- X }
- X *q = '\0';
- X PRINTF("%s", slide);
- X#endif /* ?NATIVE */
- X#endif /* ?MSWIN */
- X }
- X PRINTF("\n"); /* assume no newline at end */
- X break;
- X
- X /*
- X * Second case: read string into filename[] array. The filename should
- X * never ever be longer than FILNAMSIZ-1 (1024), but for now we'll check,
- X * just to be sure.
- X */
- X
- X case FILENAME:
- X extra_len = 0;
- X if (len >= FILNAMSIZ) {
- X FPRINTF(stderr, LoadFarString(FilenameTooLongTrunc));
- X error = PK_WARN;
- X extra_len = len - FILNAMSIZ + 1;
- X len = FILNAMSIZ - 1;
- X }
- X if (readbuf(filename, len) == 0)
- X return PK_EOF;
- X filename[len] = '\0'; /* terminate w/zero: ASCIIZ */
- X
- X A_TO_N(filename); /* translate string to native */
- X
- X if (pInfo->lcflag) /* replace with lowercase filename */
- X TOLOWER(filename, filename);
- X
- X if (pInfo->vollabel && len > 8 && filename[8] == '.') {
- X char *p = filename+8;
- X while (*p++)
- X p[-1] = *p; /* disk label, and 8th char is dot: remove dot */
- X }
- X
- X if (!extra_len) /* we're done here */
- X break;
- X
- X /*
- X * We truncated the filename, so print what's left and then fall
- X * through to the SKIP routine.
- X */
- X FPRINTF(stderr, "[ %s ]\n", filename);
- X len = extra_len;
- X /* FALL THROUGH... */
- X
- X /*
- X * Third case: skip string, adjusting readbuf's internal variables
- X * as necessary (and possibly skipping to and reading a new block of
- X * data).
- X */
- X
- X case SKIP:
- X LSEEK(cur_zipfile_bufstart + (inptr-inbuf) + len)
- X break;
- X
- X /*
- X * Fourth case: assume we're at the start of an "extra field"; malloc
- X * storage for it and read data into the allocated space.
- X */
- X
- X case EXTRA_FIELD:
- X if (extra_field != (uch *)NULL)
- X free(extra_field);
- X if ((extra_field = (uch *)malloc(len)) == (uch *)NULL) {
- X FPRINTF(stderr, LoadFarString(ExtraFieldTooLong), len);
- X LSEEK(cur_zipfile_bufstart + (inptr-inbuf) + len)
- X } else
- X if (readbuf((char *)extra_field, len) == 0)
- X return PK_EOF;
- X break;
- X
- X } /* end switch (option) */
- X return error;
- X
- X} /* end function do_string() */
- X
- X
- X
- X
- X
- X/***********************/
- X/* Function makeword() */
- X/***********************/
- X
- Xush makeword(b)
- X uch *b;
- X{
- X /*
- X * Convert Intel style 'short' integer to non-Intel non-16-bit
- X * host format. This routine also takes care of byte-ordering.
- X */
- X return (ush)((b[1] << 8) | b[0]);
- X}
- X
- X
- X
- X
- X
- X/***********************/
- X/* Function makelong() */
- X/***********************/
- X
- Xulg makelong(sig)
- X uch *sig;
- X{
- X /*
- X * Convert intel style 'long' variable to non-Intel non-16-bit
- X * host format. This routine also takes care of byte-ordering.
- X */
- X return (((ulg)sig[3]) << 24)
- X + (((ulg)sig[2]) << 16)
- X + (((ulg)sig[1]) << 8)
- X + ((ulg)sig[0]);
- X}
- X
- X
- X
- X
- X
- X#ifdef ZMEM /* memset, memcpy for systems without them */
- X
- X/*********************/
- X/* Function memset() */
- X/*********************/
- X
- Xchar *memset(buf, init, len)
- X register char *buf, init; /* buffer loc and initializer */
- X register unsigned int len; /* length of the buffer */
- X{
- X char *start;
- X
- X start = buf;
- X while (len--)
- X *(buf++) = init;
- X return start;
- X}
- X
- X
- X
- X
- X
- X/*********************/
- X/* Function memcpy() */
- X/*********************/
- X
- Xchar *memcpy(dst, src, len)
- X register char *dst, *src;
- X register unsigned int len;
- X{
- X char *start;
- X
- X start = dst;
- X while (len-- > 0)
- X *dst++ = *src++;
- X return start;
- X}
- X
- X#endif /* ZMEM */
- X
- X
- X
- X
- X
- X/************************/
- X/* Function zstrnicmp() */
- X/************************/
- X
- Xint zstrnicmp(s1, s2, n)
- X register char *s1, *s2;
- X register int n;
- X{
- X for (; n > 0; --n, ++s1, ++s2) {
- X
- X if (ToLower(*s1) != ToLower(*s2))
- X /* test includes early termination of one string */
- X return (ToLower(*s1) < ToLower(*s2))? -1 : 1;
- X
- X if (*s1 == '\0') /* both strings terminate early */
- X return 0;
- X }
- X return 0;
- X}
- X
- X
- X
- X
- X
- X#ifdef REGULUS /* returns the inode number on success(!)...argh argh argh */
- X# undef stat
- X
- X/********************/
- X/* Function zstat() */
- X/********************/
- X
- Xint zstat(p, s)
- X char *p;
- X struct stat *s;
- X{
- X return (stat(p,s) >= 0? 0 : (-1));
- X}
- X
- X#endif /* REGULUS */
- X
- X
- X
- X
- X
- X#ifdef SMALL_MEM
- X
- Xchar rgchBigBuffer[512];
- Xchar rgchSmallBuffer[96];
- Xchar rgchSmallBuffer2[96];
- X
- X/******************************/
- X/* Function LoadFarString() */ /* (and friends...) */
- X/******************************/
- X
- Xchar *LoadFarString(char Far *sz)
- X{
- X (void)zfstrcpy(rgchBigBuffer, sz);
- X return rgchBigBuffer;
- X}
- X
- Xchar *LoadFarStringSmall(char Far *sz)
- X{
- X (void)zfstrcpy(rgchSmallBuffer, sz);
- X return rgchSmallBuffer;
- X}
- X
- Xchar *LoadFarStringSmall2(char Far *sz)
- X{
- X (void)zfstrcpy(rgchSmallBuffer2, sz);
- X return rgchSmallBuffer2;
- X}
- X
- X
- X/*************************/
- X/* Function zfstrcpy() */ /* portable clone of _fstrcpy() */
- X/*************************/
- X
- Xchar Far * Far zfstrcpy(char Far *s1, const char Far *s2)
- X{
- X char Far *p = s1;
- X
- X while ((*s1++ = *s2++) != '\0');
- X return p;
- X}
- X
- X#endif /* SMALL_MEM */
- END_OF_FILE
- if test 35360 -ne `wc -c <'unzip-5.12/file_io.c'`; then
- echo shar: \"'unzip-5.12/file_io.c'\" unpacked with wrong size!
- fi
- # end of 'unzip-5.12/file_io.c'
- fi
- if test -f 'unzip-5.12/tops20/make.mic' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'unzip-5.12/tops20/make.mic'\"
- else
- echo shar: Extracting \"'unzip-5.12/tops20/make.mic'\" \(369 characters\)
- sed "s/^X//" >'unzip-5.12/tops20/make.mic' <<'END_OF_FILE'
- X@te no pau e
- X@cc -c -q unzip
- X@cc -c -q crypt
- X@cc -c -q envarg
- X@cc -c -q explod
- X@cc -c -q extrac
- X@cc -c -q fileio
- X@cc -c -q inflat
- X@cc -c -q match
- X@cc -c -q unredu
- X@cc -c -q unshri
- X@cc -c -q zipinf
- X@cc -c -q tops20
- X@cc -o unzip unzip.rel crypt.rel envarg.rel explod.rel extrac.rel fileio.rel inflat.rel match.rel unredu.rel unshri.rel zipinf.rel tops20.rel -ltmx
- X@kmic
- END_OF_FILE
- if test 369 -ne `wc -c <'unzip-5.12/tops20/make.mic'`; then
- echo shar: \"'unzip-5.12/tops20/make.mic'\" unpacked with wrong size!
- fi
- # end of 'unzip-5.12/tops20/make.mic'
- fi
- if test -f 'unzip-5.12/unix/unix.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'unzip-5.12/unix/unix.c'\"
- else
- echo shar: Extracting \"'unzip-5.12/unix/unix.c'\" \(30753 characters\)
- sed "s/^X//" >'unzip-5.12/unix/unix.c' <<'END_OF_FILE'
- X/*---------------------------------------------------------------------------
- X
- X unix.c
- X
- X Unix-specific routines for use with Info-ZIP's UnZip 5.1 and later.
- X
- X Contains: readdir()
- X do_wild() <-- generic enough to put in file_io.c?
- X mapattr()
- X mapname()
- X checkdir()
- X mkdir()
- X close_outfile()
- X version()
- X
- X ---------------------------------------------------------------------------*/
- X
- X
- X#include "unzip.h"
- X
- X/* SCO Unix, AIX, DNIX, TI SysV, Coherent 4.x, ... */
- X#if defined(__convexc__) || defined(SYSV) || defined(CRAY) || defined(BSD4_4)
- X# define DIRENT
- X#endif
- X#if defined(_AIX)
- X# define DIRENT
- X#endif
- X#ifdef COHERENT
- X# if defined(_I386) || (defined(__COHERENT__) && (__COHERENT__ >= 0x420))
- X# define DIRENT
- X# endif
- X#endif
- X
- X/* GRR: may need to uncomment one or both of these for the relevant systems */
- X
- X#if 0
- X#if defined(_POSIX_VERSION)
- X# define DIRENT
- X#endif
- X#endif
- X
- X#if 0
- X#if defined(M_XENIX)
- X# define SYSNDIR
- X#endif
- X#endif
- X
- X#ifdef DIRENT
- X# include <dirent.h>
- X#else
- X# ifdef SYSV
- X# ifdef SYSNDIR
- X# include <sys/ndir.h>
- X# else
- X# include <ndir.h>
- X# endif
- X# else /* !SYSV */
- X# ifndef NO_SYSDIR
- X# include <sys/dir.h>
- X# endif
- X# endif /* ?SYSV */
- X# ifndef dirent
- X# define dirent direct
- X# endif
- X#endif /* ?DIRENT */
- X
- Xstatic int created_dir; /* used in mapname(), checkdir() */
- Xstatic int renamed_fullpath; /* ditto */
- X
- X
- X#ifndef SFX
- X#ifdef NO_DIR /* for AT&T 3B1 */
- X
- X#define opendir(path) fopen(path,"r")
- X#define closedir(dir) fclose(dir)
- Xtypedef FILE DIR;
- X
- X/*
- X * Apparently originally by Rich Salz.
- X * Cleaned up and modified by James W. Birdsall.
- X */
- Xstruct dirent *readdir(dirp)
- X DIR *dirp;
- X{
- X static struct dirent entry;
- X
- X if (dirp == NULL)
- X return NULL;
- X
- X for (;;)
- X if (fread(&entry, sizeof (struct dirent), 1, dirp) == 0)
- X return (struct dirent *)NULL;
- X else if (entry.d_ino)
- X return &entry;
- X
- X} /* end function readdir() */
- X
- X#endif /* NO_DIR */
- X
- X
- X/**********************/
- X/* Function do_wild() */ /* for porting: dir separator; match(ignore_case) */
- X/**********************/
- X
- Xchar *do_wild(wildspec)
- X char *wildspec; /* only used first time on a given dir */
- X{
- X static DIR *dir = (DIR *)NULL;
- X static char *dirname, *wildname, matchname[FILNAMSIZ];
- X static int firstcall=TRUE, have_dirname, dirnamelen;
- X struct dirent *file;
- X
- X
- X /* Even when we're just returning wildspec, we *always* do so in
- X * matchname[]--calling routine is allowed to append four characters
- X * to the returned string, and wildspec may be a pointer to argv[].
- X */
- X if (firstcall) { /* first call: must initialize everything */
- X firstcall = FALSE;
- X
- X /* break the wildspec into a directory part and a wildcard filename */
- X if ((wildname = strrchr(wildspec, '/')) == (char *)NULL) {
- X dirname = ".";
- X dirnamelen = 1;
- X have_dirname = FALSE;
- X wildname = wildspec;
- X } else {
- X ++wildname; /* point at character after '/' */
- X dirnamelen = wildname - wildspec;
- X if ((dirname = (char *)malloc(dirnamelen+1)) == (char *)NULL) {
- X FPRINTF(stderr, "warning: can't allocate wildcard buffers\n");
- X strcpy(matchname, wildspec);
- X return matchname; /* but maybe filespec was not a wildcard */
- X }
- X strncpy(dirname, wildspec, dirnamelen);
- X dirname[dirnamelen] = '\0'; /* terminate for strcpy below */
- X have_dirname = TRUE;
- X }
- X
- X if ((dir = opendir(dirname)) != (DIR *)NULL) {
- X while ((file = readdir(dir)) != (struct dirent *)NULL) {
- X if (file->d_name[0] == '.' && wildname[0] != '.')
- X continue; /* Unix: '*' and '?' do not match leading dot */
- X if (match(file->d_name, wildname, 0)) { /* 0 == case sens. */
- X if (have_dirname) {
- X strcpy(matchname, dirname);
- X strcpy(matchname+dirnamelen, file->d_name);
- X } else
- X strcpy(matchname, file->d_name);
- X return matchname;
- X }
- X }
- X /* if we get to here directory is exhausted, so close it */
- X closedir(dir);
- X dir = (DIR *)NULL;
- X }
- X
- X /* return the raw wildspec in case that works (e.g., directory not
- X * searchable, but filespec was not wild and file is readable) */
- X strcpy(matchname, wildspec);
- X return matchname;
- X }
- X
- X /* last time through, might have failed opendir but returned raw wildspec */
- X if (dir == (DIR *)NULL) {
- X firstcall = TRUE; /* nothing left to try--reset for new wildspec */
- X if (have_dirname)
- X free(dirname);
- X return (char *)NULL;
- X }
- X
- X /* If we've gotten this far, we've read and matched at least one entry
- X * successfully (in a previous call), so dirname has been copied into
- X * matchname already.
- X */
- X while ((file = readdir(dir)) != (struct dirent *)NULL)
- X if (match(file->d_name, wildname, 0)) { /* 0 == don't ignore case */
- X if (have_dirname) {
- X /* strcpy(matchname, dirname); */
- X strcpy(matchname+dirnamelen, file->d_name);
- X } else
- X strcpy(matchname, file->d_name);
- X return matchname;
- X }
- X
- X closedir(dir); /* have read at least one dir entry; nothing left */
- X dir = (DIR *)NULL;
- X firstcall = TRUE; /* reset for new wildspec */
- X if (have_dirname)
- X free(dirname);
- X return (char *)NULL;
- X
- X} /* end function do_wild() */
- X
- X#endif /* !SFX */
- X
- X
- X
- X
- X
- X/**********************/
- X/* Function mapattr() */
- X/**********************/
- X
- Xint mapattr()
- X{
- X ulg tmp = crec.external_file_attributes;
- X
- X switch (pInfo->hostnum) {
- X case UNIX_:
- X case VMS_:
- X pInfo->file_attr = (unsigned)(tmp >> 16);
- X return 0;
- X case AMIGA_:
- X tmp = (unsigned)(tmp>>17 & 7); /* Amiga RWE bits */
- X pInfo->file_attr = (unsigned)(tmp<<6 | tmp<<3 | tmp);
- X break;
- X /* all remaining cases: expand MSDOS read-only bit into write perms */
- X case FS_FAT_:
- X case FS_HPFS_:
- X case FS_NTFS_:
- X case MAC_:
- X case ATARI_: /* (used to set = 0666) */
- X case TOPS20_:
- X default:
- X tmp = !(tmp & 1) << 1; /* read-only bit --> write perms bits */
- X pInfo->file_attr = (unsigned)(0444 | tmp<<6 | tmp<<3 | tmp);
- X break;
- X } /* end switch (host-OS-created-by) */
- X
- X /* for originating systems with no concept of "group," "other," "system": */
- X umask( (int)(tmp=umask(0)) ); /* apply mask to expanded r/w(/x) perms */
- X pInfo->file_attr &= ~tmp;
- X
- X return 0;
- X
- X} /* end function mapattr() */
- X
- X
- X
- X
- X
- X/************************/
- X/* Function mapname() */
- X/************************/
- X
- Xint mapname(renamed) /* return 0 if no error, 1 if caution (filename trunc), */
- X int renamed; /* 2 if warning (skip file because dir doesn't exist), */
- X{ /* 3 if error (skip file), 10 if no memory (skip file) */
- X char pathcomp[FILNAMSIZ]; /* path-component buffer */
- X char *pp, *cp=(char *)NULL; /* character pointers */
- X char *lastsemi=(char *)NULL; /* pointer to last semi-colon in pathcomp */
- X int quote = FALSE; /* flags */
- X int error = 0;
- X register unsigned workch; /* hold the character being tested */
- X
- X
- X/*---------------------------------------------------------------------------
- X Initialize various pointers and counters and stuff.
- X ---------------------------------------------------------------------------*/
- X
- X if (pInfo->vollabel)
- X return IZ_VOL_LABEL; /* can't set disk volume labels in Unix */
- X
- X /* can create path as long as not just freshening, or if user told us */
- X create_dirs = (!fflag || renamed);
- X
- X created_dir = FALSE; /* not yet */
- X
- X /* user gave full pathname: don't prepend rootpath */
- X renamed_fullpath = (renamed && (*filename == '/'));
- X
- X if (checkdir((char *)NULL, INIT) == 10)
- X return 10; /* initialize path buffer, unless no memory */
- X
- X *pathcomp = '\0'; /* initialize translation buffer */
- X pp = pathcomp; /* point to translation buffer */
- X if (jflag) /* junking directories */
- X cp = (char *)strrchr(filename, '/');
- X if (cp == (char *)NULL) /* no '/' or not junking dirs */
- X cp = filename; /* point to internal zipfile-member pathname */
- X else
- X ++cp; /* point to start of last component of path */
- X
- X/*---------------------------------------------------------------------------
- X Begin main loop through characters in filename.
- X ---------------------------------------------------------------------------*/
- X
- X while ((workch = (uch)*cp++) != 0) {
- X
- X if (quote) { /* if character quoted, */
- X *pp++ = (char)workch; /* include it literally */
- X quote = FALSE;
- X } else
- X switch (workch) {
- X case '/': /* can assume -j flag not given */
- X *pp = '\0';
- X if ((error = checkdir(pathcomp, APPEND_DIR)) > 1)
- X return error;
- X pp = pathcomp; /* reset conversion buffer for next piece */
- X lastsemi = (char *)NULL; /* leave directory semi-colons alone */
- X break;
- X
- X case ';': /* VMS version (or DEC-20 attrib?) */
- X lastsemi = pp;
- X *pp++ = ';'; /* keep for now; remove VMS ";##" */
- X break; /* later, if requested */
- X
- X case '\026': /* control-V quote for special chars */
- X quote = TRUE; /* set flag for next character */
- X break;
- X
- X#ifdef MTS
- X case ' ': /* change spaces to underscore under */
- X *pp++ = '_'; /* MTS; leave as spaces under Unix */
- X break;
- X#endif
- X
- X default:
- X /* allow European characters in filenames: */
- X if (isprint(workch) || (128 <= workch && workch <= 254))
- X *pp++ = (char)workch;
- X } /* end switch */
- X
- X } /* end while loop */
- X
- X *pp = '\0'; /* done with pathcomp: terminate it */
- X
- X /* if not saving them, remove VMS version numbers (appended ";###") */
- X if (!V_flag && lastsemi) {
- X pp = lastsemi + 1;
- X while (isdigit((uch)(*pp)))
- X ++pp;
- X if (*pp == '\0') /* only digits between ';' and end: nuke */
- X *lastsemi = '\0';
- X }
- X
- X/*---------------------------------------------------------------------------
- X Report if directory was created (and no file to create: filename ended
- X in '/'), check name to be sure it exists, and combine path and name be-
- X fore exiting.
- X ---------------------------------------------------------------------------*/
- X
- X if (filename[strlen(filename) - 1] == '/') {
- X checkdir(filename, GETPATH);
- X if (created_dir && QCOND2) {
- X FPRINTF(stdout, " creating: %s\n", filename);
- X return IZ_CREATED_DIR; /* set dir time (note trailing '/') */
- X }
- X return 2; /* dir existed already; don't look for data to extract */
- X }
- X
- X if (*pathcomp == '\0') {
- X FPRINTF(stderr, "mapname: conversion of %s failed\n", filename);
- X return 3;
- X }
- X
- X checkdir(pathcomp, APPEND_NAME); /* returns 1 if truncated: care? */
- X checkdir(filename, GETPATH);
- X
- X return error;
- X
- X} /* end function mapname() */
- X
- X
- X
- X
- X#if 0 /*========== NOTES ==========*/
- X
- X extract-to dir: a:path/
- X buildpath: path1/path2/ ... (NULL-terminated)
- X pathcomp: filename
- X
- X mapname():
- X loop over chars in zipfile member name
- X checkdir(path component, COMPONENT | CREATEDIR) --> map as required?
- X (d:/tmp/unzip/) (disk:[tmp.unzip.)
- X (d:/tmp/unzip/jj/) (disk:[tmp.unzip.jj.)
- X (d:/tmp/unzip/jj/temp/) (disk:[tmp.unzip.jj.temp.)
- X finally add filename itself and check for existence? (could use with rename)
- X (d:/tmp/unzip/jj/temp/msg.outdir) (disk:[tmp.unzip.jj.temp]msg.outdir)
- X checkdir(name, COPYFREE) --> copy path to name and free space
- X
- X#endif /* 0 */
- X
- X
- X
- X
- X/***********************/
- X/* Function checkdir() */
- X/***********************/
- X
- Xint checkdir(pathcomp, flag)
- X char *pathcomp;
- X int flag;
- X/*
- X * returns: 1 - (on APPEND_NAME) truncated filename
- X * 2 - path doesn't exist, not allowed to create
- X * 3 - path doesn't exist, tried to create and failed; or
- X * path exists and is not a directory, but is supposed to be
- X * 4 - path is too long
- X * 10 - can't allocate memory for filename buffers
- X */
- X{
- X static int rootlen = 0; /* length of rootpath */
- X static char *rootpath; /* user's "extract-to" directory */
- X static char *buildpath; /* full path (so far) to extracted file */
- X static char *end; /* pointer to end of buildpath ('\0') */
- X
- X# define FN_MASK 7
- X# define FUNCTION (flag & FN_MASK)
- X
- X
- X
- X/*---------------------------------------------------------------------------
- X APPEND_DIR: append the path component to the path being built and check
- X for its existence. If doesn't exist and we are creating directories, do
- X so for this one; else signal success or error as appropriate.
- X ---------------------------------------------------------------------------*/
- X
- X if (FUNCTION == APPEND_DIR) {
- X int too_long = FALSE;
- X#ifdef SHORT_NAMES
- X char *old_end = end;
- X#endif
- X
- X Trace((stderr, "appending dir segment [%s]\n", pathcomp));
- X while ((*end = *pathcomp++) != '\0')
- X ++end;
- X#ifdef SHORT_NAMES /* path components restricted to 14 chars, typically */
- X if ((end-old_end) > FILENAME_MAX) /* GRR: proper constant? */
- X *(end = old_end + FILENAME_MAX) = '\0';
- X#endif
- X
- X /* GRR: could do better check, see if overrunning buffer as we go:
- X * check end-buildpath after each append, set warning variable if
- X * within 20 of FILNAMSIZ; then if var set, do careful check when
- X * appending. Clear variable when begin new path. */
- X
- X if ((end-buildpath) > FILNAMSIZ-3) /* need '/', one-char name, '\0' */
- X too_long = TRUE; /* check if extracting directory? */
- X if (stat(buildpath, &statbuf)) { /* path doesn't exist */
- X if (!create_dirs) { /* told not to create (freshening) */
- X free(buildpath);
- X return 2; /* path doesn't exist: nothing to do */
- X }
- X if (too_long) {
- X FPRINTF(stderr, "checkdir error: path too long: %s\n",
- X buildpath);
- X fflush(stderr);
- X free(buildpath);
- X return 4; /* no room for filenames: fatal */
- X }
- X if (mkdir(buildpath, 0777) == -1) { /* create the directory */
- X FPRINTF(stderr, "checkdir error: can't create %s\n\
- X unable to process %s.\n", buildpath, filename);
- X fflush(stderr);
- X free(buildpath);
- X return 3; /* path didn't exist, tried to create, failed */
- X }
- X created_dir = TRUE;
- X } else if (!S_ISDIR(statbuf.st_mode)) {
- X FPRINTF(stderr, "checkdir error: %s exists but is not directory\n\
- X unable to process %s.\n", buildpath, filename);
- X fflush(stderr);
- X free(buildpath);
- X return 3; /* path existed but wasn't dir */
- X }
- X if (too_long) {
- X FPRINTF(stderr, "checkdir error: path too long: %s\n", buildpath);
- X fflush(stderr);
- X free(buildpath);
- X return 4; /* no room for filenames: fatal */
- X }
- X *end++ = '/';
- X *end = '\0';
- X Trace((stderr, "buildpath now = [%s]\n", buildpath));
- X return 0;
- X
- X } /* end if (FUNCTION == APPEND_DIR) */
- X
- X/*---------------------------------------------------------------------------
- X GETPATH: copy full path to the string pointed at by pathcomp, and free
- X buildpath.
- X ---------------------------------------------------------------------------*/
- X
- X if (FUNCTION == GETPATH) {
- X strcpy(pathcomp, buildpath);
- X Trace((stderr, "getting and freeing path [%s]\n", pathcomp));
- X free(buildpath);
- X buildpath = end = (char *)NULL;
- X return 0;
- X }
- X
- X/*---------------------------------------------------------------------------
- X APPEND_NAME: assume the path component is the filename; append it and
- X return without checking for existence.
- X ---------------------------------------------------------------------------*/
- X
- X if (FUNCTION == APPEND_NAME) {
- X#ifdef SHORT_NAMES
- X char *old_end = end;
- X#endif
- X
- X Trace((stderr, "appending filename [%s]\n", pathcomp));
- X while ((*end = *pathcomp++) != '\0') {
- X ++end;
- X#ifdef SHORT_NAMES /* truncate name at 14 characters, typically */
- X if ((end-old_end) > FILENAME_MAX) /* GRR: proper constant? */
- X *(end = old_end + FILENAME_MAX) = '\0';
- X#endif
- X if ((end-buildpath) >= FILNAMSIZ) {
- X *--end = '\0';
- X FPRINTF(stderr, "checkdir warning: path too long; truncating\n\
- Xcheckdir warning: path too long; truncating\n\
- X %s\n -> %s\n", filename, buildpath);
- X fflush(stderr);
- X return 1; /* filename truncated */
- X }
- X }
- X Trace((stderr, "buildpath now = [%s]\n", buildpath));
- X return 0; /* could check for existence here, prompt for new name... */
- X }
- X
- X/*---------------------------------------------------------------------------
- X INIT: allocate and initialize buffer space for the file currently being
- X extracted. If file was renamed with an absolute path, don't prepend the
- X extract-to path.
- X ---------------------------------------------------------------------------*/
- X
- X/* GRR: for VMS and TOPS-20, add up to 13 to strlen */
- X
- X if (FUNCTION == INIT) {
- X Trace((stderr, "initializing buildpath to "));
- X if ((buildpath = (char *)malloc(strlen(filename)+rootlen+1)) ==
- X (char *)NULL)
- X return 10;
- X if ((rootlen > 0) && !renamed_fullpath) {
- X strcpy(buildpath, rootpath);
- X end = buildpath + rootlen;
- X } else {
- X *buildpath = '\0';
- X end = buildpath;
- X }
- X Trace((stderr, "[%s]\n", buildpath));
- X return 0;
- X }
- X
- X/*---------------------------------------------------------------------------
- X ROOT: if appropriate, store the path in rootpath and create it if neces-
- X sary; else assume it's a zipfile member and return. This path segment
- X gets used in extracting all members from every zipfile specified on the
- X command line.
- X ---------------------------------------------------------------------------*/
- X
- X#if (!defined(SFX) || defined(SFX_EXDIR))
- X if (FUNCTION == ROOT) {
- X Trace((stderr, "initializing root path to [%s]\n", pathcomp));
- X if (pathcomp == (char *)NULL) {
- X rootlen = 0;
- X return 0;
- X }
- X if ((rootlen = strlen(pathcomp)) > 0) {
- X int had_trailing_pathsep=FALSE;
- X
- X if (pathcomp[rootlen-1] == '/') {
- X pathcomp[--rootlen] = '\0';
- X had_trailing_pathsep = TRUE;
- X }
- X if (rootlen > 0 && (stat(pathcomp, &statbuf) ||
- X !S_ISDIR(statbuf.st_mode))) /* path does not exist */
- X {
- X if (!create_dirs /* || iswild(pathcomp) */
- X#ifdef OLD_EXDIR
- X || !had_trailing_pathsep
- X#endif
- X ) {
- X rootlen = 0;
- X return 2; /* skip (or treat as stored file) */
- X }
- X /* create the directory (could add loop here to scan pathcomp
- X * and create more than one level, but why really necessary?) */
- X if (mkdir(pathcomp, 0777) == -1) {
- X FPRINTF(stderr,
- X "checkdir: can't create extraction directory: %s\n",
- X pathcomp);
- X fflush(stderr);
- X rootlen = 0; /* path didn't exist, tried to create, and */
- X return 3; /* failed: file exists, or 2+ levels required */
- X }
- X }
- X if ((rootpath = (char *)malloc(rootlen+2)) == (char *)NULL) {
- X rootlen = 0;
- X return 10;
- X }
- X strcpy(rootpath, pathcomp);
- X rootpath[rootlen++] = '/';
- X rootpath[rootlen] = '\0';
- X }
- X Trace((stderr, "rootpath now = [%s]\n", rootpath));
- X return 0;
- X }
- X#endif /* !SFX || SFX_EXDIR */
- X
- X/*---------------------------------------------------------------------------
- X END: free rootpath, immediately prior to program exit.
- X ---------------------------------------------------------------------------*/
- X
- X if (FUNCTION == END) {
- X Trace((stderr, "freeing rootpath\n"));
- X if (rootlen > 0)
- X free(rootpath);
- X return 0;
- X }
- X
- X return 99; /* should never reach */
- X
- X} /* end function checkdir() */
- X
- X
- X
- X
- X
- X#ifdef NO_MKDIR
- X
- X/********************/
- X/* Function mkdir() */
- X/********************/
- X
- Xint mkdir(path, mode)
- X char *path;
- X int mode; /* ignored */
- X/*
- X * returns: 0 - successful
- X * -1 - failed (errno not set, however)
- X */
- X{
- X char command[FILNAMSIZ+40]; /* buffer for system() call */
- X
- X /* GRR 930416: added single quotes around path to avoid bug with
- X * creating directories with ampersands in name; not yet tested */
- X sprintf(command, "IFS=\" \t\n\" /bin/mkdir '%s' 2>/dev/null", path);
- X if (system(command))
- X return -1;
- X return 0;
- X}
- X
- X#endif /* NO_MKDIR */
- X
- X
- X
- X
- X
- X#ifndef MTS
- X
- X/****************************/
- X/* Function close_outfile() */
- X/****************************/
- X
- Xvoid close_outfile()
- X{
- X static short yday[]={0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
- X time_t m_time;
- X int yr, mo, dy, hh, mm, ss, leap, days;
- X struct utimbuf tp;
- X# define YRBASE 1970
- X#ifndef BSD4_4
- X#ifdef BSD
- X static struct timeb tbp;
- X#else /* !BSD */
- X extern long timezone;
- X#endif /* ?BSD */
- X#endif /* !BSD4_4 */
- X
- X
- X/*---------------------------------------------------------------------------
- X If symbolic links are supported, allocate a storage area, put the uncom-
- X pressed "data" in it, and create the link. Since we know it's a symbolic
- X link to start with, we shouldn't have to worry about overflowing unsigned
- X ints with unsigned longs.
- X ---------------------------------------------------------------------------*/
- X
- X#ifdef SYMLINKS
- X if (symlnk) {
- X unsigned ucsize = (unsigned)lrec.ucsize;
- X char *linktarget = (char *)malloc((unsigned)lrec.ucsize+1);
- X
- X fclose(outfile); /* close "data" file... */
- X outfile = fopen(filename, FOPR); /* ...and reopen for reading */
- X if (!linktarget || (fread(linktarget, 1, ucsize, outfile) != ucsize)) {
- X FPRINTF(stderr, "\nwarning: symbolic link (%s) failed\n",
- X filename);
- X if (linktarget)
- X free(linktarget);
- X fclose(outfile);
- X return;
- X }
- X fclose(outfile); /* close "data" file for good... */
- X unlink(filename); /* ...and delete it */
- X linktarget[ucsize] = '\0';
- X FPRINTF(stdout, "-> %s ", linktarget);
- X if (symlink(linktarget, filename)) /* create the real link */
- X perror("symlink error");
- X free(linktarget);
- X return; /* can't set time on symlinks */
- X }
- X#endif /* SYMLINKS */
- X
- X fclose(outfile);
- X
- X/*---------------------------------------------------------------------------
- X Change the file permissions from default ones to those stored in the
- X zipfile.
- X ---------------------------------------------------------------------------*/
- X
- X#ifndef NO_CHMOD
- X if (chmod(filename, 0xffff & pInfo->file_attr))
- X perror("chmod (file attributes) error");
- X#endif
- X
- X/*---------------------------------------------------------------------------
- X Convert from MSDOS-format local time and date to Unix-format 32-bit GMT
- X time: adjust base year from 1980 to 1970, do usual conversions from
- X yy/mm/dd hh:mm:ss to elapsed seconds, and account for timezone and day-
- X light savings time differences.
- X ---------------------------------------------------------------------------*/
- X
- X yr = ((lrec.last_mod_file_date >> 9) & 0x7f) + (1980 - YRBASE);
- X mo = ((lrec.last_mod_file_date >> 5) & 0x0f) - 1;
- X dy = (lrec.last_mod_file_date & 0x1f) - 1;
- X hh = (lrec.last_mod_file_time >> 11) & 0x1f;
- X mm = (lrec.last_mod_file_time >> 5) & 0x3f;
- X ss = (lrec.last_mod_file_time & 0x1f) * 2;
- X
- X /* leap = # of leap yrs from YRBASE up to but not including current year */
- X leap = ((yr + YRBASE - 1) / 4); /* leap year base factor */
- X
- X /* how many days from YRBASE to this year? (& add expired days this year) */
- X days = (yr * 365) + (leap - 492) + yday[mo];
- X
- X /* if year is a leap year and month is after February, add another day */
- X if ((mo > 1) && ((yr+YRBASE)%4 == 0) && ((yr+YRBASE) != 2100))
- X ++days; /* OK through 2199 */
- X
- X /* convert date & time to seconds relative to 00:00:00, 01/01/YRBASE */
- X m_time = ((days + dy) * 86400) + (hh * 3600) + (mm * 60) + ss;
- X
- X /* adjust for local timezone */
- X#ifdef BSD
- X#ifdef BSD4_4
- X m_time -= localtime(&m_time)->tm_gmtoff; /* seconds EAST of GMT: subtr. */
- X#else
- X ftime(&tbp); /* get `timezone' */
- X m_time += tbp.timezone * 60L; /* seconds WEST of GMT: add */
- X#endif /* ?BSD4_4 */
- X#else /* !BSD */
- X tzset(); /* get `timezone' */
- X m_time += timezone; /* seconds WEST of GMT: add */
- X#endif /* ?BSD */
- X
- X /* adjust for daylight savings time (or local equivalent) */
- X#ifndef BSD4_4 /* (DST already added to tm_gmtoff, so skip tm_isdst) */
- X if (localtime(&m_time)->tm_isdst)
- X m_time -= 60L * 60L; /* adjust for daylight savings time */
- X#endif
- X
- X /* set the file's access and modification times */
- X tp.actime = tp.modtime = m_time;
- X if (utime(filename, &tp)) {
- X#ifdef AOS_VS
- X FPRINTF(stderr, "... can't set time for %s", filename);
- X#else
- X FPRINTF(stderr, "warning: can't set the time for %s\n", filename);
- X#endif
- X FFLUSH(stderr);
- X }
- X
- X} /* end function close_outfile() */
- X
- X#endif /* !MTS */
- X
- X
- X
- X
- X#ifndef SFX
- X
- X/************************/
- X/* Function version() */
- X/************************/
- X
- Xvoid version()
- X{
- X extern char Far CompiledWith[];
- X#if defined(CRAY) || defined(NetBSD)
- X char buf1[40];
- X#if defined(CRAY)
- X char buf2[40];
- X#endif
- X#endif
- X
- X PRINTF(LoadFarString(CompiledWith),
- X
- X#ifdef __GNUC__
- X "gcc ", __VERSION__,
- X#else
- X# if defined(CRAY) && defined(_RELEASE)
- X "cc ", (sprintf(buf1, "version %d", _RELEASE), buf1),
- X# else
- X# ifdef __VERSION__
- X "cc ", __VERSION__,
- X# else
- X "cc", "",
- X# endif
- X# endif
- X#endif
- X
- X "Unix",
- X
- X#if defined(sgi) || defined(__sgi)
- X " (Silicon Graphics IRIX)",
- X#else
- X#ifdef sun
- X# ifdef sparc
- X# ifdef __SVR4
- X " (Sun Sparc/Solaris)",
- X# else /* may or may not be SunOS */
- X " (Sun Sparc)",
- X# endif
- X# else
- X# if defined(sun386) || defined(i386)
- X " (Sun 386i)",
- X# else
- X# if defined(mc68020) || defined(__mc68020__)
- X " (Sun 3)",
- X# else /* mc68010 or mc68000: Sun 2 or earlier */
- X " (Sun 2)",
- X# endif
- X# endif
- X# endif
- X#else
- X#ifdef __hpux
- X " (HP/UX)",
- X#else
- X#ifdef __osf__
- X " (DEC OSF/1)",
- X#else
- X#ifdef _AIX
- X " (IBM AIX)",
- X#else
- X#ifdef aiws
- X " (IBM RT/AIX)",
- X#else
- X#if defined(CRAY) || defined(cray)
- X# ifdef _UNICOS
- X (sprintf(buf2, " (Cray UNICOS release %d)", _UNICOS), buf2),
- X# else
- X " (Cray UNICOS)",
- X# endif
- X#else
- X#if defined(uts) || defined(UTS)
- X " (Amdahl UTS)",
- X#else
- X#ifdef NeXT
- X# ifdef mc68000
- X " (NeXTStep/black)",
- X# else
- X " (NeXTStep for Intel)",
- X# endif
- X#else /* the next dozen or so are somewhat order-dependent */
- X#ifdef LINUX
- X " (Linux)",
- X#else
- X#ifdef MINIX
- X " (Minix)",
- X#else
- X#ifdef M_UNIX
- X " (SCO Unix)",
- X#else
- X#ifdef M_XENIX
- X " (SCO Xenix)",
- X#else
- X#ifdef __NetBSD__
- X# ifdef NetBSD0_8
- X (sprintf(buf1, " (NetBSD 0.8%c)", (char)(NetBSD0_8 - 1 + 'A')), buf1),
- X# else
- X# ifdef NetBSD0_9
- X (sprintf(buf1, " (NetBSD 0.9%c)", (char)(NetBSD0_9 - 1 + 'A')), buf1),
- X# else
- X# ifdef NetBSD1_0
- X (sprintf(buf1, " (NetBSD 1.0%c)", (char)(NetBSD1_0 - 1 + 'A')), buf1),
- X# else
- X (BSD4_4 == 0.5)? " (NetBSD before 0.9)" : " (NetBSD 1.1 or later)",
- X# endif
- X# endif
- X# endif
- X#else
- X#ifdef __FreeBSD__
- X (BSD4_4 == 0.5)? " (FreeBSD 1.x)" : " (FreeBSD 2.0 or later)",
- X#else
- X#ifdef __bsdi__
- X (BSD4_4 == 0.5)? " (BSD/386 1.0)" : " (BSD/386 1.1 or later)",
- X#else
- X#ifdef __386BSD__
- X (BSD4_4 == 1)? " (386BSD, post-4.4 release)" : " (386BSD)",
- X#else
- X#if defined(i486) || defined(__i486) || defined(__i486__)
- X " (Intel 486)",
- X#else
- X#if defined(i386) || defined(__i386) || defined(__i386__)
- X " (Intel 386)",
- X#else
- X#ifdef pyr
- X " (Pyramid)",
- X#else
- X#ifdef ultrix
- X# ifdef mips
- X " (DEC/MIPS)",
- X# else
- X# ifdef vax
- X " (DEC/VAX)",
- X# else /* __alpha? */
- X " (DEC/Alpha)",
- X# endif
- X# endif
- X#else
- X#ifdef gould
- X " (Gould)",
- X#else
- X#ifdef MTS
- X " (MTS)",
- X#else
- X#ifdef __convexc__
- X " (Convex)",
- X#else
- X "",
- X#endif /* Convex */
- X#endif /* MTS */
- X#endif /* Gould */
- X#endif /* DEC */
- X#endif /* Pyramid */
- X#endif /* 386 */
- X#endif /* 486 */
- X#endif /* 386BSD */
- X#endif /* BSDI BSD/386 */
- X#endif /* NetBSD */
- X#endif /* FreeBSD */
- X#endif /* SCO Xenix */
- X#endif /* SCO Unix */
- X#endif /* Minix */
- X#endif /* Linux */
- X#endif /* NeXT */
- X#endif /* Amdahl */
- X#endif /* Cray */
- X#endif /* RT/AIX */
- X#endif /* AIX */
- X#endif /* OSF/1 */
- X#endif /* HP/UX */
- X#endif /* Sun */
- X#endif /* SGI */
- X
- X#ifdef __DATE__
- X " on ", __DATE__
- X#else
- X "", ""
- X#endif
- X );
- X
- X} /* end function version() */
- X
- X#endif /* !SFX */
- END_OF_FILE
- if test 30753 -ne `wc -c <'unzip-5.12/unix/unix.c'`; then
- echo shar: \"'unzip-5.12/unix/unix.c'\" unpacked with wrong size!
- fi
- # end of 'unzip-5.12/unix/unix.c'
- fi
- echo shar: End of archive 10 \(of 20\).
- cp /dev/null ark10isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 20 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still must unpack the following archives:
- echo " " ${MISSING}
- fi
- exit 0
- exit 0 # Just in case...
-