Annotation of coherent/b/bin/unzip/file_io.c, revision 1.1.1.1

1.1       root        1: /*---------------------------------------------------------------------------
                      2: 
                      3:   file_io.c
                      4: 
                      5:   This file contains routines for doing direct input/output, file-related
                      6:   sorts of things.  Most of the system-specific code for unzip is contained
                      7:   here, including the non-echoing password code for decryption (bottom).
                      8: 
                      9:   ---------------------------------------------------------------------------*/
                     10: 
                     11: 
                     12: #if (!defined(__GO32__) && !defined(NeXT))
                     13: #  define const
                     14: #endif
                     15: 
                     16: #define FILE_IO_C
                     17: #include "unzip.h"
                     18: 
                     19: #ifdef  MSWIN
                     20: #  include "wizunzip.h"
                     21: #endif
                     22: 
                     23: 
                     24: /************************************/
                     25: /*  File_IO Local Prototypes, etc.  */
                     26: /************************************/
                     27: 
                     28: #if (!defined(DOS_OS2) || defined(MSWIN))
                     29:    static int dos2unix __((unsigned char *buf, int len));
                     30:    int CR_flag = 0;      /* when last char of buffer == CR (for dos2unix()) */
                     31: #endif
                     32: 
                     33: #ifdef OS2
                     34:    extern int   longname;          /* set in mapname.c */
                     35:    extern char  longfilename[];
                     36: #endif
                     37: 
                     38: #ifdef CRYPT
                     39: #  if (defined(DOS_OS2) || defined(VMS))
                     40: #    define MSVMS
                     41: #    ifdef DOS_OS2
                     42: #      ifdef __EMX__
                     43: #        define getch() _read_kbd(0, 1, 0)
                     44: #      else
                     45: #        ifdef __GO32__
                     46: #          include <pc.h>
                     47: #          define getch() getkey()
                     48: #        else /* !__GO32__ */
                     49: #          include <conio.h>
                     50: #        endif /* ?__GO32__ */
                     51: #      endif
                     52: #    else /* !DOS_OS2 */
                     53: #      define getch() getc(stderr)
                     54: #      define OFF 0   /* for echo control */
                     55: #      define ON 1
                     56: #      define echoff(f) echo(OFF)
                     57: #      define echon()   echo(ON)
                     58: #      include <descrip.h>
                     59: #      include <iodef.h>
                     60: #      include <ttdef.h>
                     61: #      if !defined(SS$_NORMAL)
                     62: #        define SS$_NORMAL 1   /* only thing we need from <ssdef.h> */
                     63: #      endif
                     64: #    endif /* ?DOS_OS2 */
                     65: #  else /* !(DOS_OS2 || VMS) */
                     66: #    ifdef TERMIO       /* Amdahl, Cray, all SysV? */
                     67: #      ifdef CONVEX
                     68: #        include <sys/termios.h>
                     69: #        include <sgtty.h>
                     70: #      else /* !CONVEX */
                     71: #        ifdef LINUX
                     72: #          include <termios.h>
                     73: #        else /* !LINUX */
                     74: #          include <termio.h>
                     75: #        endif /* ?LINUX */
                     76: #        define sgttyb termio
                     77: #        define sg_flags c_lflag
                     78: #      endif /* ?CONVEX */
                     79:        int ioctl OF((int, int, voidp *));
                     80: #      define GTTY(f,s) ioctl(f,TCGETA,(voidp *)s)
                     81: #      define STTY(f,s) ioctl(f,TCSETAW,(voidp *)s)
                     82: #    else /* !TERMIO */
                     83: #      if (!defined(MINIX) && !defined(__386BSD__))
                     84: #        include <sys/ioctl.h>
                     85: #      endif /* !MINIX && !__386BSD__ */
                     86: #      include <sgtty.h>
                     87: #      ifdef __386BSD__
                     88: #        define GTTY(f, s) ioctl(f, TIOCGETP, (voidp *) s)
                     89: #        define STTY(f, s) ioctl(f, TIOCSETP, (voidp *) s)
                     90: #      else /* !__386BSD__ */
                     91: #        define GTTY gtty
                     92: #        define STTY stty
                     93:          int gtty OF((int, struct sgttyb *));
                     94:          int stty OF((int, struct sgttyb *));
                     95: #      endif /* ?__386BSD__ */
                     96: #    endif /* ?TERMIO */
                     97:      int isatty OF((int));
                     98:      char *ttyname OF((int));
                     99: #    if (defined(PROTO) && !defined(__GNUC__) && !defined(_AIX))
                    100:        int open (char *, int, ...);
                    101: #    endif
                    102:      int close OF((int));
                    103:      int read OF((int, voidp *, int));
                    104: #  endif /* ?(DOS_OS2 || VMS) */
                    105: #endif /* CRYPT */
                    106: 
                    107: 
                    108: 
                    109: 
                    110: 
                    111: /******************************/
                    112: /* Function open_input_file() */
                    113: /******************************/
                    114: 
                    115: int open_input_file()    /* return non-zero if open failed */
                    116: {
                    117:     /*
                    118:      *  open the zipfile for reading and in BINARY mode to prevent cr/lf
                    119:      *  translation, which would corrupt the bitstreams
                    120:      */
                    121: 
                    122: #ifdef VMS
                    123:     zipfd = open(zipfn, O_RDONLY, 0, "ctx=stm");
                    124: #else /* !VMS */
                    125: #ifdef UNIX
                    126:     zipfd = open(zipfn, O_RDONLY);
                    127: #else /* !UNIX */
                    128: #ifdef MACOS
                    129:     zipfd = open(zipfn, 0);
                    130: #else /* !MACOS */
                    131:     zipfd = open(zipfn, O_RDONLY | O_BINARY);
                    132: #endif /* ?MACOS */
                    133: #endif /* ?UNIX */
                    134: #endif /* ?VMS */
                    135:     if (zipfd < 1) {
                    136:         fprintf(stderr, "error:  can't open zipfile [ %s ]\n", zipfn);
                    137:         return (1);
                    138:     }
                    139:     return 0;
                    140: }
                    141: 
                    142: 
                    143: 
                    144: 
                    145: 
                    146: /**********************/
                    147: /* Function readbuf() */
                    148: /**********************/
                    149: 
                    150: int readbuf(buf, size)
                    151:     char *buf;
                    152:     register unsigned size;
                    153: {                               /* return number of bytes read into buf */
                    154:     register int count;
                    155:     int n;
                    156: 
                    157:     n = size;
                    158:     while (size) {
                    159:         if (incnt == 0) {
                    160:             if ((incnt = read(zipfd, (char *)inbuf, INBUFSIZ)) <= 0)
                    161:                 return (n-size);
                    162:             /* buffer ALWAYS starts on a block boundary:  */
                    163:             cur_zipfile_bufstart += INBUFSIZ;
                    164:             inptr = inbuf;
                    165:         }
                    166:         count = MIN(size, (unsigned)incnt);
                    167:         memcpy(buf, inptr, count);
                    168:         buf += count;
                    169:         inptr += count;
                    170:         incnt -= count;
                    171:         size -= count;
                    172:     }
                    173:     return (n);
                    174: }
                    175: 
                    176: 
                    177: 
                    178: 
                    179: 
                    180: #ifndef VMS   /* for VMS use code in vms.c (old VMS code below is retained
                    181:                * in case of problems...will be removed in a later release) */
                    182: 
                    183: /*********************************/
                    184: /* Function create_output_file() */
                    185: /*********************************/
                    186: 
                    187: int create_output_file()         /* return non-0 if creat failed */
                    188: {
                    189: /*---------------------------------------------------------------------------
                    190:     Create the output file with appropriate permissions.  If we've gotten to
                    191:     this point and the file still exists, we have permission to blow it away.
                    192:   ---------------------------------------------------------------------------*/
                    193: 
                    194: #if (!defined(DOS_OS2) || defined(MSWIN))
                    195:     CR_flag = 0;   /* hack to get CR at end of buffer working */
                    196: #endif
                    197: 
                    198: #if (defined(UNIX) && !defined(AMIGA))
                    199:     {
                    200:         int mask;
                    201: 
                    202: #ifndef VMS
                    203:         if (!stat(filename, &statbuf) && (unlink(filename) < 0)) {
                    204:             fprintf(stderr, "\n%s:  cannot delete old copy\n", filename);
                    205:             return 1;
                    206:         }
                    207: #       define EXTRA_ARGS
                    208: #else /* VMS */
                    209: #       define EXTRA_ARGS   ,"rfm=stmlf","rat=cr"
                    210: #endif /* ?VMS */
                    211: 
                    212:         mask = umask(0);   /* now know that we own it */
                    213:         outfd = creat(filename, 0xffff & pInfo->unix_attr  EXTRA_ARGS);
                    214:         umask(mask);                                            /* VMS, Unix */
                    215:     }
                    216: #else /* !UNIX || AMIGA */  /* file permissions set after file closed */
                    217: #ifndef MACOS
                    218:     outfd = creat(filename, S_IWRITE | S_IREAD);     /* DOS, OS2, Mac, Amiga */
                    219: #else /* MACOS */
                    220:     {
                    221:         short fDataFork=TRUE;
                    222:         MACINFO mi;
                    223:         OSErr err;
                    224: 
                    225:         fMacZipped = FALSE;
                    226:         CtoPstr(filename);
                    227:         if (extra_field &&
                    228:             (lrec.extra_field_length > sizeof(MACINFOMIN)) &&
                    229:             (lrec.extra_field_length <= sizeof(MACINFO))) {
                    230:             BlockMove(extra_field, &mi, lrec.extra_field_length);
                    231:             if ((makeword((byte *)&mi.header) == 1992) &&
                    232:                 (makeword((byte *)&mi.data) ==
                    233:                   lrec.extra_field_length-sizeof(ZIP_EXTRA_HEADER)) &&
                    234:                 (mi.signature == 'JLEE')) {
                    235:                 gostCreator = mi.finfo.fdCreator;
                    236:                 gostType = mi.finfo.fdType;
                    237:                 fDataFork = (mi.flags & 1) ? TRUE : FALSE;
                    238:                 fMacZipped = true;
                    239:                 /* If it was Zipped w/Mac version, the filename has either */
                    240:                 /* a 'd' or 'r' appended.  Remove the d/r when unzipping */
                    241:                 filename[0]-=1;
                    242:             }
                    243:         }
                    244:         if (!fMacZipped) {
                    245:             if (!aflag)
                    246:                 gostType = gostCreator = '\?\?\?\?';
                    247:             else {
                    248: #ifdef THINK_C
                    249:                 gostCreator = 'KAHL';
                    250: #else
                    251: #ifdef MCH_MACINTOSH
                    252:                 gostCreator = 'Manx';
                    253: #else
                    254:                 gostCreator = 'MPS ';
                    255: #endif
                    256: #endif
                    257:                 gostType = 'TEXT';
                    258:             }
                    259:         }
                    260:         PtoCstr(filename);
                    261: 
                    262:         outfd = creat(filename, 0);
                    263:         if (fMacZipped) {
                    264:             CtoPstr(filename);
                    265:             if (hfsflag) {
                    266:                 HParamBlockRec   hpbr;
                    267:     
                    268:                 hpbr.fileParam.ioNamePtr = (StringPtr)filename;
                    269:                 hpbr.fileParam.ioVRefNum = gnVRefNum;
                    270:                 hpbr.fileParam.ioDirID = glDirID;
                    271:                 hpbr.fileParam.ioFlFndrInfo = mi.finfo;
                    272:                 hpbr.fileParam.ioFlCrDat = mi.lCrDat;
                    273:                 hpbr.fileParam.ioFlMdDat = mi.lMdDat;
                    274:                 err = PBHSetFInfo(&hpbr, 0);
                    275:             } else {
                    276:                 err = SetFInfo((StringPtr)filename , 0, &mi.finfo);
                    277:             }
                    278:             PtoCstr(filename);
                    279:         }
                    280:         if (outfd != -1)
                    281:             outfd = open(filename, (fDataFork)? 1 : 2);
                    282:     }
                    283: #endif /* ?MACOS */
                    284: #endif /* ?(UNIX && !AMIGA) */
                    285: 
                    286:     if (outfd < 1) {
                    287:         fprintf(stderr, "\n%s:  cannot create\n", filename);
                    288:         return 1;
                    289:     }
                    290: 
                    291: /*---------------------------------------------------------------------------
                    292:     If newly created file is in text mode and should be binary (to disable
                    293:     automatic CR/LF translations), either close it and reopen as binary or
                    294:     else change the mode to binary (DOS, OS/2).
                    295:   ---------------------------------------------------------------------------*/
                    296: 
                    297: #if (!defined(UNIX) && !defined(MACOS))
                    298:     if (!aflag) {
                    299: #ifdef DOS_OS2
                    300:         if (setmode(outfd, O_BINARY) == -1) {
                    301: #else /* !DOS_OS2 */
                    302:         close(outfd);
                    303:         if ((outfd = open(filename, O_RDWR | O_BINARY)) < 1) {
                    304: #endif /* ?DOS_OS2 */
                    305:             fprintf(stderr, "Can't make output file binary:  %s\n", filename);
                    306:             return 1;
                    307:         }
                    308:     }
                    309: #endif /* !UNIX && !MACOS */
                    310: 
                    311:     return 0;
                    312: }
                    313: 
                    314: #endif /* !VMS */
                    315: 
                    316: 
                    317: 
                    318: 
                    319: 
                    320: /****************************/
                    321: /* Function FillBitBuffer() */
                    322: /****************************/
                    323: 
                    324: int FillBitBuffer()
                    325: {
                    326:     /*
                    327:      * Fill bitbuf, which is 32 bits.  This function is only used by the
                    328:      * READBIT and PEEKBIT macros (which are used by all of the uncompression
                    329:      * routines).
                    330:      */
                    331:     UWORD temp;
                    332: 
                    333:     zipeof = 1;
                    334:     while (bits_left < 25 && ReadByte(&temp) == 8)
                    335:     {
                    336:       bitbuf |= (ULONG)temp << bits_left;
                    337:       bits_left += 8;
                    338:       zipeof = 0;
                    339:     }
                    340:     return 0;
                    341: }
                    342: 
                    343: 
                    344: 
                    345: 
                    346: 
                    347: /***********************/
                    348: /* Function ReadByte() */
                    349: /***********************/
                    350: 
                    351: int ReadByte(x)
                    352:     UWORD *x;
                    353: {
                    354:     /*
                    355:      * read a byte; return 8 if byte available, 0 if not
                    356:      */
                    357: 
                    358:     if (mem_mode)
                    359:         return ReadMemoryByte(x);
                    360: 
                    361:     if (csize-- <= 0)
                    362:         return 0;
                    363: 
                    364:     if (incnt == 0) {
                    365:         if ((incnt = read(zipfd, (char *)inbuf, INBUFSIZ)) <= 0)
                    366:             return 0;
                    367:         /* buffer ALWAYS starts on a block boundary:  */
                    368:         cur_zipfile_bufstart += INBUFSIZ;
                    369:         inptr = inbuf;
                    370: #ifdef CRYPT
                    371:         if (pInfo->encrypted) {
                    372:             byte *p;
                    373:             int n, t;
                    374: 
                    375:             for (n = (longint)incnt > csize + 1 ? (int)csize + 1 : incnt,
                    376:                  p = inptr; n--; p++)
                    377:                 *p = (byte) DECRYPT(*p);
                    378:         }
                    379: #endif /* CRYPT */
                    380:     }
                    381:     *x = *inptr++;
                    382:     --incnt;
                    383:     return 8;
                    384: }
                    385: 
                    386: 
                    387: 
                    388: 
                    389: 
                    390: #ifndef VMS   /* for VMS use code in vms.c */
                    391: 
                    392: /**************************/
                    393: /* Function FlushOutput() */
                    394: /**************************/
                    395: 
                    396: int FlushOutput()
                    397: {
                    398:     /*
                    399:      * flush contents of output buffer; return PK-type error code
                    400:      */
                    401: #if (!defined(DOS_OS2) || defined(MSWIN))
                    402:     int saved_ctrlZ = FALSE;
                    403: #endif
                    404:     int len;
                    405: 
                    406: 
                    407:     if (mem_mode) {
                    408:         int rc = FlushMemory();
                    409:         outpos += outcnt;
                    410:         outcnt = 0;
                    411:         outptr = outbuf;
                    412:         return rc;
                    413:     }
                    414: 
                    415:     if (disk_full) {
                    416:         outpos += outcnt;   /* fake emptied buffer */
                    417:         outcnt = 0;
                    418:         outptr = outbuf;
                    419:         return 50;          /* ignore rest of this file */
                    420:     }
                    421: 
                    422:     if (outcnt) {
                    423:         UpdateCRC(outbuf, outcnt);
                    424: 
                    425:         if (!tflag) {
                    426: #if (!defined(DOS_OS2) || defined(MSWIN))
                    427:             if (aflag) {
                    428:                 if (outbuf[outcnt-1] == CTRLZ) {
                    429:                     --outcnt;
                    430:                     saved_ctrlZ = TRUE;
                    431:                 }
                    432:                 len = dos2unix(outbuf, outcnt);
                    433:             } else
                    434: #endif /* !DOS_OS2 || MSWIN */
                    435:                 len = outcnt;
                    436: #ifdef MACOS
                    437:             if ((giCursor+1) >> 2 != (giCursor>>2))
                    438:                 SetCursor( *rghCursor[((giCursor+1)>>2)&0x03] );
                    439:             giCursor = (giCursor+1) & 15;
                    440: #endif /* MACOS */
                    441: #ifdef MSWIN
                    442:             /* if writing to console vs. actual file, write to Msg Window */
                    443:             if (cflag)
                    444:                 WriteBufferToMsgWin(outout, len, FALSE);
                    445:             else if (_lwrite(outfd, outout, len) != (UINT)len)
                    446: #else /* !MSWIN */
                    447:             if (write(outfd, (char *)outout, len) != len)
                    448: #endif /* ?MSWIN */
                    449: #ifdef DOS_OS2
                    450:                 if (!cflag)           /* ^Z treated as EOF, removed with -c */
                    451: #else /* !DOS_OS2 */
                    452: #ifdef MINIX
                    453:                 if (errno == EFBIG)
                    454:                     if (write(fd, outout, len/2) != len/2  ||
                    455:                         write(fd, outout+len/2, len/2) != len/2)
                    456: #endif /* MINIX */
                    457: #endif /* ?DOS_OS2 */
                    458:                 {
                    459:                     /* GRR: add test for force_flag when has its own switch */
                    460:                     fprintf(stderr,
                    461:                       "\n%s:  write error (disk full?).  Continue? (y/n/^C) ",
                    462:                       filename);
                    463:                     FFLUSH   /* for Amiga and Mac MPW */
                    464: #ifdef MSWIN
                    465:                     disk_full = 2;
                    466: #else /* !MSWIN */
                    467:                     fgets(answerbuf, 9, stdin);
                    468:                     if (*answerbuf == 'y')   /* stop writing to this file */
                    469:                         disk_full = 1;       /*  (outfd bad?), but new OK */
                    470:                     else
                    471:                         disk_full = 2;       /* no:  exit program */
                    472: #endif /* ?MSWIN */
                    473:                     return 50;    /* 50:  disk full */
                    474:                 }
                    475:         }
                    476:         outpos += outcnt;
                    477:         outcnt = 0;
                    478:         outptr = outbuf;
                    479: #if (!defined(DOS_OS2) || defined(MSWIN))
                    480:         if (saved_ctrlZ) {
                    481:             *outptr++ = CTRLZ;
                    482:             ++outcnt;
                    483:         }
                    484: #endif /* !DOS_OS2 || MSWIN */
                    485:     }
                    486:     return 0;                   /* 0:  no error */
                    487: }
                    488: 
                    489: #endif /* !VMS */
                    490: 
                    491: 
                    492: 
                    493: 
                    494: 
                    495: #if (!defined(DOS_OS2) || defined(MSWIN))
                    496: 
                    497: /***********************/
                    498: /* Function dos2unix() */
                    499: /***********************/
                    500: 
                    501: static int dos2unix(buf, len)   /* GRR:  rewrite for generic text conversions */
                    502:     unsigned char *buf;
                    503:     int len;
                    504: {
                    505:     int new_len;
                    506:     int i;
                    507: #ifdef MSWIN
                    508:     unsigned char __far *walker;
                    509: #else /* !MSWIN */
                    510:     unsigned char *walker;
                    511: #endif /* ?MSWIN */
                    512: 
                    513:     new_len = len;
                    514:     walker = outout;
                    515: #ifdef MACOS
                    516:     /*
                    517:      * Mac wants to strip LFs instead CRs from CRLF pairs
                    518:      */
                    519:     if (CR_flag && *buf == LF) {
                    520:         buf++;
                    521:         new_len--;
                    522:         len--;
                    523:         CR_flag = buf[len] == CR;
                    524:     }
                    525:     else
                    526:         CR_flag = buf[len - 1] == CR;
                    527:     for (i = 0; i < len; i += 1) {
                    528:         *walker++ = ascii_to_native(*buf);
                    529:         if (*buf == LF) walker[-1] = CR;
                    530:         if (*buf++ == CR && *buf == LF) {
                    531:             new_len--;
                    532:             buf++;
                    533:             i++;
                    534:         }
                    535:     }
                    536: #else /* !MACOS */
                    537:     if (CR_flag && *buf != LF)
                    538:         *walker++ = ascii_to_native(CR);
                    539:     CR_flag = buf[len - 1] == CR;
                    540:     for (i = 0; i < len; i += 1) {
                    541:         *walker++ = ascii_to_native(*buf);
                    542:         if (*buf++ == CR && *buf == LF) {
                    543:             new_len--;
                    544:             walker[-1] = ascii_to_native(*buf++);
                    545:             i++;
                    546:         }
                    547:     }
                    548:     /*
                    549:      * If the last character is a CR, then "ignore it" for now...
                    550:      */
                    551:     if (walker[-1] == ascii_to_native(CR))
                    552:         new_len--;
                    553: #endif /* ?MACOS */
                    554:     return new_len;
                    555: }
                    556: 
                    557: #endif /* !DOS_OS2 || MSWIN */
                    558: 
                    559: 
                    560: 
                    561: 
                    562: 
                    563: #ifdef __GO32__
                    564: 
                    565: void _dos_setftime(int fd, UWORD dosdate, UWORD dostime)
                    566: {
                    567:     asm("pushl %ebx");
                    568:     asm("movl %0, %%ebx": : "g" (fd));
                    569:     asm("movl %0, %%ecx": : "g" (dostime));
                    570:     asm("movl %0, %%edx": : "g" (dosdate));
                    571:     asm("movl $0x5701, %eax");
                    572:     asm("int $0x21");
                    573:     asm("popl %ebx");
                    574: }
                    575: 
                    576: void _dos_setfileattr(char *name, int attr)
                    577: {
                    578:     asm("movl %0, %%edx": : "g" (name));
                    579:     asm("movl %0, %%ecx": : "g" (attr));
                    580:     asm("movl $0x4301, %eax");
                    581:     asm("int $0x21");
                    582: }
                    583: 
                    584: #endif /* __GO32__ */
                    585: 
                    586: 
                    587: 
                    588: 
                    589: 
                    590: #ifdef DOS_OS2
                    591: 
                    592: /**************************************/
                    593: /* Function set_file_time_and_close() */
                    594: /**************************************/
                    595: 
                    596: void set_file_time_and_close()
                    597:  /*
                    598:   * MS-DOS AND OS/2 VERSION (Mac, Unix/VMS versions are below)
                    599:   *
                    600:   * Set the output file date/time stamp according to information from the
                    601:   * zipfile directory record for this member, then close the file and set
                    602:   * its permissions (archive, hidden, read-only, system).  Aside from closing
                    603:   * the file, this routine is optional (but most compilers support it).
                    604:   */
                    605: {
                    606: /*---------------------------------------------------------------------------
                    607:     Allocate local variables needed by OS/2 and Turbo C.
                    608:   ---------------------------------------------------------------------------*/
                    609: 
                    610: #ifdef __TURBOC__
                    611: 
                    612:     union {
                    613:         struct ftime ft;        /* system file time record */
                    614:         struct {
                    615:             UWORD ztime;        /* date and time words */
                    616:             UWORD zdate;        /* .. same format as in .ZIP file */
                    617:         } zt;
                    618:     } td;
                    619: 
                    620: #endif                          /* __TURBOC__ */
                    621: 
                    622: /*---------------------------------------------------------------------------
                    623:      Do not attempt to set the time stamp on standard output.
                    624:   ---------------------------------------------------------------------------*/
                    625: 
                    626:     if (cflag) {
                    627:         close(outfd);
                    628:         return;
                    629:     }
                    630: 
                    631: /*---------------------------------------------------------------------------
                    632:     Copy and/or convert time and date variables, if necessary; then set the
                    633:     file time/date.
                    634:   ---------------------------------------------------------------------------*/
                    635: 
                    636: #ifndef OS2
                    637: #ifdef __TURBOC__
                    638:     td.zt.ztime = lrec.last_mod_file_time;
                    639:     td.zt.zdate = lrec.last_mod_file_date;
                    640:     setftime(outfd, &td.ft);
                    641: #else /* !__TURBOC__ */
                    642: #ifdef WIN32
                    643:     {
                    644:         FILETIME ft;     /* 64-bit value made up of two 32 bit [low & high] */
                    645:         WORD wDOSDate;   /* for vconvertin from DOS date to Windows NT */
                    646:         WORD wDOSTime;
                    647:         HANDLE hFile;    /* file handle (defined in Windows NT) */
                    648: 
                    649:         wDOSTime = (WORD) lrec.last_mod_file_time;
                    650:         wDOSDate = (WORD) lrec.last_mod_file_date;
                    651: 
                    652:         /* The DosDateTimeToFileTime() function converts a DOS date/time
                    653:          * into a 64 bit Windows NT file time */
                    654:         DosDateTimeToFileTime(wDOSDate, wDOSTime, &ft);
                    655: 
                    656:         /* Close the file and then re-open it using the Win32
                    657:          * CreateFile call, so that the file can be created
                    658:          * with GENERIC_WRITE access, otherwise the SetFileTime
                    659:          * call will fail. */
                    660:         close(outfd);
                    661: 
                    662:         hFile = CreateFile(filename, GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
                    663:              FILE_ATTRIBUTE_NORMAL, NULL);
                    664: 
                    665:         if (!SetFileTime(hFile, NULL, NULL, &ft))
                    666:             printf("\nSetFileTime failed: %d\n", GetLastError());
                    667:         CloseHandle(hFile);
                    668:         return;
                    669:     }
                    670: #else /* !WIN32 */
                    671:     _dos_setftime(outfd, lrec.last_mod_file_date, lrec.last_mod_file_time);
                    672: #endif /* ?WIN32 */
                    673: #endif /* ?__TURBOC__ */
                    674: #endif /* ?OS2 */
                    675: 
                    676: /*---------------------------------------------------------------------------
                    677:     And finally we can close the file...at least everybody agrees on how to
                    678:     do *this*.  I think...  Oh yeah, also change the mode according to the
                    679:     stored file attributes, since we didn't do that when we opened the dude.
                    680:   ---------------------------------------------------------------------------*/
                    681: 
                    682:     close(outfd);
                    683: 
                    684: #ifdef OS2
                    685:     SetPathInfo(filename, lrec.last_mod_file_date,
                    686:                           lrec.last_mod_file_time, pInfo->dos_attr);
                    687:     if (extra_field)
                    688:         SetEAs(filename, extra_field);
                    689:     if (longname)
                    690:         SetLongNameEA(filename, longfilename);
                    691: #else /* !OS2 */
                    692: #ifdef __TURBOC__
                    693:     if (_chmod(filename, 1, pInfo->dos_attr) != pInfo->dos_attr)
                    694:         fprintf(stderr, "\nwarning:  file attributes may not be correct\n");
                    695: #else /* !__TURBOC__ */
                    696: #ifdef WIN32
                    697:     /* Attempt to set the file attributes.  SetFileAttributes returns
                    698:      * FALSE (0) if unsucessful, in which case print an error message,
                    699:      * with error value returned from GetLastError call. */
                    700:     pInfo->dos_attr = pInfo->dos_attr & 0x7F;
                    701: 
                    702:     if (!(SetFileAttributes(filename, pInfo->dos_attr)))
                    703:         fprintf(stderr, "\nwarning (%d): could not set file attributes\n",
                    704:           GetLastError());
                    705: #else /* !WIN32 */
                    706:     _dos_setfileattr(filename, pInfo->dos_attr);
                    707: #endif /* ?WIN32 */
                    708: #endif /* ?__TURBOC__ */
                    709: #endif /* ?OS2 */
                    710: 
                    711: } /* end function set_file_time_and_close() (DOS, OS/2) */
                    712: 
                    713: 
                    714: 
                    715: 
                    716: 
                    717: #else                           /* !DOS_OS2 */
                    718: #ifdef MACOS                    /* Mac */
                    719: 
                    720: /**************************************/
                    721: /* Function set_file_time_and_close() */
                    722: /**************************************/
                    723: 
                    724: void set_file_time_and_close()
                    725:  /*
                    726:   * MAC VERSION
                    727:   */
                    728: {
                    729:     long m_time;
                    730:     DateTimeRec dtr;
                    731:     ParamBlockRec pbr;
                    732:     HParamBlockRec hpbr;
                    733:     OSErr err;
                    734: 
                    735:     if (outfd != 1) {
                    736:         close(outfd);
                    737: 
                    738:         /*
                    739:          * Macintosh bases all file modification times on the number of seconds
                    740:          * elapsed since Jan 1, 1904, 00:00:00.  Therefore, to maintain
                    741:          * compatibility with MS-DOS archives, which date from Jan 1, 1980,
                    742:          * with NO relation to GMT, the following conversions must be made:
                    743:          *      the Year (yr) must be incremented by 1980;
                    744:          *      and converted to seconds using the Mac routine Date2Secs(),
                    745:          *      almost similar in complexity to the Unix version :-)
                    746:          *                                     J. Lee
                    747:          */
                    748: 
                    749:         dtr.year = (((lrec.last_mod_file_date >> 9) & 0x7f) + 1980);
                    750:         dtr.month = ((lrec.last_mod_file_date >> 5) & 0x0f);
                    751:         dtr.day = (lrec.last_mod_file_date & 0x1f);
                    752: 
                    753:         dtr.hour = ((lrec.last_mod_file_time >> 11) & 0x1f);
                    754:         dtr.minute = ((lrec.last_mod_file_time >> 5) & 0x3f);
                    755:         dtr.second = ((lrec.last_mod_file_time & 0x1f) * 2);
                    756: 
                    757:         Date2Secs(&dtr, (unsigned long *)&m_time);
                    758:         CtoPstr(filename);
                    759:         if (hfsflag) {
                    760:             hpbr.fileParam.ioNamePtr = (StringPtr)filename;
                    761:             hpbr.fileParam.ioVRefNum = gnVRefNum;
                    762:             hpbr.fileParam.ioDirID = glDirID;
                    763:             hpbr.fileParam.ioFDirIndex = 0;
                    764:             err = PBHGetFInfo(&hpbr, 0L);
                    765:             hpbr.fileParam.ioFlMdDat = m_time;
                    766:             if ( !fMacZipped )
                    767:                 hpbr.fileParam.ioFlCrDat = m_time;
                    768:             hpbr.fileParam.ioDirID = glDirID;
                    769:             if (err == noErr)
                    770:                 err = PBHSetFInfo(&hpbr, 0L);
                    771:             if (err != noErr)
                    772:                 printf("error:  can't set the time for %s\n", filename);
                    773:         } else {
                    774:             pbr.fileParam.ioNamePtr = (StringPtr)filename;
                    775:             pbr.fileParam.ioVRefNum = pbr.fileParam.ioFVersNum =
                    776:               pbr.fileParam.ioFDirIndex = 0;
                    777:             err = PBGetFInfo(&pbr, 0L);
                    778:             pbr.fileParam.ioFlMdDat = pbr.fileParam.ioFlCrDat = m_time;
                    779:             if (err == noErr)
                    780:                 err = PBSetFInfo(&pbr, 0L);
                    781:             if (err != noErr)
                    782:                 printf("error:  can't set the time for %s\n", filename);
                    783:         }
                    784: 
                    785:         /* set read-only perms if needed */
                    786:         if ((err == noErr) && !(pInfo->unix_attr & S_IWRITE)) {
                    787:             if (hfsflag) {
                    788:                 hpbr.fileParam.ioNamePtr = (StringPtr)filename;
                    789:                 hpbr.fileParam.ioVRefNum = gnVRefNum;
                    790:                 hpbr.fileParam.ioDirID = glDirID;
                    791:                 err = PBHSetFLock(&hpbr, 0);
                    792:             } else
                    793:                 err = SetFLock((ConstStr255Param)filename, 0);
                    794:         }
                    795:         PtoCstr(filename);
                    796:     }
                    797: }
                    798: 
                    799: 
                    800: 
                    801: 
                    802: 
                    803: #else /* !MACOS... */
                    804: #if (!defined(MTS) && !defined(VMS))   /* && !MTS (can't do) && !VMS: only one
                    805:                                   * left is UNIX (for VMS use code in vms.c) */
                    806: 
                    807: /**************************************/
                    808: /* Function set_file_time_and_close() */
                    809: /**************************************/
                    810: 
                    811: void set_file_time_and_close()
                    812:  /*
                    813:   * UNIX VERSION (MS-DOS & OS/2, Mac versions are above)
                    814:   */
                    815: {
                    816:     static short yday[]={0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
                    817:     long m_time;
                    818:     int yr, mo, dy, hh, mm, ss, leap, days=0;
                    819:     struct utimbuf {
                    820:         time_t actime;          /* new access time */
                    821:         time_t modtime;         /* new modification time */
                    822:     } tp;
                    823: #ifdef AMIGA
                    824: #   define YRBASE  1978         /* in AmigaDos, counting begins 01-Jan-1978 */
                    825:     struct DateStamp myadate;
                    826: /*  extern char *_TZ;   no longer used? */
                    827: #else /* !AMIGA */
                    828: #   define YRBASE  1970
                    829: #ifdef BSD
                    830: #ifndef __386BSD__
                    831:     static struct timeb tbp;
                    832: #endif /* !__386BSD__ */
                    833: #else /* !BSD */
                    834:     extern long timezone;
                    835: #endif /* ?BSD */
                    836: #endif /* ?AMIGA */
                    837: 
                    838: 
                    839:     /*
                    840:      * Close the file *before* setting its time under Unix and AmigaDos.
                    841:      */
                    842: #ifdef AMIGA
                    843:     if (cflag)                  /* can't set time on stdout */
                    844:         return;
                    845:     close(outfd);
                    846: #else /* !AMIGA */
                    847:     close(outfd);
                    848:     if (cflag)                  /* can't set time on stdout */
                    849:         return;
                    850: #endif /* ?AMIGA */
                    851: 
                    852:     /*
                    853:      * These date conversions look a little weird, so I'll explain.
                    854:      * UNIX bases all file modification times on the number of seconds
                    855:      * elapsed since Jan 1, 1970, 00:00:00 GMT.  Therefore, to maintain
                    856:      * compatibility with MS-DOS archives, which date from Jan 1, 1980,
                    857:      * with NO relation to GMT, the following conversions must be made:
                    858:      *      the Year (yr) must be incremented by 10;
                    859:      *      the Date (dy) must be decremented by 1;
                    860:      *      and the whole mess must be adjusted by TWO factors:
                    861:      *          relationship to GMT (ie.,Pacific Time adds 8 hrs.),
                    862:      *          and whether or not it is Daylight Savings Time.
                    863:      * Also, the usual conversions must take place to account for leap years,
                    864:      * etc.
                    865:      *                                     C. Seaman
                    866:      */
                    867: 
                    868:     /* dissect date */
                    869:     yr = ((lrec.last_mod_file_date >> 9) & 0x7f) + (1980 - YRBASE);
                    870:     mo = ((lrec.last_mod_file_date >> 5) & 0x0f) - 1;
                    871:     dy = (lrec.last_mod_file_date & 0x1f) - 1;
                    872: 
                    873:     /* dissect time */
                    874:     hh = (lrec.last_mod_file_time >> 11) & 0x1f;
                    875:     mm = (lrec.last_mod_file_time >> 5) & 0x3f;
                    876:     ss = (lrec.last_mod_file_time & 0x1f) * 2;
                    877: 
                    878:     /* leap = # of leap years from BASE up to but not including current year */
                    879:     leap = ((yr + YRBASE - 1) / 4);   /* leap year base factor */
                    880: 
                    881:     /* How many days from BASE to this year? (& add expired days this year) */
                    882:     days = (yr * 365) + (leap - 492) + yday[mo];
                    883: 
                    884:     /* if year is a leap year and month is after February, add another day */
                    885:     if ((mo > 1) && ((yr+YRBASE)%4 == 0) && ((yr+YRBASE) != 2100))
                    886:         ++days;                 /* OK through 2199 */
                    887: 
                    888: #ifdef AMIGA
                    889: /*  _TZ = getenv("TZ"); does Amiga not have TZ and tzset() after all? */
                    890:     myadate.ds_Days   =   days+dy-2;   /* off by one? */
                    891:     myadate.ds_Minute =   hh*60+mm;
                    892:     myadate.ds_Tick   =   ss*TICKS_PER_SECOND;
                    893: 
                    894:     if (!(SetFileDate(filename, &myadate)))
                    895:         fprintf(stderr, "error:  can't set the time for %s\n", filename);
                    896: 
                    897: #else /* !AMIGA */
                    898:     /* convert date & time to seconds relative to 00:00:00, 01/01/YRBASE */
                    899:     m_time = ((days + dy) * 86400) + (hh * 3600) + (mm * 60) + ss;
                    900: 
                    901: #ifdef BSD
                    902: #ifndef __386BSD__
                    903:     ftime(&tbp);
                    904:     m_time += tbp.timezone * 60L;
                    905: #endif
                    906: /* #elif WIN32
                    907:  * don't do anything right now (esp. since "elif" is not legal for old cc's */
                    908: #else /* !BSD */
                    909:     tzset();                    /* set `timezone' */
                    910:     m_time += timezone;         /* account for timezone differences */
                    911: #endif /* ?BSD */
                    912: 
                    913: #ifdef __386BSD__
                    914:     m_time += localtime(&m_time)->tm_gmtoff;
                    915: #else
                    916:     if (localtime(&m_time)->tm_isdst)
                    917:         m_time -= 60L * 60L;    /* adjust for daylight savings time */
                    918: #endif
                    919: 
                    920:     tp.actime = m_time;         /* set access time */
                    921:     tp.modtime = m_time;        /* set modification time */
                    922: 
                    923:     /* set the time stamp on the file */
                    924:     if (utime(filename, &tp))
                    925:         fprintf(stderr, "error:  can't set the time for %s\n", filename);
                    926: #endif /* ?AMIGA */
                    927: }
                    928: 
                    929: #endif /* !MTS && !VMS */
                    930: #endif /* ?MACOS */
                    931: #endif /* ?DOS_OS2 */
                    932: 
                    933: 
                    934: 
                    935: 
                    936: 
                    937: /************************/
                    938: /*  Function handler()  */
                    939: /************************/
                    940: 
                    941: void handler(signal)   /* upon interrupt, turn on echo and exit cleanly */
                    942:     int signal;
                    943: {
                    944: #if (defined(SIGBUS) || defined(SIGSEGV))
                    945:     static char *corrupt = "error:  zipfile probably corrupt\n";
                    946: #endif
                    947: 
                    948: #ifndef DOS_OS2
                    949: #ifdef CRYPT
                    950:     echon();
                    951: #endif /* CRYPT */
                    952:     putc('\n', stderr);
                    953: #endif /* !DOS_OS2 */
                    954: #ifdef SIGBUS
                    955:     if (signal == SIGBUS) {
                    956:         fprintf(stderr, corrupt);
                    957:         exit(3);
                    958:     }
                    959: #endif /* SIGBUS */
                    960: #ifdef SIGSEGV
                    961:     if (signal == SIGSEGV) {
                    962:         fprintf(stderr, corrupt);
                    963:         exit(3);
                    964:     }
                    965: #endif /* SIGSEGV */
                    966:     exit(0);
                    967: }
                    968: 
                    969: 
                    970: 
                    971: 
                    972: 
                    973: /*******************************/
                    974: /*  Non-echoing password code  */
                    975: /*******************************/
                    976: 
                    977: #ifdef CRYPT
                    978: #ifndef DOS_OS2
                    979: #ifdef VMS
                    980: 
                    981: int echo(opt)
                    982:     int opt;
                    983: {
                    984: /*---------------------------------------------------------------------------
                    985:     Based on VMSmunch.c, which in turn was based on Joe Meadows' file.c code.
                    986:   ---------------------------------------------------------------------------
                    987:      * For VMS v5.x:
                    988:      *   IO$_SENSEMODE/SETMODE info:  Programming, Vol. 7A, System Programming,
                    989:      *     I/O User's: Part I, sec. 8.4.1.1, 8.4.3, 8.4.5, 8.6
                    990:      *   sys$assign(), sys$qio() info:  Programming, Vol. 4B, System Services,
                    991:      *     System Services Reference Manual, pp. sys-23, sys-379
                    992:      *   fixed-length descriptor info:  Programming, Vol. 3, System Services,
                    993:      *     Intro to System Routines, sec. 2.9.2
                    994:      * GRR, 15 Aug 91
                    995:   ---------------------------------------------------------------------------*/
                    996:     static struct dsc$descriptor_s DevDesc =
                    997:         {9, DSC$K_DTYPE_T, DSC$K_CLASS_S, "SYS$INPUT"};
                    998:      /* {dsc$w_length, dsc$b_dtype, dsc$b_class, dsc$a_pointer}; */
                    999:     static short           DevChan, iosb[4];
                   1000:     static long            i, status;
                   1001:     static unsigned long   oldmode[2], newmode[2];   /* each = 8 bytes */
                   1002:   
                   1003: 
                   1004: /*---------------------------------------------------------------------------
                   1005:     Assign a channel to standard input.
                   1006:   ---------------------------------------------------------------------------*/
                   1007: 
                   1008:     status = sys$assign(&DevDesc, &DevChan, 0, 0);
                   1009:     if (!(status & 1))
                   1010:         return status;
                   1011: 
                   1012: /*---------------------------------------------------------------------------
                   1013:     Use sys$qio and the IO$_SENSEMODE function to determine the current tty
                   1014:     status (for password reading, could use IO$_READVBLK function instead,
                   1015:     but echo on/off will be more general).
                   1016:   ---------------------------------------------------------------------------*/
                   1017: 
                   1018:     status = sys$qio(0, DevChan, IO$_SENSEMODE, &iosb, 0, 0,
                   1019:                      oldmode, 8, 0, 0, 0, 0);
                   1020:     if (!(status & 1))
                   1021:         return status;
                   1022:     status = iosb[0];
                   1023:     if (!(status & 1))
                   1024:         return status;
                   1025: 
                   1026: /*---------------------------------------------------------------------------
                   1027:     Copy old mode into new-mode buffer, then modify to be either NOECHO or
                   1028:     ECHO (depending on function argument opt).
                   1029:   ---------------------------------------------------------------------------*/
                   1030: 
                   1031:     newmode[0] = oldmode[0];
                   1032:     newmode[1] = oldmode[1];
                   1033:     if (opt == OFF)
                   1034:         newmode[1] |= TT$M_NOECHO;                      /* set NOECHO bit */
                   1035:     else
                   1036:         newmode[1] &= ~((unsigned long) TT$M_NOECHO);   /* clear NOECHO bit */
                   1037: 
                   1038: /*---------------------------------------------------------------------------
                   1039:     Use the IO$_SETMODE function to change the tty status.
                   1040:   ---------------------------------------------------------------------------*/
                   1041: 
                   1042:     status = sys$qio(0, DevChan, IO$_SETMODE, &iosb, 0, 0,
                   1043:                      newmode, 8, 0, 0, 0, 0);
                   1044:     if (!(status & 1))
                   1045:         return status;
                   1046:     status = iosb[0];
                   1047:     if (!(status & 1))
                   1048:         return status;
                   1049: 
                   1050: /*---------------------------------------------------------------------------
                   1051:     Deassign the sys$input channel by way of clean-up, then exit happily.
                   1052:   ---------------------------------------------------------------------------*/
                   1053: 
                   1054:     status = sys$dassgn(DevChan);
                   1055:     if (!(status & 1))
                   1056:         return status;
                   1057: 
                   1058:     return SS$_NORMAL;   /* we be happy */
                   1059: 
                   1060: } /* end function echo() */
                   1061: 
                   1062: 
                   1063: 
                   1064: 
                   1065: 
                   1066: #else /* !VMS */
                   1067: 
                   1068: static int echofd=(-1);       /* file descriptor whose echo is off */
                   1069: 
                   1070: void echoff(f)
                   1071:     int f;                    /* file descriptor for which to turn echo off */
                   1072: /* Turn echo off for file descriptor f.  Assumes that f is a tty device. */
                   1073: {
                   1074:     struct sgttyb sg;         /* tty device structure */
                   1075: 
                   1076:     echofd = f;
                   1077:     GTTY(f, &sg);             /* get settings */
                   1078:     sg.sg_flags &= ~ECHO;     /* turn echo off */
                   1079:     STTY(f, &sg);
                   1080: }
                   1081: 
                   1082: 
                   1083: 
                   1084: void echon()
                   1085: /* Turn echo back on for file descriptor echofd. */
                   1086: {
                   1087:     struct sgttyb sg;         /* tty device structure */
                   1088: 
                   1089:     if (echofd != -1) {
                   1090:         GTTY(echofd, &sg);    /* get settings */
                   1091:         sg.sg_flags |= ECHO;  /* turn echo on */
                   1092:         STTY(echofd, &sg);
                   1093:         echofd = -1;
                   1094:     }
                   1095: }
                   1096: 
                   1097: #endif /* ?VMS */
                   1098: #endif /* !DOS_OS2 */
                   1099: 
                   1100: 
                   1101: 
                   1102: 
                   1103: 
                   1104: char *getp(m, p, n)
                   1105:     char *m;                  /* prompt for password */
                   1106:     char *p;                  /* return value: line input */
                   1107:     int n;                    /* bytes available in p[] */
                   1108: /* Get a password of length n-1 or less into *p using the prompt *m.
                   1109:    The entered password is not echoed.  Return p on success, NULL on
                   1110:    failure (can't get controlling tty). */
                   1111: {
                   1112:     char c;                   /* one-byte buffer for read() to use */
                   1113:     int i;                    /* number of characters input */
                   1114:     char *w;                  /* warning on retry */
                   1115: 
                   1116: #ifndef DOS_OS2
                   1117: #ifndef VMS
                   1118:     int f;                    /* file decsriptor for tty device */
                   1119: 
                   1120:     /* turn off echo on tty */
                   1121:     if (!isatty(2))
                   1122:         return NULL;          /* error if not tty */
                   1123:     if ((f = open(ttyname(2), 0, 0)) == -1)
                   1124:         return NULL;
                   1125: #endif /* !VMS */
                   1126:     echoff(f);                /* turn echo off */
                   1127: #endif /* !DOS_OS2 */
                   1128: 
                   1129:     /* get password */
                   1130:     w = "";
                   1131:     do {
                   1132: #ifdef VMS   /* bug:  VMS adds '\n' to NULL fputs (apparently) */
                   1133:         if (*w)
                   1134: #endif /* VMS */
                   1135:             fputs(w, stderr); /* warning if back again */
                   1136:         fputs(m, stderr);     /* prompt */
                   1137:         fflush(stderr);
                   1138:         i = 0;
                   1139:         do {                  /* read line, keeping n */
                   1140: #ifdef MSVMS
                   1141:             if ((c = (char)getch()) == '\r')
                   1142:                 c = '\n';
                   1143: #else /* !MSVMS */
                   1144:             read(f, &c, 1);
                   1145: #endif /* ?MSVMS */
                   1146:             if (i < n)
                   1147:                 p[i++] = c;
                   1148:         } while (c != '\n');
                   1149:         putc('\n', stderr);  fflush(stderr);
                   1150:         w = "(line too long--try again)\n";
                   1151:     } while (p[i-1] != '\n');
                   1152:     p[i-1] = 0;               /* terminate at newline */
                   1153: 
                   1154: #ifndef DOS_OS2
                   1155:     echon();                  /* turn echo back on */
                   1156: #ifndef VMS
                   1157:     close(f);
                   1158: #endif /* !VMS */
                   1159: #endif /* !DOS_OS2 */
                   1160: 
                   1161:     /* return pointer to password */
                   1162:     return p;
                   1163: }
                   1164: 
                   1165: #endif /* CRYPT */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.