qdos.c 19 KB

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