home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 9 Archive / 09-Archive.zip / zip22.zip / qdos / qdos.c < prev    next >
C/C++ Source or Header  |  1997-10-15  |  19KB  |  867 lines

  1. /*
  2.  * Yes this  file is necessary; the QDOS file system is the most
  3.  * ludicrous known to man (even more so that VMS!).
  4.  */
  5.  
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include <sys/stat.h>
  10. #include <fcntl.h>
  11. #include <dirent.h>
  12. #include <unistd.h>
  13.  
  14. #include "zip.h"
  15. #include "crypt.h"
  16. #include "ttyio.h"
  17.  
  18. #ifdef QDOS
  19.  
  20. # include <qdos.h>
  21.  
  22. #if CRYPT
  23.  
  24. char *getp(m, p, n)
  25.     ZCONST char *m;              /* prompt for password */
  26.     char *p;                    /* return value: line input */
  27.     int n;                      /* bytes available in p[] */
  28. {
  29.     int c;                      /* one-byte buffer for read() to use */
  30.     int i;                      /* number of characters input */
  31.     char *w;                    /* warning on retry */
  32.  
  33.     /* get password */
  34.     w = "";
  35.     sd_cure(getchid(0), -1);    /* enable cursor */
  36.     do {
  37.         fputs(w, stderr);       /* warning if back again */
  38.         fputs(m, stderr);       /* display prompt and flush */
  39.         fflush(stderr);
  40.         i = 0;
  41.         do {
  42.             c = getch();
  43.             if (c == 0xc2) {
  44.                 if (i > 0) {
  45.                     i--; /* the `del' keys works */
  46.                     fputs("\b \b", stderr);
  47.                 }
  48.             }
  49.             else if (i < n) {
  50.                 p[i++] = c;     /* truncate past n */
  51.                 if(c != '\n') putc('*', stderr);
  52.             }
  53.         } while (c != '\n');
  54.  
  55.         putc('\n', stderr);  fflush(stderr);
  56.         w = "(line too long--try again)\n";
  57.     } while (p[i-1] != '\n');
  58.  
  59.     p[i-1] = 0;                 /* terminate at newline */
  60.     sd_curs(getchid(0), -1);    /* suppress cursor */
  61.     return p;                   /* return pointer to password */
  62.  
  63. } /* end function getp() */
  64.  
  65. #endif /* CRYPT */
  66.  
  67.  
  68. #define MATCH shmatch
  69. #define __attribute__(p)
  70.  
  71. int newname(char *, int);
  72.  
  73. #else /* !QDOS */
  74. #define QDOS_FLMAX 36
  75.  
  76. short qlflag = 0;
  77.  
  78. struct qdirect  {
  79.     long            d_length __attribute__ ((packed));  /* file length */
  80.     unsigned char   d_access __attribute__ ((packed));  /* file access type */
  81.     unsigned char   d_type __attribute__ ((packed));    /* file type */
  82.     long            d_datalen __attribute__ ((packed)); /* data length */
  83.     long            d_reserved __attribute__ ((packed));/* Unused */
  84.     short           d_szname __attribute__ ((packed));  /* size of name */
  85.     char            d_name[QDOS_FLMAX] __attribute__ ((packed));/* name area */
  86.     long            d_update __attribute__ ((packed));  /* last update */
  87.     long            d_refdate __attribute__ ((packed));
  88.     long            d_backup __attribute__ ((packed));   /* EOD */
  89.     } ;
  90. #endif /* ?QDOS */
  91.  
  92. #define SHORTID 0x4afb          /* in big-endian order !! */
  93. #define LONGID  "QDOS02"
  94. #define EXTRALEN (sizeof(struct qdirect) + 8)
  95.  
  96. typedef struct
  97. {
  98.     unsigned short shortid __attribute__ ((packed));
  99.     struct
  100.     {
  101.         unsigned char lo __attribute__ ((packed));
  102.         unsigned char hi __attribute__ ((packed));
  103.     } len __attribute__ ((packed));
  104.     char        longid[8] __attribute__ ((packed));
  105.     struct      qdirect     header __attribute__ ((packed));
  106. } qdosextra;
  107.  
  108. #ifdef USE_EF_UT_TIME
  109. local int GetExtraTime(struct zlist far *z, iztimes *z_utim, unsigned ut_flg);
  110. #endif
  111.  
  112. #ifdef QDOS
  113.  
  114. #define rev_short(x) (x)
  115. #define rev_long(x) (x)
  116.  
  117. char _prog_name[] = "zip";
  118. char _copyright[] = "(c) Info-ZIP Group";
  119. long _stack = 16*1024;
  120. char *  _endmsg = NULL;
  121.  
  122. extern void consetup_title(chanid_t,struct WINDOWDEF *);
  123. void (*_consetup)(chanid_t,struct WINDOWDEF *) = consetup_title;
  124.  
  125. struct WINDOWDEF _condetails =
  126. {
  127.     2,
  128.     1,
  129.     0,
  130.     7,
  131.     500,
  132.     220,
  133.     2,
  134.     30
  135. };
  136.  
  137. extern short qlwait;
  138. extern short dtype;
  139.  
  140. #define CHECKDIR(p1) (((p1).d_type == dtype) && (((p1).d_length % 64) == 0))
  141.  
  142. char * stpcpy (char *d, ZCONST char *s)
  143. {
  144.     while(*d++ = *s++)
  145.         ; /* Null loop */
  146.     return d-1;
  147. }
  148.  
  149. static jobid_t chowner(chanid_t chan)
  150. {
  151.     extern char *_sys_var;
  152.     char *scht;
  153.     long *cdb;
  154.     long jid;
  155.  
  156.     scht = *((char **)(_sys_var + 0x78));
  157.     cdb = *(long **)((long *)scht  + (chan & 0xffff));
  158.     jid = *(cdb + 2);
  159.     return jid;
  160. }
  161.  
  162. void QDOSexit(void)
  163. {
  164.     jobid_t me,you;
  165.  
  166.     me = getpid();
  167.     you = chowner(getchid(0));
  168.  
  169.     if((me == you) && ((qlflag & 4) == 0))
  170.     {
  171.         if(isatty(0) && isatty(2) && qlwait)
  172.         {
  173.             char c = 0;
  174.             fputs("Press a key to exit", stderr);
  175.             if((io_fbyte(getchid(0), qlwait, &c) == 0) && c == 27)
  176.             {
  177.                 io_fbyte(getchid(0), -1, &c);
  178.             }
  179.         }
  180.     }
  181.     exit(0);
  182. }
  183.  
  184. /* Access seems to be *always* broken in c68 */
  185. /* Not accurate, just works */
  186.  
  187. int access (char *f, int mode)
  188. {
  189.     struct stat st;
  190.     int fd;
  191.  
  192.     if((fd = stat(f, &st)) == 0)
  193.     {
  194.         switch(fd)
  195.         {
  196.         case F_OK:
  197.             break;
  198.         case R_OK:
  199.             fd = (st.st_mode & 0444) == 0;
  200.             break;
  201.         case W_OK:
  202.             fd = (st.st_mode & 0222) == 0;
  203.             break;
  204.         case X_OK:
  205.             fd = (st.st_mode & 0111) == 0;
  206.             break;
  207.         default:
  208.             fd = -1;
  209.             break;
  210.         }
  211.     }
  212.     return fd;
  213. }
  214.  
  215. /* Fixup a Mickey Mouse file naming system */
  216.  
  217. char * Unix2ql (char *qlname, char **dot)
  218. {
  219.     static char path[64];
  220.     char name[64];
  221.     char *q, *r, *s;
  222.  
  223.     strcpy(name, qlname);
  224.     if(*name == '~')
  225.     {
  226.         r = name+1;
  227.         getcwd(path, sizeof(path));
  228.         q = path + strlen(path);
  229.         if(*(q-1) != '_')
  230.         {
  231.             *q++ = '_';
  232.         }
  233.     }
  234.     else
  235.     {
  236.         q = path;
  237.         r = name;
  238.     }
  239.  
  240.     if(*r == '/')
  241.     {
  242.         r++;
  243.     }
  244.  
  245.     strcpy(q, r);
  246.  
  247.     while (*q)
  248.     {
  249.         if(*q == '/' || *q == '.')
  250.         {
  251.             if(*q == '.' && dot)
  252.             {
  253.                 *dot = name + (q - path);
  254.             }
  255.             *q = '_';
  256.         }
  257.  
  258.         q++;
  259.     }
  260.     return path;
  261. }
  262.  
  263. #if 0                                 /* Not used in ZIP */
  264.  
  265. GuessAltName(char *name, char *dot)
  266. {
  267.     if(dot)
  268.     {
  269.         *dot = '.';
  270.     }
  271.     else
  272.     {
  273.         if((dot = strrchr(name, '_')))
  274.         {
  275.             *dot = '.';
  276.         }
  277.     }
  278. }
  279.  
  280. #endif /* 0 */
  281.  
  282. short devlen(char *p)
  283. {
  284.     char defpath[40];
  285.     short deflen = 0, ok = 0;
  286.  
  287.     getcwd(defpath, sizeof(defpath));
  288.     deflen = strlen(defpath);
  289.     if(deflen)
  290.     {
  291.         if(strnicmp(p, defpath, deflen) == 0)
  292.         {
  293.             ok = 1;
  294.         }
  295.     }
  296.  
  297.     if(!ok)
  298.     {
  299.         if(isdirdev(p))
  300.         {
  301.             deflen = 5;
  302.         }
  303.         else
  304.         {
  305.             deflen = 0;
  306.         }
  307.     }
  308.     return deflen;
  309. }
  310.  
  311. char * ql2Unix (char *qlname)
  312. {
  313.     struct stat st;
  314.     int sts;
  315.     char *p, *r, *s, *ldp;
  316.     char *pnam = NULL;
  317.     static char path[64];
  318.     short  deflen;
  319.     char name[64];
  320.  
  321.     strcpy(name, qlname);
  322.     strcpy(path, name);
  323.  
  324.     deflen = devlen(qlname);
  325.  
  326.     p = name + deflen;
  327.     pnam = path + deflen;
  328.  
  329.     if(s = strrchr(p, '_'))
  330.     {
  331.         *s = 0;
  332.         sts = stat(name, &st);
  333.         if(deflen && sts ==0 && (st.st_mode & S_IFDIR))
  334.         {
  335.             *(path+(s-name)) = '/';
  336.         }
  337.         else
  338.         {
  339.             *(path+(s-name)) = '.';
  340.         }
  341.     }
  342.  
  343.     ldp = p;
  344.     for(r = p; *r; r++)
  345.     {
  346.         if(r != ldp && *r == '_')
  347.         {
  348.             *r = 0;
  349.             if(deflen)
  350.             {
  351.                 sts = stat(name, &st);
  352.             }
  353.             else
  354.                 sts = -1;
  355.  
  356.             if(sts ==0 && (st.st_mode & S_IFDIR))
  357.             {
  358.                 *(path+(r-name)) = '/';
  359.                 ldp = r + 1;
  360.             }
  361.             else
  362.             {
  363.                 *(path+(r-name)) = '_';
  364.             }
  365.             *r = '_';
  366.         }
  367.     }
  368.     return pnam;
  369. }
  370.  
  371. char *LastDir(char *ws)
  372. {
  373.     char *p;
  374.     char *q = ws;
  375.     struct stat s;
  376.  
  377.     for(p = ws; *p; p++)
  378.     {
  379.         if(p != ws && *p == '_')
  380.         {
  381.             char c;
  382.  
  383.             p++;
  384.             c = *p;
  385.             *p = 0;
  386.             if(stat(ws, &s) == 0 && S_ISDIR(s.st_mode))
  387.             {
  388.                 q = p;
  389.             }
  390.             *p = c;
  391.         }
  392.     }
  393.     return q;
  394. }
  395.  
  396. # ifndef UTIL
  397.  
  398. static int add_dir(char * dnam)
  399. {
  400.     int e = ZE_OK;
  401.     char *p;
  402.     short nlen;
  403.  
  404.     nlen = strlen(dnam);
  405.     if(p = malloc(nlen + 2))
  406.     {
  407.         strncpy (p, dnam, nlen);
  408.         if(*(p+nlen) != '_')
  409.         {
  410.             *(p+nlen) = '_';
  411.             *(p+nlen+1) = '\0';
  412.         }
  413.         if ((e = newname(p, 1)) != ZE_OK)
  414.         {
  415.                 free(p);
  416.         }
  417.     }
  418.     else
  419.     {
  420.         e = ZE_MEM;
  421.     }
  422.     return e;
  423. }
  424.  
  425. int qlwild (char *dnam, short dorecurse, short l)
  426. {
  427.     static char match[40] = {0};
  428.     static char ddev[8] =  {0};
  429.     static short nc;
  430.     static short llen;
  431.     static char base[40];
  432.  
  433.     int chid;
  434.     struct qdirect qd;
  435.     char *dp;
  436.     int e = ZE_MISS;
  437.  
  438.     if (l == 0)
  439.     {
  440.         nc = 0;
  441.         *base = '\0';
  442.         if (isdirdev (dnam))
  443.         {
  444.             dp = dnam;
  445.             strncpy (ddev, dnam, 5);
  446.         }
  447.         else
  448.         {
  449.  
  450.             char *p;
  451.             char temp[40];
  452.  
  453.             getcwd (temp, 40);
  454.  
  455.             llen = strlen(temp);
  456.             p = (temp + llen - 1);
  457.             if (*p != '_')
  458.             {
  459.                 *p++ = '_';
  460.                 *p = 0;
  461.             }
  462.  
  463.             strncpy (ddev, temp, 5);
  464.             dp = base;
  465.             p = stpcpy (dp, temp);
  466.             strcpy (p, dnam);
  467.         }
  468.  
  469.         {
  470.             char *q = isshexp (dp);
  471.             if(q)
  472.             {
  473.                 strcpy (match, dp + 5);
  474.                 if (q)
  475.                 {
  476.                     while (q != dp && *q != '_')
  477.                     {
  478.                         q--;
  479.                     }
  480.                     *(++q) = '\0';
  481.                 }
  482.             }
  483.             else
  484.             {
  485.                 struct stat s;
  486.                 if (stat(dp, &s) == 0)
  487.                 {
  488.                     if (!(s.st_mode & S_IFDIR))
  489.                     {
  490.                         return procname(dp);
  491.                     }
  492.                 }
  493.                 else
  494.                 {
  495.                     return ZE_MISS;  /* woops, no wildcards! */
  496.                 }
  497.             }
  498.  
  499.         }
  500.     }
  501.     else
  502.     {
  503.         dp = dnam;
  504.     }
  505.  
  506.     if ((chid = io_open (dp, 4L)) > 0)
  507.     {
  508.         int id = 0;
  509.         while (io_fstrg (chid, -1, &qd, 64) > 0)
  510.         {
  511.             short j;
  512.  
  513.             if (qd.d_szname)
  514.             {
  515.                 if (CHECKDIR(qd))
  516.                 {
  517.                     if(dorecurse)
  518.                     {
  519.                         char fnam[256], *p;
  520.  
  521.                         p = stpcpy (fnam, ddev);
  522.                         strncpy (p, qd.d_name, qd.d_szname);
  523.                         *(p + qd.d_szname) = 0;
  524.                         e = qlwild (fnam, dorecurse, l+1);
  525.                     }
  526.                     else
  527.                     {
  528.                         continue;
  529.                     }
  530.                 }
  531.                 else
  532.                 {
  533.                     char nam[48];
  534.                     strcpy(nam, ddev);
  535.  
  536.                     strncpy (nam + 5, qd.d_name, qd.d_szname);
  537.                     *(nam + 5 + qd.d_szname) = 0;
  538.  
  539.                     if (MATCH (match, nam + 5) == 1)
  540.                     {
  541.                         if(dirnames && l && id == 0)
  542.                         {
  543.                             id = 1;
  544.                             if((e = add_dir(dp)) != ZE_OK)
  545.                             {
  546.                                 return e;
  547.                             }
  548.                         }
  549.  
  550.                         if((e = procname(nam)) == ZE_OK)
  551.                         {
  552.                             nc++;
  553.                         }
  554.                     }
  555.                 }
  556.             }
  557.         }
  558.         io_close (chid);
  559.     }
  560.  
  561.     if (l == 0)
  562.     {
  563.         *ddev = 0;
  564.         *match = 0;
  565.         e = (nc) ? ZE_OK : ZE_MISS;
  566.     }
  567.     return e;
  568.  
  569. }
  570.  
  571. int wild(char *p)
  572. {
  573.     return qlwild(p, recurse, 0);
  574. }
  575. # endif /* !UTIL */
  576.  
  577. /*
  578.  * Return QDOS error, 0 if exec 1 if found but not exe or rel
  579.  */
  580. int qlstat(char *name, struct qdirect *qs, char *flag)
  581. {
  582.     int r;
  583.     r = qstat(name, qs);
  584.     if(r == 0)
  585.     {
  586.         if(qs->d_type == 0)
  587.         {
  588.             r = 1;
  589.         }
  590.         else if(CHECKDIR(*qs))
  591.         {
  592.             r = 255;
  593.         }
  594.     }
  595.     return r;
  596. }
  597.  
  598. #else /* !QDOS */
  599.  
  600. long rev_long (ulg l)
  601. {
  602.     uch cc[4];
  603.     cc[0] = (uch)(l >> 24);
  604.     cc[1] = (uch)((l >> 16) & 0xff);
  605.     cc[2] = (uch)((l >> 8) & 0xff);
  606.     cc[3] = (uch)(l & 0xff);
  607.     return *(ulg *)cc;
  608. }
  609.  
  610. short rev_short (ush s)
  611. {
  612.     uch cc[2];
  613.     cc[0] = (uch)((s >> 8) & 0xff);
  614.     cc[1] = (uch)(s & 0xff);
  615.     return *(ush *)cc;
  616. }
  617.  
  618. #define O_BINARY 0
  619.  
  620. int qlstat(char *name, struct qdirect *qs, char *flag)
  621. {
  622.     int r = -1;
  623.     int n, fd;
  624.     struct stat s;
  625.     struct _ntc_
  626.     {
  627.         long id;
  628.         long dlen;
  629.     } ntc;
  630.  
  631.     *flag = 0;
  632.     if((fd = open(name, O_RDONLY | O_BINARY)) > 0)
  633.     {
  634.         short nl;
  635.  
  636.         fstat(fd, &s);
  637.         lseek(fd, -8, SEEK_END);
  638.         read(fd, &ntc, 8);
  639.         qs->d_length = rev_long(s.st_size);
  640.         qs->d_update = rev_long(s.st_ctime + 283996800);
  641.  
  642.     nl = strlen(name);
  643.     if(nl > QDOS_FLMAX)
  644.     {
  645.         nl = QDOS_FLMAX;
  646.         *flag = 1;
  647.     }
  648.     qs->d_szname = rev_short(nl);
  649.     memcpy(qs->d_name, name, nl);
  650.     
  651.         if(ntc.id == *(long *)"XTcc")
  652.         {
  653.             qs->d_datalen = ntc.dlen;    /* This is big endian */
  654.             qs->d_type = 1;
  655.             r = 0;
  656.         }
  657.         else
  658.         {
  659.             qs->d_type = 0;
  660.             qs->d_datalen = 0;
  661.             r = 1;
  662.         }
  663.         close(fd);
  664.         return r;
  665.     }
  666.     else
  667.     {
  668.         fprintf(stderr, "Fails %d\n", fd);
  669.         return r;
  670.     }
  671. }
  672.  
  673. #endif /* ?QDOS */
  674.  
  675. #ifdef USE_EF_UT_TIME
  676.  
  677. #define EB_L_UT_SIZE    (EB_HEADSIZE + eb_l_ut_len)
  678. #define EB_C_UT_SIZE    (EB_HEADSIZE + eb_c_ut_len)
  679.  
  680. #ifdef UNIX
  681. #define EB_L_UX2_SIZE     (EB_HEADSIZE + EB_UX2_MINLEN)
  682. #define EB_C_UX2_SIZE     EB_HEADSIZE
  683. #define EF_L_UT_UX2_SIZE  (EB_L_UT_SIZE + EB_L_UX2_SIZE)
  684. #define EF_C_UT_UX2_SIZE  (EB_C_UT_SIZE + EB_C_UX2_SIZE)
  685. #else
  686. #define EF_L_UT_UX2_SIZE  EB_L_UT_SIZE
  687. #define EF_C_UT_UX2_SIZE  EB_C_UT_SIZE
  688. #endif
  689.  
  690. local int GetExtraTime(struct zlist far *z, iztimes *z_utim, unsigned ut_flg)
  691. {
  692.   char *eb_l_ptr;
  693.   char *eb_c_ptr;
  694.   char *eb_pt;
  695.   extent eb_l_ut_len = 0;
  696.   extent eb_c_ut_len = 0;
  697.  
  698. #ifdef UNIX
  699.   struct stat s;
  700.  
  701.   /* For the full sized UT local field including the UID/GID fields, we
  702.    * have to stat the file, again.  */
  703.   if (stat(z->name, &s))
  704.     return ZE_OPEN;
  705.   /* update times in z_utim, stat() call might have changed atime... */
  706.   z_utim->mtime = s.st_mtime;
  707.   z_utim->atime = s.st_atime;
  708.   z_utim->ctime = s.st_mtime;   /* best guess (st_ctime != creation time) */
  709. #endif /* UNIX */
  710.  
  711.   if (ut_flg != 0) {
  712.     if (ut_flg & EB_UT_FL_MTIME)
  713.       eb_l_ut_len = eb_c_ut_len = 1;
  714.     if (ut_flg & EB_UT_FL_ATIME)
  715.       eb_l_ut_len++;
  716.     if (ut_flg & EB_UT_FL_CTIME)
  717.       eb_l_ut_len++;
  718.  
  719.     eb_l_ut_len = EB_UT_LEN(eb_l_ut_len);
  720.     eb_c_ut_len = EB_UT_LEN(eb_c_ut_len);
  721.   }
  722.  
  723.   if (EF_L_UT_UX2_SIZE > 0) {
  724.     if(z->ext)
  725.       eb_l_ptr = realloc(z->extra, (z->ext + EF_L_UT_UX2_SIZE));
  726.     else
  727.       eb_l_ptr = malloc(EF_L_UT_UX2_SIZE);
  728.  
  729.     if (eb_l_ptr == NULL)
  730.       return ZE_MEM;
  731.  
  732.     if(z->cext)
  733.       eb_c_ptr = realloc(z->cextra, (z->cext + EF_C_UT_UX2_SIZE));
  734.     else
  735.       eb_c_ptr = malloc(EF_C_UT_UX2_SIZE);
  736.  
  737.     if (eb_c_ptr == NULL)
  738.       return ZE_MEM;
  739.  
  740.     z->extra = eb_l_ptr;
  741.     eb_l_ptr += z->ext;
  742.     z->ext += EF_L_UT_UX2_SIZE;
  743.  
  744.     if (ut_flg != 0) {
  745.       eb_l_ptr[0]  = 'U';
  746.       eb_l_ptr[1]  = 'T';
  747.       eb_l_ptr[2]  = eb_l_ut_len;       /* length of data part of e.f. */
  748.       eb_l_ptr[3]  = 0;
  749.       eb_l_ptr[4]  = ut_flg;
  750.       eb_pt = eb_l_ptr + 5;
  751.       if (ut_flg & EB_UT_FL_MTIME) {
  752.         *eb_pt++ = (char)(z_utim->mtime);
  753.         *eb_pt++ = (char)(z_utim->mtime >> 8);
  754.         *eb_pt++ = (char)(z_utim->mtime >> 16);
  755.         *eb_pt++ = (char)(z_utim->mtime >> 24);
  756.       }
  757.       if (ut_flg & EB_UT_FL_ATIME) {
  758.         *eb_pt++ = (char)(z_utim->atime);
  759.         *eb_pt++ = (char)(z_utim->atime >> 8);
  760.         *eb_pt++ = (char)(z_utim->atime >> 16);
  761.         *eb_pt++ = (char)(z_utim->atime >> 24);
  762.       }
  763.       if (ut_flg & EB_UT_FL_CTIME) {
  764.         *eb_pt++ = (char)(z_utim->ctime);
  765.         *eb_pt++ = (char)(z_utim->ctime >> 8);
  766.         *eb_pt++ = (char)(z_utim->ctime >> 16);
  767.         *eb_pt++ = (char)(z_utim->ctime >> 24);
  768.       }
  769.     }
  770. #ifdef UNIX
  771.     else {
  772.       eb_pt = eb_l_ptr;
  773.     }
  774.     *eb_pt++ = 'U';
  775.     *eb_pt++ = 'x';
  776.     *eb_pt++ = EB_UX2_MINLEN;            /* length of data part of local e.f. */
  777.     *eb_pt++  = 0;
  778.     *eb_pt++ = (char)(s.st_uid);
  779.     *eb_pt++ = (char)(s.st_uid >> 8);
  780.     *eb_pt++ = (char)(s.st_gid);
  781.     *eb_pt++ = (char)(s.st_gid >> 8);
  782. #endif /* UNIX */
  783.  
  784.     z->cextra = eb_c_ptr;
  785.     eb_c_ptr += z->cext;
  786.     z->cext += EF_C_UT_UX2_SIZE;
  787.  
  788.     if (ut_flg != 0) {
  789.       memcpy(eb_c_ptr, eb_l_ptr, EB_C_UT_SIZE);
  790.       eb_c_ptr[EB_LEN] = eb_c_ut_len;
  791.     }
  792. #ifdef UNIX
  793.     memcpy(eb_c_ptr+EB_C_UT_SIZE, eb_l_ptr+EB_L_UT_SIZE, EB_C_UX2_SIZE);
  794.     eb_c_ptr[EB_LEN+EB_C_UT_SIZE] = 0;
  795. #endif /* UNIX */
  796.   }
  797.  
  798.   return ZE_OK;
  799. }
  800.  
  801. #endif /* USE_EF_UT_TIME */
  802.  
  803.  
  804. int set_extra_field (struct zlist *z, iztimes *z_utim )
  805. {
  806.     int rv = 0;
  807.     int last_rv = 0;
  808.     char flag = 0;
  809.  
  810.     if ((qlflag & 3) != 1)
  811.     {
  812.         qdosextra       *lq, *cq;
  813.         if ((lq = (qdosextra *) calloc(sizeof(qdosextra), 1)) == NULL)
  814.             return ZE_MEM;
  815.         if ((cq = (qdosextra *) calloc(sizeof(qdosextra), 1)) == NULL)
  816.             return ZE_MEM;
  817.  
  818.         rv = qlstat(z->name, &(lq->header), &flag);
  819.  
  820.         if (rv == 0 || (rv == 1 && (qlflag & 2)))
  821.         {
  822.             lq->shortid = rev_short((short) SHORTID);
  823.             lq->len.lo  = (unsigned char)(EXTRALEN & 0xff);
  824.             lq->len.hi  = (unsigned char)(EXTRALEN >> 8);
  825.             strcpy(lq->longid, LONGID);
  826.  
  827.             memcpy(cq, lq, sizeof(qdosextra));
  828.  
  829.             z->ext      =   sizeof(qdosextra);
  830.             z->cext     =   sizeof(qdosextra);
  831.             z->extra    =   (void *) lq;
  832.             z->cextra   =   (void *) cq;
  833.             fprintf (stderr, " %c",
  834.                      lq->header.d_datalen ? '*' : '#');
  835.         }
  836.         else if (rv == -1)
  837.         {
  838.             fprintf(stderr,
  839.                     "%s: warning: cannot stat %s, no file header added\n",
  840.                     "zip", z->name);
  841.         }
  842.         if(flag)
  843.         {
  844.             fputs (" !", stderr);
  845.         }
  846.      }
  847.     last_rv = (rv == -1 ? ZE_OPEN : ZE_OK);
  848.  
  849. #ifdef USE_EF_UT_TIME
  850. # ifdef QDOS
  851. #   define IZ_UT_FLAGS EB_UT_FL_MTIME
  852. # endif
  853. # ifdef UNIX
  854. #   define IZ_UT_FLAGS (EB_UT_FL_MTIME | EB_UT_FL_ATIME)
  855. # endif
  856. # ifndef IZ_UT_FLAGS
  857. #   define IZ_UT_FLAGS EB_UT_FL_MTIME
  858. # endif
  859.  
  860.     rv = GetExtraTime(z, z_utim, IZ_UT_FLAGS);
  861.     if (rv != ZE_OK)
  862.         last_rv = rv;
  863. #endif /* USE_EF_UT_TIME */
  864.  
  865.     return last_rv;
  866. }
  867.