home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #19 / NN_1992_19.iso / spool / vmsnet / sources / 320 < prev    next >
Encoding:
Internet Message Format  |  1992-09-01  |  46.9 KB

  1. Path: sparky!uunet!zaphod.mps.ohio-state.edu!news.acns.nwu.edu!network.ucsd.edu!mvb.saic.com!vmsnet-sources
  2. From: goathunter@wkuvx1.bitnet
  3. Newsgroups: vmsnet.sources
  4. Subject: Zip v1.9 & UnZip v5.0, part 03/22
  5. Message-ID: <8009589@MVB.SAIC.COM>
  6. Date: Tue, 01 Sep 1992 22:48:58 GMT
  7. Organization: Western Kentucky University, Bowling Green, KY
  8. Lines: 1547
  9. Approved: Mark.Berryman@Mvb.Saic.Com
  10.  
  11. Submitted-by: goathunter@wkuvx1.bitnet
  12. Posting-number: Volume 3, Issue 125
  13. Archive-name: zip_unzip/part03
  14.  
  15. -+-+-+-+-+-+-+-+ START OF PART 3 -+-+-+-+-+-+-+-+
  16. X    /* same test as in zipbare() in crypt.c: */
  17. X    if ((UWORD)(c `7C (b<<8)) != (pInfo->ExtLocHdr? lrec.last_mod_file_time
  18. V :
  19. X        (UWORD)(lrec.crc32 >> 16)))
  20. X        return -1;  /* bad */
  21. X
  22. X    /* password OK:  decrypt current buffer contents before leaving */
  23. X    for (n = (longint)incnt > csize ? (int)csize : incnt, p = inptr; n--; p+
  24. V+)
  25. X        *p = (byte) DECRYPT(*p);
  26. X    return 0;       /* OK */
  27. X
  28. X`7D /* end function testp() */
  29. X
  30. X#endif /* CRYPT */
  31. X
  32. X
  33. X
  34. X
  35. X
  36. X/*******************************/
  37. X/*  Function ReadMemoryByte()  */
  38. X/*******************************/
  39. X
  40. Xint ReadMemoryByte(x)   /* return PK-type error code */
  41. X    UWORD *x;
  42. X`7B
  43. X    if (mem_i_offset < mem_i_size) `7B
  44. X        *x = (UWORD) mem_i_buffer`5Bmem_i_offset++`5D;
  45. X        return 8;
  46. X    `7D else
  47. X        return 0;
  48. X`7D
  49. X
  50. X
  51. X
  52. X
  53. X
  54. X/****************************/
  55. X/*  Function FlushMemory()  */
  56. X/****************************/
  57. X
  58. Xint FlushMemory()   /* return PK-type error code */
  59. X`7B
  60. X    if (outcnt == 0)
  61. X        return 0;
  62. X
  63. X    if (mem_o_offset + outcnt <= mem_o_size) `7B
  64. X        memcpy((char *)(mem_o_buffer+mem_o_offset), (char *)outbuf, outcnt);
  65. X        mem_o_offset += outcnt;
  66. X        return 0;
  67. X    `7D else
  68. X        return 50;
  69. X`7D
  70. X
  71. X
  72. X
  73. X
  74. X
  75. X/***************************/
  76. X/*  Function memextract()  */   /* extract compressed extra field block */
  77. X/***************************/
  78. X
  79. Xint memextract(tgt, tgtsize, src, srcsize)  /* return 0 if success, 1 if not
  80. V */
  81. X    byte *tgt, *src;
  82. X    ULONG tgtsize, srcsize;
  83. X`7B
  84. X    UWORD method, error = 0;
  85. X    ULONG crc, oldcrc;
  86. X
  87. X    method = makeword(src);
  88. X    crc = makelong(src+2);
  89. X
  90. X    mem_i_buffer = src + 2 + 4;      /* method and crc */
  91. X    mem_i_size   = srcsize - 2 - 4;
  92. X    mem_i_offset = 0;
  93. X `20
  94. X    mem_o_buffer = tgt;
  95. X    mem_o_size   = tgtsize;
  96. X    mem_o_offset = 0;
  97. X
  98. X    mem_mode = 1;
  99. X
  100. X    bits_left = 0;
  101. X    bitbuf = 0L;
  102. X    outpos = 0L;
  103. X    outcnt = 0;
  104. X    outptr = outbuf;
  105. X    zipeof = 0;
  106. X
  107. X    switch (method) `7B
  108. X        case STORED:
  109. X            memcpy(tgt, src + 2 + 4, (extent) (srcsize - 2 - 4));
  110. X            break;
  111. X        case DEFLATED:
  112. X            inflate();
  113. X            FlushOutput();
  114. X            break;
  115. X        default:
  116. X            fprintf(stderr,
  117. X              "warning:  unsupported extra field compression type--skipping\
  118. Vn");
  119. X            error = 1;   /* GRR:  this should be passed on up via SetEAs() *
  120. V/
  121. X            break;
  122. X    `7D
  123. X
  124. X    mem_mode = 0;
  125. X
  126. X    if (!error) `7B
  127. X        oldcrc = crc32val;
  128. X        crc32val = 0xFFFFFFFFL;
  129. X        UpdateCRC((unsigned char *) mem_o_buffer, (int) mem_o_size);
  130. X        crc32val = (`7Ecrc32val) & 0xFFFFFFFFL;
  131. X
  132. X        if (crc32val != crc) `7B
  133. X            printf("(Bad extra field CRC %08lx, should be %08lx)\n", crc32va
  134. Vl,
  135. X              crc);
  136. X            error = 1;
  137. X        `7D
  138. X        crc32val = oldcrc; /* grrr ... this ugly kludge should be fixed */
  139. X    `7D
  140. X
  141. X    return error;
  142. X`7D
  143. $ CALL UNPACK [.UNZIP50]EXTRACT.C;1 241729109
  144. $ create 'f'
  145. X/*--------------------------------------------------------------------------
  146. V-
  147. X
  148. X  file_io.c
  149. X
  150. X  This file contains routines for doing direct input/output, file-related
  151. X  sorts of things.  Most of the system-specific code for unzip is contained
  152. X  here, including the non-echoing password code for decryption (bottom).
  153. X
  154. X  --------------------------------------------------------------------------
  155. V-*/
  156. X
  157. X
  158. X#ifndef __GO32__
  159. X#  define const
  160. X#endif
  161. X
  162. X#define FILE_IO_C
  163. X#include "unzip.h"
  164. X
  165. X#ifdef  MSWIN
  166. X#  include "wizunzip.h"
  167. X#endif
  168. X
  169. X
  170. X/************************************/
  171. X/*  File_IO Local Prototypes, etc.  */
  172. X/************************************/
  173. X
  174. X#if (!defined(DOS_OS2) `7C`7C defined(MSWIN))
  175. X   static int dos2unix __((unsigned char *buf, int len));
  176. X   int CR_flag = 0;      /* when last char of buffer == CR (for dos2unix())
  177. V */
  178. X#endif
  179. X
  180. X#ifdef OS2
  181. X   extern int   longname;          /* set in mapname.c */
  182. X   extern char  longfilename`5B`5D;
  183. X#endif
  184. X
  185. X#ifdef CRYPT
  186. X#  if (defined(DOS_OS2) `7C`7C defined(VMS))
  187. X#    define MSVMS
  188. X#    ifdef DOS_OS2
  189. X#      ifdef __EMX__
  190. X#        define getch() _read_kbd(0, 1, 0)
  191. X#      else
  192. X#        ifdef __GO32__
  193. X#          include <pc.h>
  194. X#          define getch() getkey()
  195. X#        else /* !__GO32__ */
  196. X#          include <conio.h>
  197. X#        endif /* ?__GO32__ */
  198. X#      endif
  199. X#    else /* !DOS_OS2 */
  200. X#      define getch() getc(stderr)
  201. X#      define OFF 0   /* for echo control */
  202. X#      define ON 1
  203. X#      define echoff(f) echo(OFF)
  204. X#      define echon()   echo(ON)
  205. X#      include <descrip.h>
  206. X#      include <iodef.h>
  207. X#      include <ttdef.h>
  208. X#      if !defined(SS$_NORMAL)
  209. X#        define SS$_NORMAL 1   /* only thing we need from <ssdef.h> */
  210. X#      endif
  211. X#    endif /* ?DOS_OS2 */
  212. X#  else /* !(DOS_OS2 `7C`7C VMS) */
  213. X#    ifdef TERMIO       /* Amdahl, Cray, all SysV? */
  214. X#      ifdef CONVEX
  215. X#        include <sys/termios.h>
  216. X#        include <sgtty.h>
  217. X#      else /* !CONVEX */
  218. X#        ifdef LINUX
  219. X#          include <termios.h>
  220. X#        else /* !LINUX */
  221. X#          include <sys/termio.h>
  222. X#        endif /* ?LINUX */
  223. X#        define sgttyb termio
  224. X#        define sg_flags c_lflag
  225. X#      endif /* ?CONVEX */
  226. X       int ioctl OF((int, int, voidp *));
  227. X#      define GTTY(f,s) ioctl(f,TCGETA,(voidp *)s)
  228. X#      define STTY(f,s) ioctl(f,TCSETAW,(voidp *)s)
  229. X#    else /* !TERMIO */
  230. X#      if (!defined(MINIX) && !defined(__386BSD__))
  231. X#        include <sys/ioctl.h>
  232. X#      endif /* !MINIX && !__386BSD__ */
  233. X#      include <sgtty.h>
  234. X#      ifdef __386BSD__
  235. X#        define GTTY(f, s) ioctl(f, TIOCGETP, (voidp *) s)
  236. X#        define STTY(f, s) ioctl(f, TIOCSETP, (voidp *) s)
  237. X#      else /* !__386BSD__ */
  238. X#        define GTTY gtty
  239. X#        define STTY stty
  240. X         int gtty OF((int, struct sgttyb *));
  241. X         int stty OF((int, struct sgttyb *));
  242. X#      endif /* ?__386BSD__ */
  243. X#    endif /* ?TERMIO */
  244. X     int isatty OF((int));
  245. X     char *ttyname OF((int));
  246. X#    if (defined(PROTO) && !defined(__GNUC__) && !defined(_AIX))
  247. X       int open (char *, int, ...);
  248. X#    endif
  249. X     int close OF((int));
  250. X     int read OF((int, voidp *, int));
  251. X#  endif /* ?(DOS_OS2 `7C`7C VMS) */
  252. X#endif /* CRYPT */
  253. X
  254. X
  255. X
  256. X
  257. X
  258. X/******************************/
  259. X/* Function open_input_file() */
  260. X/******************************/
  261. X
  262. Xint open_input_file()    /* return non-zero if open failed */
  263. X`7B
  264. X    /*
  265. X     *  open the zipfile for reading and in BINARY mode to prevent cr/lf
  266. X     *  translation, which would corrupt the bitstreams
  267. X     */
  268. X
  269. X#ifdef VMS
  270. X    zipfd = open(zipfn, O_RDONLY, 0, "ctx=stm");
  271. X#else /* !VMS */
  272. X#ifdef UNIX
  273. X    zipfd = open(zipfn, O_RDONLY);
  274. X#else /* !UNIX */
  275. X#ifdef MACOS
  276. X    zipfd = open(zipfn, 0);
  277. X#else /* !MACOS */
  278. X    zipfd = open(zipfn, O_RDONLY `7C O_BINARY);
  279. X#endif /* ?MACOS */
  280. X#endif /* ?UNIX */
  281. X#endif /* ?VMS */
  282. X    if (zipfd < 1) `7B
  283. X        fprintf(stderr, "error:  can't open zipfile `5B %s `5D\n", zipfn);
  284. X        return (1);
  285. X    `7D
  286. X    return 0;
  287. X`7D
  288. X
  289. X
  290. X
  291. X
  292. X
  293. X/**********************/
  294. X/* Function readbuf() */
  295. X/**********************/
  296. X
  297. Xint readbuf(buf, size)
  298. X    char *buf;
  299. X    register unsigned size;
  300. X`7B                               /* return number of bytes read into buf */
  301. X    register int count;
  302. X    int n;
  303. X
  304. X    n = size;
  305. X    while (size) `7B
  306. X        if (incnt == 0) `7B
  307. X            if ((incnt = read(zipfd, (char *)inbuf, INBUFSIZ)) <= 0)
  308. X                return (n-size);
  309. X            /* buffer ALWAYS starts on a block boundary:  */
  310. X            cur_zipfile_bufstart += INBUFSIZ;
  311. X            inptr = inbuf;
  312. X        `7D
  313. X        count = MIN(size, (unsigned)incnt);
  314. X        memcpy(buf, inptr, count);
  315. X        buf += count;
  316. X        inptr += count;
  317. X        incnt -= count;
  318. X        size -= count;
  319. X    `7D
  320. X    return (n);
  321. X`7D
  322. X
  323. X
  324. X
  325. X
  326. X
  327. X#ifndef VMS   /* for VMS use code in vms.c (old VMS code below is retained
  328. X               * in case of problems...will be removed in a later release) *
  329. V/
  330. X
  331. X/*********************************/
  332. X/* Function create_output_file() */
  333. X/*********************************/
  334. X
  335. Xint create_output_file()         /* return non-0 if creat failed */
  336. X`7B
  337. X/*--------------------------------------------------------------------------
  338. V-
  339. X    Create the output file with appropriate permissions.  If we've gotten to
  340. X    this point and the file still exists, we have permission to blow it away
  341. V.
  342. X  --------------------------------------------------------------------------
  343. V-*/
  344. X
  345. X#if (!defined(DOS_OS2) `7C`7C defined(MSWIN))
  346. X    CR_flag = 0;   /* hack to get CR at end of buffer working */
  347. X#endif
  348. X
  349. X#if (defined(UNIX) && !defined(AMIGA))
  350. X    `7B
  351. X        int mask;
  352. X
  353. X#ifndef VMS
  354. X        if (!stat(filename, &statbuf) && (unlink(filename) < 0)) `7B
  355. X            fprintf(stderr, "\n%s:  cannot delete old copy\n", filename);
  356. X            return 1;
  357. X        `7D
  358. X#       define EXTRA_ARGS
  359. X#else /* VMS */
  360. X#       define EXTRA_ARGS   ,"rfm=stmlf","rat=cr"
  361. X#endif /* ?VMS */
  362. X
  363. X        mask = umask(0);   /* now know that we own it */
  364. X        outfd = creat(filename, 0xffff & pInfo->unix_attr  EXTRA_ARGS);
  365. X        umask(mask);                                            /* VMS, Unix
  366. V */
  367. X    `7D
  368. X#else /* !UNIX `7C`7C AMIGA */  /* file permissions set after file closed */
  369. X#ifndef MACOS
  370. X    outfd = creat(filename, S_IWRITE `7C S_IREAD);     /* DOS, OS2, Mac, Ami
  371. Vga */
  372. X#else /* MACOS */
  373. X    `7B
  374. X        short fDataFork=TRUE;
  375. X        MACINFO mi;
  376. X        OSErr err;
  377. X
  378. X        fMacZipped = FALSE;
  379. X        CtoPstr(filename);
  380. X        if (extra_field &&
  381. X            (lrec.extra_field_length > sizeof(MACINFOMIN)) &&
  382. X            (lrec.extra_field_length <= sizeof(MACINFO))) `7B
  383. X            BlockMove(extra_field, &mi, lrec.extra_field_length);
  384. X            if ((makeword((byte *)&mi.header) == 1992) &&
  385. X                (makeword((byte *)&mi.data) ==
  386. X                  lrec.extra_field_length-sizeof(ZIP_EXTRA_HEADER)) &&
  387. X                (mi.signature == 'JLEE')) `7B
  388. X                gostCreator = mi.finfo.fdCreator;
  389. X                gostType = mi.finfo.fdType;
  390. X                fDataFork = (mi.flags & 1) ? TRUE : FALSE;
  391. X                fMacZipped = true;
  392. X                /* If it was Zipped w/Mac version, the filename has either *
  393. V/
  394. X                /* a 'd' or 'r' appended.  Remove the d/r when unzipping */
  395. X                filename`5B0`5D-=1;
  396. X            `7D
  397. X        `7D
  398. X        if (!fMacZipped) `7B
  399. X            if (!aflag)
  400. X                gostType = gostCreator = '\?\?\?\?';
  401. X            else `7B
  402. X#ifdef THINK_C
  403. X                gostCreator = 'KAHL';
  404. X#else
  405. X#ifdef MCH_MACINTOSH
  406. X                gostCreator = 'Manx';
  407. X#else
  408. X                gostCreator = 'MPS ';
  409. X#endif
  410. X#endif
  411. X                gostType = 'TEXT';
  412. X            `7D
  413. X        `7D
  414. X        PtoCstr(filename);
  415. X
  416. X        outfd = creat(filename, 0);
  417. X        if (fMacZipped) `7B
  418. X            CtoPstr(filename);
  419. X            if (hfsflag) `7B
  420. X                HParamBlockRec   hpbr;
  421. X   `20
  422. X                hpbr.fileParam.ioNamePtr = (StringPtr)filename;
  423. X                hpbr.fileParam.ioVRefNum = gnVRefNum;
  424. X                hpbr.fileParam.ioDirID = glDirID;
  425. X                hpbr.fileParam.ioFlFndrInfo = mi.finfo;
  426. X                hpbr.fileParam.ioFlCrDat = mi.lCrDat;
  427. X                hpbr.fileParam.ioFlMdDat = mi.lMdDat;
  428. X                err = PBHSetFInfo(&hpbr, 0);
  429. X            `7D else `7B
  430. X                err = SetFInfo((StringPtr)filename , 0, &mi.finfo);
  431. X            `7D
  432. X            PtoCstr(filename);
  433. X        `7D
  434. X        if (outfd != -1)
  435. X            outfd = open(filename, (fDataFork)? 1 : 2);
  436. X    `7D
  437. X#endif /* ?MACOS */
  438. X#endif /* ?(UNIX && !AMIGA) */
  439. X
  440. X    if (outfd < 1) `7B
  441. X        fprintf(stderr, "\n%s:  cannot create\n", filename);
  442. X        return 1;
  443. X    `7D
  444. X
  445. X/*--------------------------------------------------------------------------
  446. V-
  447. X    If newly created file is in text mode and should be binary (to disable
  448. X    automatic CR/LF translations), either close it and reopen as binary or
  449. X    else change the mode to binary (DOS, OS/2).
  450. X  --------------------------------------------------------------------------
  451. V-*/
  452. X
  453. X#if (!defined(UNIX) && !defined(MACOS))
  454. X    if (!aflag) `7B
  455. X#ifdef DOS_OS2
  456. X        if (setmode(outfd, O_BINARY) == -1) `7B
  457. X#else /* !DOS_OS2 */
  458. X        close(outfd);
  459. X        if ((outfd = open(filename, O_RDWR `7C O_BINARY)) < 1) `7B
  460. X#endif /* ?DOS_OS2 */
  461. X            fprintf(stderr, "Can't make output file binary:  %s\n", filename
  462. V);
  463. X            return 1;
  464. X        `7D
  465. X    `7D
  466. X#endif /* !UNIX && !MACOS */
  467. X
  468. X    return 0;
  469. X`7D
  470. X
  471. X#endif /* !VMS */
  472. X
  473. X
  474. X
  475. X
  476. X
  477. X/****************************/
  478. X/* Function FillBitBuffer() */
  479. X/****************************/
  480. X
  481. Xint FillBitBuffer()
  482. X`7B
  483. X    /*
  484. X     * Fill bitbuf, which is 32 bits.  This function is only used by the
  485. X     * READBIT and PEEKBIT macros (which are used by all of the uncompressio
  486. Vn
  487. X     * routines).
  488. X     */
  489. X    UWORD temp;
  490. X
  491. X    zipeof = 1;
  492. X    while (bits_left < 25 && ReadByte(&temp) == 8)
  493. X    `7B
  494. X      bitbuf `7C= (ULONG)temp << bits_left;
  495. X      bits_left += 8;
  496. X      zipeof = 0;
  497. X    `7D
  498. X    return 0;
  499. X`7D
  500. X
  501. X
  502. X
  503. X
  504. X
  505. X/***********************/
  506. X/* Function ReadByte() */
  507. X/***********************/
  508. X
  509. Xint ReadByte(x)
  510. X    UWORD *x;
  511. X`7B
  512. X    /*
  513. X     * read a byte; return 8 if byte available, 0 if not
  514. X     */
  515. X
  516. X    if (mem_mode)
  517. X        return ReadMemoryByte(x);
  518. X
  519. X    if (csize-- <= 0)
  520. X        return 0;
  521. X
  522. X    if (incnt == 0) `7B
  523. X        if ((incnt = read(zipfd, (char *)inbuf, INBUFSIZ)) <= 0)
  524. X            return 0;
  525. X        /* buffer ALWAYS starts on a block boundary:  */
  526. X        cur_zipfile_bufstart += INBUFSIZ;
  527. X        inptr = inbuf;
  528. X#ifdef CRYPT
  529. X        if (pInfo->encrypted) `7B
  530. X            byte *p;
  531. X            int n, t;
  532. X
  533. X            for (n = (longint)incnt > csize + 1 ? (int)csize + 1 : incnt,
  534. X                 p = inptr; n--; p++)
  535. X                *p = (byte) DECRYPT(*p);
  536. X        `7D
  537. X#endif /* CRYPT */
  538. X    `7D
  539. X    *x = *inptr++;
  540. X    --incnt;
  541. X    return 8;
  542. X`7D
  543. X
  544. X
  545. X
  546. X
  547. X
  548. X#ifndef VMS   /* for VMS use code in vms.c */
  549. X
  550. X/**************************/
  551. X/* Function FlushOutput() */
  552. X/**************************/
  553. X
  554. Xint FlushOutput()
  555. X`7B
  556. X    /*
  557. X     * flush contents of output buffer; return PK-type error code
  558. X     */
  559. X#if (!defined(DOS_OS2) `7C`7C defined(MSWIN))
  560. X    int saved_ctrlZ = FALSE;
  561. X#endif
  562. X    int len;
  563. X
  564. X
  565. X    if (mem_mode) `7B
  566. X        int rc = FlushMemory();
  567. X        outpos += outcnt;
  568. X        outcnt = 0;
  569. X        outptr = outbuf;
  570. X        return rc;
  571. X    `7D
  572. X
  573. X    if (disk_full) `7B
  574. X        outpos += outcnt;   /* fake emptied buffer */
  575. X        outcnt = 0;
  576. X        outptr = outbuf;
  577. X        return 50;          /* ignore rest of this file */
  578. X    `7D
  579. X
  580. X    if (outcnt) `7B
  581. X        UpdateCRC(outbuf, outcnt);
  582. X
  583. X        if (!tflag) `7B
  584. X#if (!defined(DOS_OS2) `7C`7C defined(MSWIN))
  585. X            if (aflag) `7B
  586. X                if (outbuf`5Boutcnt-1`5D == CTRLZ) `7B
  587. X                    --outcnt;
  588. X                    saved_ctrlZ = TRUE;
  589. X                `7D
  590. X                len = dos2unix(outbuf, outcnt);
  591. X            `7D else
  592. X#endif /* !DOS_OS2 `7C`7C MSWIN */
  593. X                len = outcnt;
  594. X#ifdef MACOS
  595. X            if ((giCursor+1) >> 2 != (giCursor>>2))
  596. X                SetCursor( *rghCursor`5B((giCursor+1)>>2)&0x03`5D );
  597. X            giCursor = (giCursor+1) & 15;
  598. X#endif /* MACOS */
  599. X#ifdef MSWIN
  600. X            /* if writing to console vs. actual file, write to Msg Window */
  601. X            if (cflag)
  602. X                WriteBufferToMsgWin(outout, len, FALSE);
  603. X            else if (_lwrite(outfd, outout, len) != (UINT)len)
  604. X#else /* !MSWIN */
  605. X            if (write(outfd, (char *)outout, len) != len)
  606. X#endif /* ?MSWIN */
  607. X#ifdef DOS_OS2
  608. X                if (!cflag)           /* `5EZ treated as EOF, removed with -
  609. Vc */
  610. X#else /* !DOS_OS2 */
  611. X#ifdef MINIX
  612. X                if (errno == EFBIG)
  613. X                    if (write(fd, outout, len/2) != len/2  `7C`7C
  614. X                        write(fd, outout+len/2, len/2) != len/2)
  615. X#endif /* MINIX */
  616. X#endif /* ?DOS_OS2 */
  617. X                `7B
  618. X                    /* GRR: add test for force_flag when has its own switch
  619. V */
  620. X                    fprintf(stderr,
  621. X                      "\n%s:  write error (disk full?).  Continue? (y/n/`5EC
  622. V) ",
  623. X                      filename);
  624. X                    FFLUSH   /* for Amiga and Mac MPW */
  625. X#ifdef MSWIN
  626. X                    disk_full = 2;
  627. X#else /* !MSWIN */
  628. X                    fgets(answerbuf, 9, stdin);
  629. X                    if (*answerbuf == 'y')   /* stop writing to this file */
  630. X                        disk_full = 1;       /*  (outfd bad?), but new OK */
  631. X                    else
  632. X                        disk_full = 2;       /* no:  exit program */
  633. X#endif /* ?MSWIN */
  634. X                    return 50;    /* 50:  disk full */
  635. X                `7D
  636. X        `7D
  637. X        outpos += outcnt;
  638. X        outcnt = 0;
  639. X        outptr = outbuf;
  640. X#if (!defined(DOS_OS2) `7C`7C defined(MSWIN))
  641. X        if (saved_ctrlZ) `7B
  642. X            *outptr++ = CTRLZ;
  643. X            ++outcnt;
  644. X        `7D
  645. X#endif /* !DOS_OS2 `7C`7C MSWIN */
  646. X    `7D
  647. X    return 0;                   /* 0:  no error */
  648. X`7D
  649. X
  650. X#endif /* !VMS */
  651. X
  652. X
  653. X
  654. X
  655. X
  656. X#if (!defined(DOS_OS2) `7C`7C defined(MSWIN))
  657. X
  658. X/***********************/
  659. X/* Function dos2unix() */
  660. X/***********************/
  661. X
  662. Xstatic int dos2unix(buf, len)   /* GRR:  rewrite for generic text conversion
  663. Vs */
  664. X    unsigned char *buf;
  665. X    int len;
  666. X`7B
  667. X    int new_len;
  668. X    int i;
  669. X#ifdef MSWIN
  670. X    unsigned char __far *walker;
  671. X#else /* !MSWIN */
  672. X    unsigned char *walker;
  673. X#endif /* ?MSWIN */
  674. X
  675. X    new_len = len;
  676. X    walker = outout;
  677. X#ifdef MACOS
  678. X    /*
  679. X     * Mac wants to strip LFs instead CRs from CRLF pairs
  680. X     */
  681. X    if (CR_flag && *buf == LF) `7B
  682. X        buf++;
  683. X        new_len--;
  684. X        len--;
  685. X        CR_flag = buf`5Blen`5D == CR;
  686. X    `7D
  687. X    else
  688. X        CR_flag = buf`5Blen - 1`5D == CR;
  689. X    for (i = 0; i < len; i += 1) `7B
  690. X        *walker++ = ascii_to_native(*buf);
  691. X        if (*buf == LF) walker`5B-1`5D = CR;
  692. X        if (*buf++ == CR && *buf == LF) `7B
  693. X            new_len--;
  694. X            buf++;
  695. X            i++;
  696. X        `7D
  697. X    `7D
  698. X#else /* !MACOS */
  699. X    if (CR_flag && *buf != LF)
  700. X        *walker++ = ascii_to_native(CR);
  701. X    CR_flag = buf`5Blen - 1`5D == CR;
  702. X    for (i = 0; i < len; i += 1) `7B
  703. X        *walker++ = ascii_to_native(*buf);
  704. X        if (*buf++ == CR && *buf == LF) `7B
  705. X            new_len--;
  706. X            walker`5B-1`5D = ascii_to_native(*buf++);
  707. X            i++;
  708. X        `7D
  709. X    `7D
  710. X    /*
  711. X     * If the last character is a CR, then "ignore it" for now...
  712. X     */
  713. X    if (walker`5B-1`5D == ascii_to_native(CR))
  714. X        new_len--;
  715. X#endif /* ?MACOS */
  716. X    return new_len;
  717. X`7D
  718. X
  719. X#endif /* !DOS_OS2 `7C`7C MSWIN */
  720. X
  721. X
  722. X
  723. X
  724. X
  725. X#ifdef __GO32__
  726. X
  727. Xvoid _dos_setftime(int fd, UWORD dosdate, UWORD dostime)
  728. X`7B
  729. X    asm("pushl %ebx");
  730. X    asm("movl %0, %%ebx": : "g" (fd));
  731. X    asm("movl %0, %%ecx": : "g" (dostime));
  732. X    asm("movl %0, %%edx": : "g" (dosdate));
  733. X    asm("movl $0x5701, %eax");
  734. X    asm("int $0x21");
  735. X    asm("popl %ebx");
  736. X`7D
  737. X
  738. Xvoid _dos_setfileattr(char *name, int attr)
  739. X`7B
  740. X    asm("movl %0, %%edx": : "g" (name));
  741. X    asm("movl %0, %%ecx": : "g" (attr));
  742. X    asm("movl $0x4301, %eax");
  743. X    asm("int $0x21");
  744. X`7D
  745. X
  746. X#endif /* __GO32__ */
  747. X
  748. X
  749. X
  750. X
  751. X
  752. X#ifdef DOS_OS2
  753. X
  754. X/**************************************/
  755. X/* Function set_file_time_and_close() */
  756. X/**************************************/
  757. X
  758. Xvoid set_file_time_and_close()
  759. X /*
  760. X  * MS-DOS AND OS/2 VERSION (Mac, Unix/VMS versions are below)
  761. X  *
  762. X  * Set the output file date/time stamp according to information from the
  763. X  * zipfile directory record for this member, then close the file and set
  764. X  * its permissions (archive, hidden, read-only, system).  Aside from closin
  765. Vg
  766. X  * the file, this routine is optional (but most compilers support it).
  767. X  */
  768. X`7B
  769. X/*--------------------------------------------------------------------------
  770. V-
  771. X    Allocate local variables needed by OS/2 and Turbo C.
  772. X  --------------------------------------------------------------------------
  773. V-*/
  774. X
  775. X#ifdef __TURBOC__
  776. X
  777. X    union `7B
  778. X        struct ftime ft;        /* system file time record */
  779. X        struct `7B
  780. X            UWORD ztime;        /* date and time words */
  781. X            UWORD zdate;        /* .. same format as in .ZIP file */
  782. X        `7D zt;
  783. X    `7D td;
  784. X
  785. X#endif                          /* __TURBOC__ */
  786. X
  787. X/*--------------------------------------------------------------------------
  788. V-
  789. X     Do not attempt to set the time stamp on standard output.
  790. X  --------------------------------------------------------------------------
  791. V-*/
  792. X
  793. X    if (cflag) `7B
  794. X        close(outfd);
  795. X        return;
  796. X    `7D
  797. X
  798. X/*--------------------------------------------------------------------------
  799. V-
  800. X    Copy and/or convert time and date variables, if necessary; then set the
  801. X    file time/date.
  802. X  --------------------------------------------------------------------------
  803. V-*/
  804. X
  805. X#ifndef OS2
  806. X#ifdef __TURBOC__
  807. X    td.zt.ztime = lrec.last_mod_file_time;
  808. X    td.zt.zdate = lrec.last_mod_file_date;
  809. X    setftime(outfd, &td.ft);
  810. X#else /* !__TURBOC__ */
  811. X#ifdef WIN32
  812. X    `7B
  813. X        FILETIME ft;     /* 64-bit value made up of two 32 bit `5Blow & high
  814. V`5D */
  815. X        WORD wDOSDate;   /* for vconvertin from DOS date to Windows NT */
  816. X        WORD wDOSTime;
  817. X        HANDLE hFile;    /* file handle (defined in Windows NT) */
  818. X
  819. X        wDOSTime = (WORD) lrec.last_mod_file_time;
  820. X        wDOSDate = (WORD) lrec.last_mod_file_date;
  821. X
  822. X        /* The DosDateTimeToFileTime() function converts a DOS date/time
  823. X         * into a 64 bit Windows NT file time */
  824. X        DosDateTimeToFileTime(wDOSDate, wDOSTime, &ft);
  825. X
  826. X        /* Close the file and then re-open it using the Win32
  827. X         * CreateFile call, so that the file can be created
  828. X         * with GENERIC_WRITE access, otherwise the SetFileTime
  829. X         * call will fail. */
  830. X        close(outfd);
  831. X
  832. X        hFile = CreateFile(filename, GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
  833. X             FILE_ATTRIBUTE_NORMAL, NULL);
  834. X
  835. X        if (!SetFileTime(hFile, NULL, NULL, &ft))
  836. X            printf("\nSetFileTime failed: %d\n", GetLastError());
  837. X        CloseHandle(hFile);
  838. X        return;
  839. X    `7D
  840. X#else /* !WIN32 */
  841. X    _dos_setftime(outfd, lrec.last_mod_file_date, lrec.last_mod_file_time);
  842. X#endif /* ?WIN32 */
  843. X#endif /* ?__TURBOC__ */
  844. X#endif /* ?OS2 */
  845. X
  846. X/*--------------------------------------------------------------------------
  847. V-
  848. X    And finally we can close the file...at least everybody agrees on how to
  849. X    do *this*.  I think...  Oh yeah, also change the mode according to the
  850. X    stored file attributes, since we didn't do that when we opened the dude.
  851. X  --------------------------------------------------------------------------
  852. V-*/
  853. X
  854. X    close(outfd);
  855. X
  856. X#ifdef OS2
  857. X    SetPathInfo(filename, lrec.last_mod_file_date,
  858. X                          lrec.last_mod_file_time, pInfo->dos_attr);
  859. X    if (extra_field)
  860. X        SetEAs(filename, extra_field);
  861. X    if (longname)
  862. X        SetLongNameEA(filename, longfilename);
  863. X#else /* !OS2 */
  864. X#ifdef __TURBOC__
  865. X    if (_chmod(filename, 1, pInfo->dos_attr) != pInfo->dos_attr)
  866. X        fprintf(stderr, "\nwarning:  file attributes may not be correct\n");
  867. X#else /* !__TURBOC__ */
  868. X#ifdef WIN32
  869. X    /* Attempt to set the file attributes.  SetFileAttributes returns
  870. X     * FALSE (0) if unsucessful, in which case print an error message,
  871. X     * with error value returned from GetLastError call. */
  872. X    pInfo->dos_attr = pInfo->dos_attr & 0x7F;
  873. X
  874. X    if (!(SetFileAttributes(filename, pInfo->dos_attr)))
  875. X        fprintf(stderr, "\nwarning (%d): could not set file attributes\n",
  876. X          GetLastError());
  877. X#else /* !WIN32 */
  878. X    _dos_setfileattr(filename, pInfo->dos_attr);
  879. X#endif /* ?WIN32 */
  880. X#endif /* ?__TURBOC__ */
  881. X#endif /* ?OS2 */
  882. X
  883. X`7D /* end function set_file_time_and_close() (DOS, OS/2) */
  884. X
  885. X
  886. X
  887. X
  888. X
  889. X#else                           /* !DOS_OS2 */
  890. X#ifdef MACOS                    /* Mac */
  891. X
  892. X/**************************************/
  893. X/* Function set_file_time_and_close() */
  894. X/**************************************/
  895. X
  896. Xvoid set_file_time_and_close()
  897. X /*
  898. X  * MAC VERSION
  899. X  */
  900. X`7B
  901. X    long m_time;
  902. X    DateTimeRec dtr;
  903. X    ParamBlockRec pbr;
  904. X    HParamBlockRec hpbr;
  905. X    OSErr err;
  906. X
  907. X    if (outfd != 1) `7B
  908. X        close(outfd);
  909. X
  910. X        /*
  911. X         * Macintosh bases all file modification times on the number of seco
  912. Vnds
  913. X         * elapsed since Jan 1, 1904, 00:00:00.  Therefore, to maintain
  914. X         * compatibility with MS-DOS archives, which date from Jan 1, 1980,
  915. X         * with NO relation to GMT, the following conversions must be made:
  916. X         *      the Year (yr) must be incremented by 1980;
  917. X         *      and converted to seconds using the Mac routine Date2Secs(),
  918. X         *      almost similar in complexity to the Unix version :-)
  919. X         *                                     J. Lee
  920. X         */
  921. X
  922. X        dtr.year = (((lrec.last_mod_file_date >> 9) & 0x7f) + 1980);
  923. X        dtr.month = ((lrec.last_mod_file_date >> 5) & 0x0f);
  924. X        dtr.day = (lrec.last_mod_file_date & 0x1f);
  925. X
  926. X        dtr.hour = ((lrec.last_mod_file_time >> 11) & 0x1f);
  927. X        dtr.minute = ((lrec.last_mod_file_time >> 5) & 0x3f);
  928. X        dtr.second = ((lrec.last_mod_file_time & 0x1f) * 2);
  929. X
  930. X        Date2Secs(&dtr, (unsigned long *)&m_time);
  931. X        CtoPstr(filename);
  932. X        if (hfsflag) `7B
  933. X            hpbr.fileParam.ioNamePtr = (StringPtr)filename;
  934. X            hpbr.fileParam.ioVRefNum = gnVRefNum;
  935. X            hpbr.fileParam.ioDirID = glDirID;
  936. X            hpbr.fileParam.ioFDirIndex = 0;
  937. X            err = PBHGetFInfo(&hpbr, 0L);
  938. X            hpbr.fileParam.ioFlMdDat = m_time;
  939. X            if ( !fMacZipped )
  940. X                hpbr.fileParam.ioFlCrDat = m_time;
  941. X            hpbr.fileParam.ioDirID = glDirID;
  942. X            if (err == noErr)
  943. X                err = PBHSetFInfo(&hpbr, 0L);
  944. X            if (err != noErr)
  945. X                printf("error:  can't set the time for %s\n", filename);
  946. X        `7D else `7B
  947. X            pbr.fileParam.ioNamePtr = (StringPtr)filename;
  948. X            pbr.fileParam.ioVRefNum = pbr.fileParam.ioFVersNum =
  949. X              pbr.fileParam.ioFDirIndex = 0;
  950. X            err = PBGetFInfo(&pbr, 0L);
  951. X            pbr.fileParam.ioFlMdDat = pbr.fileParam.ioFlCrDat = m_time;
  952. X            if (err == noErr)
  953. X                err = PBSetFInfo(&pbr, 0L);
  954. X            if (err != noErr)
  955. X                printf("error:  can't set the time for %s\n", filename);
  956. X        `7D
  957. X
  958. X        /* set read-only perms if needed */
  959. X        if ((err == noErr) && !(pInfo->unix_attr & S_IWRITE)) `7B
  960. X            if (hfsflag) `7B
  961. X                hpbr.fileParam.ioNamePtr = (StringPtr)filename;
  962. X                hpbr.fileParam.ioVRefNum = gnVRefNum;
  963. X                hpbr.fileParam.ioDirID = glDirID;
  964. X                err = PBHSetFLock(&hpbr, 0);
  965. X            `7D else
  966. X                err = SetFLock((ConstStr255Param)filename, 0);
  967. X        `7D
  968. X        PtoCstr(filename);
  969. X    `7D
  970. X`7D
  971. X
  972. X
  973. X
  974. X
  975. X
  976. X#else /* !MACOS... */
  977. X#if (!defined(MTS) && !defined(VMS))   /* && !MTS (can't do) && !VMS: only o
  978. Vne
  979. X                                  * left is UNIX (for VMS use code in vms.c)
  980. V */
  981. X
  982. X/**************************************/
  983. X/* Function set_file_time_and_close() */
  984. X/**************************************/
  985. X
  986. Xvoid set_file_time_and_close()
  987. X /*
  988. X  * UNIX VERSION (MS-DOS & OS/2, Mac versions are above)
  989. X  */
  990. X`7B
  991. X    static short yday`5B`5D=`7B0, 31, 59, 90, 120, 151, 181, 212, 243, 273,
  992. V 304, 334`7D;
  993. X    long m_time;
  994. X    int yr, mo, dy, hh, mm, ss, leap, days=0;
  995. X    struct utimbuf `7B
  996. X        time_t actime;          /* new access time */
  997. X        time_t modtime;         /* new modification time */
  998. X    `7D tp;
  999. X#ifdef AMIGA
  1000. X#   define YRBASE  1978         /* in AmigaDos, counting begins 01-Jan-1978
  1001. V */
  1002. X    struct DateStamp myadate;
  1003. X/*  extern char *_TZ;   no longer used? */
  1004. X#else /* !AMIGA */
  1005. X#   define YRBASE  1970
  1006. X#ifdef BSD
  1007. X#ifndef __386BSD__
  1008. X    static struct timeb tbp;
  1009. X#endif /* !__386BSD__ */
  1010. X#else /* !BSD */
  1011. X    extern long timezone;
  1012. X#endif /* ?BSD */
  1013. X#endif /* ?AMIGA */
  1014. X
  1015. X
  1016. X    /*
  1017. X     * Close the file *before* setting its time under Unix and AmigaDos.
  1018. X     */
  1019. X#ifdef AMIGA
  1020. X    if (cflag)                  /* can't set time on stdout */
  1021. X        return;
  1022. X    close(outfd);
  1023. X#else /* !AMIGA */
  1024. X    close(outfd);
  1025. X    if (cflag)                  /* can't set time on stdout */
  1026. X        return;
  1027. X#endif /* ?AMIGA */
  1028. X
  1029. X    /*
  1030. X     * These date conversions look a little weird, so I'll explain.
  1031. X     * UNIX bases all file modification times on the number of seconds
  1032. X     * elapsed since Jan 1, 1970, 00:00:00 GMT.  Therefore, to maintain
  1033. X     * compatibility with MS-DOS archives, which date from Jan 1, 1980,
  1034. X     * with NO relation to GMT, the following conversions must be made:
  1035. X     *      the Year (yr) must be incremented by 10;
  1036. X     *      the Date (dy) must be decremented by 1;
  1037. X     *      and the whole mess must be adjusted by TWO factors:
  1038. X     *          relationship to GMT (ie.,Pacific Time adds 8 hrs.),
  1039. X     *          and whether or not it is Daylight Savings Time.
  1040. X     * Also, the usual conversions must take place to account for leap years
  1041. V,
  1042. X     * etc.
  1043. X     *                                     C. Seaman
  1044. X     */
  1045. X
  1046. X    /* dissect date */
  1047. X    yr = ((lrec.last_mod_file_date >> 9) & 0x7f) + (1980 - YRBASE);
  1048. X    mo = ((lrec.last_mod_file_date >> 5) & 0x0f) - 1;
  1049. X    dy = (lrec.last_mod_file_date & 0x1f) - 1;
  1050. X
  1051. X    /* dissect time */
  1052. X    hh = (lrec.last_mod_file_time >> 11) & 0x1f;
  1053. X    mm = (lrec.last_mod_file_time >> 5) & 0x3f;
  1054. X    ss = (lrec.last_mod_file_time & 0x1f) * 2;
  1055. X
  1056. X    /* leap = # of leap years from BASE up to but not including current year
  1057. V */
  1058. X    leap = ((yr + YRBASE - 1) / 4);   /* leap year base factor */
  1059. X
  1060. X    /* How many days from BASE to this year? (& add expired days this year)
  1061. V */
  1062. X    days = (yr * 365) + (leap - 492) + yday`5Bmo`5D;
  1063. X
  1064. X    /* if year is a leap year and month is after February, add another day *
  1065. V/
  1066. X    if ((mo > 1) && ((yr+YRBASE)%4 == 0) && ((yr+YRBASE) != 2100))
  1067. X        ++days;                 /* OK through 2199 */
  1068. X
  1069. X#ifdef AMIGA
  1070. X/*  _TZ = getenv("TZ"); does Amiga not have TZ and tzset() after all? */
  1071. X    myadate.ds_Days   =   days+dy-2;   /* off by one? */
  1072. X    myadate.ds_Minute =   hh*60+mm;
  1073. X    myadate.ds_Tick   =   ss*TICKS_PER_SECOND;
  1074. X
  1075. X    if (!(SetFileDate(filename, &myadate)))
  1076. X        fprintf(stderr, "error:  can't set the time for %s\n", filename);
  1077. X
  1078. X#else /* !AMIGA */
  1079. X    /* convert date & time to seconds relative to 00:00:00, 01/01/YRBASE */
  1080. X    m_time = ((days + dy) * 86400) + (hh * 3600) + (mm * 60) + ss;
  1081. X
  1082. X#ifdef BSD
  1083. X#ifndef __386BSD__
  1084. X    ftime(&tbp);
  1085. X    m_time += tbp.timezone * 60L;
  1086. X#endif
  1087. X/* #elif WIN32
  1088. X * don't do anything right now (esp. since "elif" is not legal for old cc's
  1089. V */
  1090. X#else /* !BSD */
  1091. X    tzset();                    /* set `60timezone' */
  1092. X    m_time += timezone;         /* account for timezone differences */
  1093. X#endif /* ?BSD */
  1094. X
  1095. X#ifdef __386BSD__
  1096. X    m_time += localtime(&m_time)->tm_gmtoff;
  1097. X#else
  1098. X    if (localtime(&m_time)->tm_isdst)
  1099. X        m_time -= 60L * 60L;    /* adjust for daylight savings time */
  1100. X#endif
  1101. X
  1102. X    tp.actime = m_time;         /* set access time */
  1103. X    tp.modtime = m_time;        /* set modification time */
  1104. X
  1105. X    /* set the time stamp on the file */
  1106. X    if (utime(filename, &tp))
  1107. X        fprintf(stderr, "error:  can't set the time for %s\n", filename);
  1108. X#endif /* ?AMIGA */
  1109. X`7D
  1110. X
  1111. X#endif /* !MTS && !VMS */
  1112. X#endif /* ?MACOS */
  1113. X#endif /* ?DOS_OS2 */
  1114. X
  1115. X
  1116. X
  1117. X
  1118. X
  1119. X/************************/
  1120. X/*  Function handler()  */
  1121. X/************************/
  1122. X
  1123. Xvoid handler(signal)   /* upon interrupt, turn on echo and exit cleanly */
  1124. X    int signal;
  1125. X`7B
  1126. X#if (defined(SIGBUS) `7C`7C defined(SIGSEGV))
  1127. X    static char *corrupt = "error:  zipfile probably corrupt\n";
  1128. X#endif
  1129. X
  1130. X#ifndef DOS_OS2
  1131. X#ifdef CRYPT
  1132. X    echon();
  1133. X#endif /* CRYPT */
  1134. X    putc('\n', stderr);
  1135. X#endif /* !DOS_OS2 */
  1136. X#ifdef SIGBUS
  1137. X    if (signal == SIGBUS) `7B
  1138. X        fprintf(stderr, corrupt);
  1139. X        exit(3);
  1140. X    `7D
  1141. X#endif /* SIGBUS */
  1142. X#ifdef SIGSEGV
  1143. X    if (signal == SIGSEGV) `7B
  1144. X        fprintf(stderr, corrupt);
  1145. X        exit(3);
  1146. X    `7D
  1147. X#endif /* SIGSEGV */
  1148. X    exit(0);
  1149. X`7D
  1150. X
  1151. X
  1152. X
  1153. X
  1154. X
  1155. X/*******************************/
  1156. X/*  Non-echoing password code  */
  1157. X/*******************************/
  1158. X
  1159. X#ifdef CRYPT
  1160. X#ifndef DOS_OS2
  1161. X#ifdef VMS
  1162. X
  1163. Xint echo(opt)
  1164. X    int opt;
  1165. X`7B
  1166. X/*--------------------------------------------------------------------------
  1167. V-
  1168. X    Based on VMSmunch.c, which in turn was based on Joe Meadows' file.c code
  1169. V.
  1170. X  --------------------------------------------------------------------------
  1171. V-
  1172. X     * For VMS v5.x:
  1173. X     *   IO$_SENSEMODE/SETMODE info:  Programming, Vol. 7A, System Programmi
  1174. Vng,
  1175. X     *     I/O User's: Part I, sec. 8.4.1.1, 8.4.3, 8.4.5, 8.6
  1176. X     *   sys$assign(), sys$qio() info:  Programming, Vol. 4B, System Service
  1177. Vs,
  1178. X     *     System Services Reference Manual, pp. sys-23, sys-379
  1179. X     *   fixed-length descriptor info:  Programming, Vol. 3, System Services
  1180. V,
  1181. X     *     Intro to System Routines, sec. 2.9.2
  1182. X     * GRR, 15 Aug 91
  1183. X  --------------------------------------------------------------------------
  1184. V-*/
  1185. X    static struct dsc$descriptor_s DevDesc =
  1186. X        `7B9, DSC$K_DTYPE_T, DSC$K_CLASS_S, "SYS$INPUT"`7D;
  1187. X     /* `7Bdsc$w_length, dsc$b_dtype, dsc$b_class, dsc$a_pointer`7D; */
  1188. X    static short           DevChan, iosb`5B4`5D;
  1189. X    static long            i, status;
  1190. X    static unsigned long   oldmode`5B2`5D, newmode`5B2`5D;   /* each = 8 byt
  1191. Ves */
  1192. X `20
  1193. X
  1194. X/*--------------------------------------------------------------------------
  1195. V-
  1196. X    Assign a channel to standard input.
  1197. X  --------------------------------------------------------------------------
  1198. V-*/
  1199. X
  1200. X    status = sys$assign(&DevDesc, &DevChan, 0, 0);
  1201. X    if (!(status & 1))
  1202. X        return status;
  1203. X
  1204. X/*--------------------------------------------------------------------------
  1205. V-
  1206. X    Use sys$qio and the IO$_SENSEMODE function to determine the current tty
  1207. X    status (for password reading, could use IO$_READVBLK function instead,
  1208. X    but echo on/off will be more general).
  1209. X  --------------------------------------------------------------------------
  1210. V-*/
  1211. X
  1212. X    status = sys$qio(0, DevChan, IO$_SENSEMODE, &iosb, 0, 0,
  1213. X                     oldmode, 8, 0, 0, 0, 0);
  1214. X    if (!(status & 1))
  1215. X        return status;
  1216. X    status = iosb`5B0`5D;
  1217. X    if (!(status & 1))
  1218. X        return status;
  1219. X
  1220. X/*--------------------------------------------------------------------------
  1221. V-
  1222. X    Copy old mode into new-mode buffer, then modify to be either NOECHO or
  1223. X    ECHO (depending on function argument opt).
  1224. X  --------------------------------------------------------------------------
  1225. V-*/
  1226. X
  1227. X    newmode`5B0`5D = oldmode`5B0`5D;
  1228. X    newmode`5B1`5D = oldmode`5B1`5D;
  1229. X    if (opt == OFF)
  1230. X        newmode`5B1`5D `7C= TT$M_NOECHO;                      /* set NOECHO
  1231. V bit */
  1232. X    else
  1233. X        newmode`5B1`5D &= `7E((unsigned long) TT$M_NOECHO);   /* clear NOECH
  1234. VO bit */
  1235. X
  1236. X/*--------------------------------------------------------------------------
  1237. V-
  1238. X    Use the IO$_SETMODE function to change the tty status.
  1239. X  --------------------------------------------------------------------------
  1240. V-*/
  1241. X
  1242. X    status = sys$qio(0, DevChan, IO$_SETMODE, &iosb, 0, 0,
  1243. X                     newmode, 8, 0, 0, 0, 0);
  1244. X    if (!(status & 1))
  1245. X        return status;
  1246. X    status = iosb`5B0`5D;
  1247. X    if (!(status & 1))
  1248. X        return status;
  1249. X
  1250. X/*--------------------------------------------------------------------------
  1251. V-
  1252. X    Deassign the sys$input channel by way of clean-up, then exit happily.
  1253. X  --------------------------------------------------------------------------
  1254. V-*/
  1255. X
  1256. X    status = sys$dassgn(DevChan);
  1257. X    if (!(status & 1))
  1258. X        return status;
  1259. X
  1260. X    return SS$_NORMAL;   /* we be happy */
  1261. X
  1262. X`7D /* end function echo() */
  1263. X
  1264. X
  1265. X
  1266. X
  1267. X
  1268. X#else /* !VMS */
  1269. X
  1270. Xstatic int echofd=(-1);       /* file descriptor whose echo is off */
  1271. X
  1272. Xvoid echoff(f)
  1273. X    int f;                    /* file descriptor for which to turn echo off
  1274. V */
  1275. X/* Turn echo off for file descriptor f.  Assumes that f is a tty device. */
  1276. X`7B
  1277. X    struct sgttyb sg;         /* tty device structure */
  1278. X
  1279. X    echofd = f;
  1280. X    GTTY(f, &sg);             /* get settings */
  1281. X    sg.sg_flags &= `7EECHO;     /* turn echo off */
  1282. X    STTY(f, &sg);
  1283. X`7D
  1284. X
  1285. X
  1286. X
  1287. Xvoid echon()
  1288. X/* Turn echo back on for file descriptor echofd. */
  1289. X`7B
  1290. X    struct sgttyb sg;         /* tty device structure */
  1291. X
  1292. X    if (echofd != -1) `7B
  1293. X        GTTY(echofd, &sg);    /* get settings */
  1294. X        sg.sg_flags `7C= ECHO;  /* turn echo on */
  1295. X        STTY(echofd, &sg);
  1296. X        echofd = -1;
  1297. X    `7D
  1298. X`7D
  1299. X
  1300. X#endif /* ?VMS */
  1301. X#endif /* !DOS_OS2 */
  1302. X
  1303. X
  1304. X
  1305. X
  1306. X
  1307. Xchar *getp(m, p, n)
  1308. X    char *m;                  /* prompt for password */
  1309. X    char *p;                  /* return value: line input */
  1310. X    int n;                    /* bytes available in p`5B`5D */
  1311. X/* Get a password of length n-1 or less into *p using the prompt *m.
  1312. X   The entered password is not echoed.  Return p on success, NULL on
  1313. X   failure (can't get controlling tty). */
  1314. X`7B
  1315. X    char c;                   /* one-byte buffer for read() to use */
  1316. X    int i;                    /* number of characters input */
  1317. X    char *w;                  /* warning on retry */
  1318. X
  1319. X#ifndef DOS_OS2
  1320. X#ifndef VMS
  1321. X    int f;                    /* file decsriptor for tty device */
  1322. X
  1323. X    /* turn off echo on tty */
  1324. X    if (!isatty(2))
  1325. X        return NULL;          /* error if not tty */
  1326. X    if ((f = open(ttyname(2), 0, 0)) == -1)
  1327. X        return NULL;
  1328. X#endif /* !VMS */
  1329. X    echoff(f);                /* turn echo off */
  1330. X#endif /* !DOS_OS2 */
  1331. X
  1332. X    /* get password */
  1333. X    w = "";
  1334. X    do `7B
  1335. X#ifdef VMS   /* bug:  VMS adds '\n' to NULL fputs (apparently) */
  1336. X        if (*w)
  1337. X#endif /* VMS */
  1338. X            fputs(w, stderr); /* warning if back again */
  1339. X        fputs(m, stderr);     /* prompt */
  1340. X        fflush(stderr);
  1341. X        i = 0;
  1342. X        do `7B                  /* read line, keeping n */
  1343. X#ifdef MSVMS
  1344. X            if ((c = (char)getch()) == '\r')
  1345. X                c = '\n';
  1346. X#else /* !MSVMS */
  1347. X            read(f, &c, 1);
  1348. X#endif /* ?MSVMS */
  1349. X            if (i < n)
  1350. X                p`5Bi++`5D = c;
  1351. X        `7D while (c != '\n');
  1352. X        putc('\n', stderr);  fflush(stderr);
  1353. X        w = "(line too long--try again)\n";
  1354. X    `7D while (p`5Bi-1`5D != '\n');
  1355. X    p`5Bi-1`5D = 0;               /* terminate at newline */
  1356. X
  1357. X#ifndef DOS_OS2
  1358. X    echon();                  /* turn echo back on */
  1359. X#ifndef VMS
  1360. X    close(f);
  1361. X#endif /* !VMS */
  1362. X#endif /* !DOS_OS2 */
  1363. X
  1364. X    /* return pointer to password */
  1365. X    return p;
  1366. X`7D
  1367. X
  1368. X#endif /* CRYPT */
  1369. $ CALL UNPACK [.UNZIP50]FILE_IO.C;1 828092931
  1370. $ create 'f'
  1371. X.TH FUNZIP 1 "19 Aug 92 (v1.3)"
  1372. X.SH NAME
  1373. Xfunzip \- extract from a ZIP archive file as a filter
  1374. X.SH SYNOPSIS
  1375. X`5B...`5D  `7C  \fBfunzip\fP `5B password `5D  `7C  `5B...`5D
  1376. X.SH ARGUMENTS
  1377. X.IP `5B\fIpassword\fP`5D \w'`5B\fIpassword\fP`5D'u+2m
  1378. XOptional password to be used if ZIP archive is encrypted.  Decryption
  1379. Xmay not be supported at some sites.  See DESCRIPTION for more details.
  1380. X.PD
  1381. X.SH DESCRIPTION
  1382. X.I FUnZip
  1383. Xacts as a filter; that is, it assumes that a ZIP archive is being piped into
  1384. Xstandard input, and it extracts the first member from the archive to stdout.
  1385. XGiven the limitation on single-member extraction, \fIFUnZip\fP is most
  1386. Xuseful in conjunction with a secondary archiver program such as tar(1).
  1387. XThe following section includes an example illustrating this usage in the
  1388. Xcase of disk backups to tape.
  1389. X.PD
  1390. X.SH EXAMPLES
  1391. XTo use \fIFUnZip\fP to extract the first member file of the archive test.zip
  1392. Xand to pipe it into more(1):
  1393. X.PP
  1394. X.IP "\t\fIfunzip\fP < test.zip `7C more"
  1395. X.PP
  1396. XTo use \fIFUnZip\fP to test the first member file of test.zip (any errors
  1397. Xwill be reported on standard error):
  1398. X.PP
  1399. X.IP "\t\fIfunzip\fP < test.zip > /dev/null"
  1400. X.PP
  1401. XTo use \fIZip\fP and \fIFUnZip\fP in place of compress(1) and zcat(1) for
  1402. Xtape backups:
  1403. X.PP
  1404. X.IP "\ttar cf \- . `7C \fIzip\fP \-7 `7C dd of=/dev/nrst0 obs=8k"
  1405. X.IP "\tdd if=/dev/nrst0 ibs=8k `7C \fIfunzip\fP `7C tar xf \-"
  1406. X.PP
  1407. X(where, for example, nrst0 is a SCSI tape drive).
  1408. X.PD
  1409. X.SH LIMITATIONS
  1410. XThere is presently no way to extract any member but the first from a ZIP
  1411. Xarchive.  This would be useful in the case where a ZIP archive is included
  1412. Xwithin another archive.
  1413. X.PP
  1414. XAn alternate mechanism for passing the password to \fIFUnZip\fP would
  1415. Xbe preferable to putting it on the command line.
  1416. X.PP
  1417. X\fIFUnZip\fP would be useful under OS/2, too.
  1418. X.PP
  1419. XThe functionality of \fIFUnZip\fP should be included in \fIUnZip\fP
  1420. Xdirectly (future release).
  1421. X.PD
  1422. X.SH SEE ALSO
  1423. Xunzip(1), zip(1), zipcloak(1), zipinfo(1), zipnote(1), zipsplit(1)
  1424. X.PD
  1425. X.SH AUTHOR
  1426. XMark Adler (Info-ZIP)
  1427. X.PD
  1428. $ CALL UNPACK [.UNZIP50]FUNZIP.1;1 1063803495
  1429. $ create 'f'
  1430. X/* funzip.c -- Not copyrighted 1992 by Mark Adler
  1431. X   version 1.3, 16 August 1992 */
  1432. X
  1433. X
  1434. X/* You can do whatever you like with this source file, though I would
  1435. X   prefer that if you modify it and redistribute it that you include
  1436. X   comments to that effect with your name and the date.  Thank you.
  1437. X
  1438. X   History:
  1439. X   vers    date          who           what
  1440. X   ----  ---------  --------------  ------------------------------------
  1441. X    1.0  13 Aug 92  M. Adler        really simple unzip filter.
  1442. X    1.1  13 Aug 92  M. Adler        cleaned up somewhat, give help if
  1443. X                                    stdin not redirected, warn if more
  1444. X                                    zip file entries after the first.
  1445. X    1.2  15 Aug 92  M. Adler        added check of lengths for stored
  1446. X                                    entries, added more help.
  1447. X    1.3  16 Aug 92  M. Adler        removed redundant #define's, added
  1448. X                                    decryption.
  1449. X
  1450. X */
  1451. X
  1452. X
  1453. X/*
  1454. X
  1455. X   All funzip does is take a zip file from stdin and decompress the
  1456. X   first entry to stdout.  The entry has to be either deflated or
  1457. X   stored.  If the entry is encrypted, then the decryption password
  1458. X   must be supplied on the command line as the first argument.
  1459. X
  1460. X   funzip needs to be linked with inflate.o compiled from the unzip
  1461. X   source.  If decryption is desired, then it needs to be compiled
  1462. X   with -DCRYPT and linked also with crypt.o.
  1463. X
  1464. X */
  1465. X
  1466. X#include "unzip.h"
  1467. X
  1468. X/* enforce binary i/o if recognized */
  1469. X#ifdef __STDC__
  1470. X#  define FOPR "rb"
  1471. X#  define FOPW "w+b"
  1472. X#else
  1473. X#  define FOPR "r"
  1474. X#  define FOPW "w+"
  1475. X#endif
  1476. X
  1477. X/* PKZIP header definitions */
  1478. X#define LOCSIG 0x04034b50L      /* four byte lead-in (lsb first) */
  1479. X#define LOCFLG 6                /* offset of bit flag */
  1480. X#define  CRPFLG 1               /*  bit for encrypted entry */
  1481. X#define  EXTFLG 8               /*  bit for extended local header */
  1482. X#define LOCHOW 8                /* offset of compression method */
  1483. X#define LOCTIM 10               /* file mod time (for decryption) */
  1484. X#define LOCCRC 14               /* offset of crc */
  1485. X#define LOCSIZ 18               /* offset of compressed size */
  1486. X#define LOCLEN 22               /* offset of uncompressed length */
  1487. X#define LOCFIL 26               /* offset of file name field length */
  1488. X#define LOCEXT 28               /* offset of extra field length */
  1489. X#define LOCHDR 30               /* size of local header, including sig */
  1490. X#define EXTHDR 16               /* size of extended local header, inc sig */
  1491. X
  1492. X/* Macros for getting two byte and four byte header values */
  1493. X#define SH(p) ((UWORD)(byte)((p)`5B0`5D) `7C ((UWORD)(byte)((p)`5B1`5D) << 8
  1494. V))
  1495. X#define LG(p) ((ULONG)(SH(p)) `7C ((ULONG)(SH((p)+2)) << 16))
  1496. X
  1497. X/* Function prototypes */
  1498. XULONG updcrc OF((byte *, int));
  1499. Xint inflate_entry OF((void));
  1500. Xvoid err OF((int, char *));
  1501. Xvoid main OF((int, char **));
  1502. X
  1503. X/* Globals */
  1504. XFILE *in, *out;                 /* input and output files */
  1505. Xunion work area;                /* inflate sliding window */
  1506. Xbyte *outbuf;                   /* malloc'ed output buffer */
  1507. Xbyte *outptr;                   /* points to next byte in output buffer */
  1508. Xint outcnt;                     /* bytes in output buffer */
  1509. XULONG outsiz;                   /* total bytes written to out */
  1510. Xint decrypt;                    /* flag to turn on decryption */
  1511. Xchar *key;                      /* not used--needed to link crypt.c */
  1512. X
  1513. X/* Masks for inflate.c */
  1514. XUWORD mask_bits`5B`5D = `7B
  1515. X    0x0000,
  1516. X    0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
  1517. X    0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
  1518. X`7D;
  1519. X
  1520. X
  1521. X/* Table of CRC-32's of all single byte values (made by makecrc.c) */
  1522. XULONG crc_32_tab`5B`5D = `7B
  1523. X  0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
  1524. X  0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
  1525. X  0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
  1526. X  0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
  1527. X  0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
  1528. X  0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
  1529. X  0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
  1530. X  0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
  1531. X  0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
  1532. X  0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
  1533. X  0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
  1534. X  0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
  1535. X  0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
  1536. X  0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
  1537. X  0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
  1538. X  0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
  1539. X  0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
  1540. X  0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
  1541. X  0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
  1542. X  0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
  1543. X  0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
  1544. X  0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
  1545. X  0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
  1546. X  0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
  1547. X  0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
  1548. X  0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
  1549. X  0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
  1550. X  0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
  1551. X  0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
  1552. X  0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
  1553. X  0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
  1554. X  0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
  1555. X  0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
  1556. X  0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
  1557. +-+-+-+-+-+-+-+-  END  OF PART 3 +-+-+-+-+-+-+-+-
  1558.