human68k.c 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  1. /*
  2. Copyright (c) 1990-1999 Info-ZIP. All rights reserved.
  3. See the accompanying file LICENSE, version 1999-Oct-05 or later
  4. (the contents of which are also included in zip.h) for terms of use.
  5. If, for some reason, both of these files are missing, the Info-ZIP license
  6. also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html
  7. */
  8. #include "zip.h"
  9. #include <time.h>
  10. #include <stdio.h>
  11. #include <dirent.h>
  12. #ifndef UTIL
  13. #include <sys/dos.h>
  14. #endif
  15. #define MATCH shmatch
  16. #define PAD 0
  17. #ifndef UTIL
  18. /* Library functions not in (most) header files */
  19. int utime OF((char *, ztimbuf *));
  20. /* Local functions */
  21. local char *readd OF((DIR *));
  22. local char *readd(DIR* d)
  23. {
  24. struct dirent* e = readdir(d);
  25. return e == NULL ? NULL : e->d_name;
  26. }
  27. int wild(char* w)
  28. {
  29. struct _filbuf inf;
  30. /* convert FNAMX to malloc - 11/08/04 EG */
  31. char *name;
  32. char *p;
  33. if (strcmp(w, "-") == 0) /* if compressing stdin */
  34. return newname(w, 0, 0);
  35. if ((name = malloc(strlen(w) + 1)) == NULL) {
  36. ZIPERR(ZE_MEM, "wild");
  37. }
  38. strcpy(name, w);
  39. _toslash(name);
  40. if ((p = strrchr(name, '/')) == NULL && (p = strrchr(name, ':')) == NULL)
  41. p = name;
  42. else
  43. p++;
  44. if (_dos_lfiles (&inf, w, 0xff) < 0) {
  45. free(name);
  46. return ZE_MISS;
  47. }
  48. do {
  49. int r;
  50. strcpy(p, inf.name);
  51. r = procname(name, 0);
  52. if (r != ZE_OK) {
  53. free(name);
  54. return r;
  55. }
  56. } while (_dos_nfiles(&inf) >= 0);
  57. free(name);
  58. return ZE_OK;
  59. }
  60. int procname(n, caseflag)
  61. char *n; /* name to process */
  62. int caseflag; /* true to force case-sensitive match */
  63. /* Process a name or sh expression to operate on (or exclude). Return
  64. an error code in the ZE_ class. */
  65. {
  66. char *a; /* path and name for recursion */
  67. DIR *d; /* directory stream from opendir() */
  68. char *e; /* pointer to name from readd() */
  69. int m; /* matched flag */
  70. char *p; /* path for recursion */
  71. struct stat s; /* result of stat() */
  72. struct zlist far *z; /* steps through zfiles list */
  73. if (strcmp(n, "-") == 0) /* if compressing stdin */
  74. return newname(n, 0, caseflag);
  75. else if (LSSTAT(n, &s))
  76. {
  77. /* Not a file or directory--search for shell expression in zip file */
  78. p = ex2in(n, 0, (int *)NULL); /* shouldn't affect matching chars */
  79. m = 1;
  80. for (z = zfiles; z != NULL; z = z->nxt) {
  81. if (MATCH(p, z->iname, caseflag))
  82. {
  83. z->mark = pcount ? filter(z->zname, caseflag) : 1;
  84. if (verbose)
  85. fprintf(mesg, "zip diagnostic: %scluding %s\n",
  86. z->mark ? "in" : "ex", z->name);
  87. m = 0;
  88. }
  89. }
  90. free((zvoid *)p);
  91. return m ? ZE_MISS : ZE_OK;
  92. }
  93. /* Live name--use if file, recurse if directory */
  94. _toslash(n);
  95. if ((s.st_mode & S_IFDIR) == 0)
  96. {
  97. /* add or remove name of file */
  98. if ((m = newname(n, 0, caseflag)) != ZE_OK)
  99. return m;
  100. } else {
  101. /* Add trailing / to the directory name */
  102. if ((p = malloc(strlen(n)+2)) == NULL)
  103. return ZE_MEM;
  104. if (strcmp(n, ".") == 0) {
  105. *p = '\0'; /* avoid "./" prefix and do not create zip entry */
  106. } else {
  107. strcpy(p, n);
  108. a = p + strlen(p);
  109. if (a[-1] != '/')
  110. strcpy(a, "/");
  111. if (dirnames && (m = newname(p, 1, caseflag)) != ZE_OK) {
  112. free((zvoid *)p);
  113. return m;
  114. }
  115. }
  116. /* recurse into directory */
  117. if (recurse && (d = opendir(n)) != NULL)
  118. {
  119. while ((e = readd(d)) != NULL) {
  120. if (strcmp(e, ".") && strcmp(e, ".."))
  121. {
  122. if ((a = malloc(strlen(p) + strlen(e) + 1)) == NULL)
  123. {
  124. closedir(d);
  125. free((zvoid *)p);
  126. return ZE_MEM;
  127. }
  128. strcat(strcpy(a, p), e);
  129. if ((m = procname(a, caseflag)) != ZE_OK) /* recurse on name */
  130. {
  131. if (m == ZE_MISS)
  132. zipwarn("name not matched: ", a);
  133. else
  134. ziperr(m, a);
  135. }
  136. free((zvoid *)a);
  137. }
  138. }
  139. closedir(d);
  140. }
  141. free((zvoid *)p);
  142. } /* (s.st_mode & S_IFDIR) == 0) */
  143. return ZE_OK;
  144. }
  145. char *ex2in(x, isdir, pdosflag)
  146. char *x; /* external file name */
  147. int isdir; /* input: x is a directory */
  148. int *pdosflag; /* output: force MSDOS file attributes? */
  149. /* Convert the external file name to a zip file name, returning the malloc'ed
  150. string or NULL if not enough memory. */
  151. {
  152. char *n; /* internal file name (malloc'ed) */
  153. char *t; /* shortened name */
  154. /* Find starting point in name before doing malloc */
  155. t = (x[0] && x[1] == (char)':') ? x + 2 : x;
  156. while (*t == (char)'/')
  157. t++;
  158. /* Make changes, if any, to the copied name (leave original intact) */
  159. _toslash(t);
  160. if (!pathput)
  161. t = last(t, '/');
  162. /* Malloc space for internal name and copy it */
  163. if ((n = malloc(strlen(t) + 1)) == NULL)
  164. return NULL;
  165. strcpy(n, t);
  166. if (dosify)
  167. msname(n);
  168. /* Returned malloc'ed name */
  169. if (pdosflag)
  170. *pdosflag = dosify;
  171. return n;
  172. }
  173. char *in2ex(n)
  174. char *n; /* internal file name */
  175. /* Convert the zip file name to an external file name, returning the malloc'ed
  176. string or NULL if not enough memory. */
  177. {
  178. char *x; /* external file name */
  179. if ((x = malloc(strlen(n) + 1 + PAD)) == NULL)
  180. return NULL;
  181. return strcpy(x, n);
  182. }
  183. void stamp(f, d)
  184. char *f; /* name of file to change */
  185. ulg d; /* dos-style time to change it to */
  186. /* Set last updated and accessed time of file f to the DOS time d. */
  187. {
  188. ztimbuf u; /* argument for utime() */
  189. /* Convert DOS time to time_t format in u */
  190. u.actime = u.modtime = dos2unixtime(d);
  191. /* Set updated and accessed times of f */
  192. utime(f, &u);
  193. }
  194. ulg filetime(f, a, n, t)
  195. char *f; /* name of file to get info on */
  196. ulg *a; /* return value: file attributes */
  197. long *n; /* return value: file size */
  198. iztimes *t; /* return value: access, modific. and creation times */
  199. /* If file *f does not exist, return 0. Else, return the file's last
  200. modified date and time as an MSDOS date and time. The date and
  201. time is returned in a long with the date most significant to allow
  202. unsigned integer comparison of absolute times. Also, if a is not
  203. a NULL pointer, store the file attributes there, with the high two
  204. bytes being the Unix attributes, and the low byte being a mapping
  205. of that to DOS attributes. If n is not NULL, store the file size
  206. there. If t is not NULL, the file's access, modification and creation
  207. times are stored there as UNIX time_t values.
  208. If f is "-", use standard input as the file. If f is a device, return
  209. a file size of -1 */
  210. {
  211. struct stat s; /* results of stat() */
  212. /* convert FNMAX to malloc - 11/8/04 EG */
  213. char *name;
  214. int len = strlen(f);
  215. isstdin = !strcmp(f, "-");
  216. if ((name = malloc(len + 1)) == NULL) {
  217. ZIPERR(ZE_MEM, "filetime");
  218. }
  219. strcpy(name, f);
  220. if (name[len - 1] == '/')
  221. name[len - 1] = '\0';
  222. /* not all systems allow stat'ing a file with / appended */
  223. if (isstdin) {
  224. if (fstat(fileno(stdin), &s) != 0) {
  225. free(name);
  226. error("fstat(stdin)");
  227. }
  228. } else if (LSSTAT(name, &s) != 0) {
  229. /* Accept about any file kind including directories
  230. * (stored with trailing / with -r option)
  231. */
  232. free(name);
  233. return 0;
  234. }
  235. if (a != NULL) {
  236. int atr = _dos_chmod(name, -1);
  237. if (atr < 0)
  238. atr = 0x20;
  239. *a = ((ulg)s.st_mode << 16) | (isstdin ? 0L : (ulg)atr);
  240. }
  241. free(name);
  242. if (n != NULL)
  243. *n = S_ISVOL(s.st_mode) ? -2L : S_ISREG(s.st_mode) ? s.st_size : -1L;
  244. if (t != NULL) {
  245. t->atime = s.st_atime;
  246. t->mtime = s.st_mtime;
  247. t->ctime = s.st_ctime;
  248. }
  249. return unix2dostime(&s.st_mtime);
  250. }
  251. int set_extra_field(z, z_utim)
  252. struct zlist far *z;
  253. iztimes *z_utim;
  254. /* create extra field and change z->att if desired */
  255. {
  256. #ifdef USE_EF_UT_TIME
  257. if ((z->extra = (char *)malloc(EB_HEADSIZE+EB_UT_LEN(1))) == NULL)
  258. return ZE_MEM;
  259. z->extra[0] = 'U';
  260. z->extra[1] = 'T';
  261. z->extra[2] = EB_UT_LEN(1); /* length of data part of e.f. */
  262. z->extra[3] = 0;
  263. z->extra[4] = EB_UT_FL_MTIME;
  264. z->extra[5] = (char)(z_utim->mtime);
  265. z->extra[6] = (char)(z_utim->mtime >> 8);
  266. z->extra[7] = (char)(z_utim->mtime >> 16);
  267. z->extra[8] = (char)(z_utim->mtime >> 24);
  268. z->cext = z->ext = (EB_HEADSIZE+EB_UT_LEN(1));
  269. z->cextra = z->extra;
  270. return ZE_OK;
  271. #else /* !USE_EF_UT_TIME */
  272. return (int)(z-z);
  273. #endif /* ?USE_EF_UT_TIME */
  274. }
  275. int deletedir(d)
  276. char *d; /* directory to delete */
  277. /* Delete the directory *d if it is empty, do nothing otherwise.
  278. Return the result of rmdir(), delete(), or system().
  279. For VMS, d must be in format [x.y]z.dir;1 (not [x.y.z]).
  280. */
  281. {
  282. return rmdir(d);
  283. }
  284. void print_period(void)
  285. {
  286. fputc('.', stderr);
  287. }
  288. #endif /* !UTIL */
  289. /******************************/
  290. /* Function version_local() */
  291. /******************************/
  292. void version_local()
  293. {
  294. static ZCONST char CompiledWith[] = "Compiled with %s%s for %s%s%s%s.\n\n";
  295. #if 0
  296. char buf[40];
  297. #endif
  298. printf(CompiledWith,
  299. #ifdef __GNUC__
  300. "gcc ", __VERSION__,
  301. #else
  302. # if 0
  303. "cc ", (sprintf(buf, " version %d", _RELEASE), buf),
  304. # else
  305. "unknown compiler", "",
  306. # endif
  307. #endif
  308. "Human68k",
  309. #ifdef __MC68020__
  310. " (X68030)",
  311. #else
  312. " (X680x0)",
  313. #endif
  314. #ifdef __DATE__
  315. " on ", __DATE__
  316. #else
  317. "", ""
  318. #endif
  319. );
  320. } /* end function version_local() */