|
|
1.1 ! root 1: /* ! 2: ! 3: Copyright (C) 1990-1992 Mark Adler, Richard B. Wales, Jean-loup Gailly, ! 4: Kai Uwe Rommel and Igor Mandrichenko. ! 5: Permission is granted to any individual or institution to use, copy, or ! 6: redistribute this software so long as all of the original files are included ! 7: unmodified, that it is not sold for profit, and that this copyright notice ! 8: is retained. ! 9: ! 10: */ ! 11: ! 12: /* ! 13: * util.c by Mark Adler. ! 14: */ ! 15: ! 16: #include "zip.h" ! 17: #include <ctype.h> ! 18: ! 19: #if defined(MSDOS) && !defined(OS2) && !defined(__GO32__) && !defined(WIN32) ! 20: # include <dos.h> ! 21: #endif ! 22: ! 23: uch upper[256], lower[256]; ! 24: /* Country-dependent case map table */ ! 25: ! 26: ! 27: #ifndef UTIL /* UTIL picks out namecmp code (all utils) and crc32 (zipcloak) */ ! 28: ! 29: /* Local functions */ ! 30: #ifdef PROTO ! 31: local int recmatch(char *, char *); ! 32: local unsigned ident(unsigned chr); ! 33: #endif /* PROTO */ ! 34: ! 35: char *isshexp(p) ! 36: char *p; /* candidate sh expression */ ! 37: /* If p is a sh expression, a pointer to the first special character is ! 38: returned. Otherwise, NULL is returned. */ ! 39: { ! 40: for (; *p; p++) ! 41: if (*p == '\\' && *(p+1)) ! 42: p++; ! 43: #ifdef VMS ! 44: else if (*p == '%' || *p == '*') ! 45: #else /* !VMS */ ! 46: else if (*p == '?' || *p == '*' || *p == '[') ! 47: #endif /* ?VMS */ ! 48: return p; ! 49: return NULL; ! 50: } ! 51: ! 52: ! 53: local int recmatch(p, s) ! 54: char *p; /* sh pattern to match */ ! 55: char *s; /* string to match it to */ ! 56: /* Recursively compare the sh pattern p with the string s and return 1 if ! 57: they match, and 0 or 2 if they don't or if there is a syntax error in the ! 58: pattern. This routine recurses on itself no deeper than the number of ! 59: characters in the pattern. */ ! 60: { ! 61: int c; /* pattern char or start of range in [-] loop */ ! 62: ! 63: /* Get first character, the pattern for new recmatch calls follows */ ! 64: c = *p++; ! 65: ! 66: /* If that was the end of the pattern, match if string empty too */ ! 67: if (c == 0) ! 68: return *s == 0; ! 69: ! 70: /* '?' (or '%') matches any character (but not an empty string) */ ! 71: #ifdef VMS ! 72: if (c == '%') ! 73: #else /* !VMS */ ! 74: if (c == '?') ! 75: #endif /* ?VMS */ ! 76: return *s ? recmatch(p, s + 1) : 0; ! 77: ! 78: /* '*' matches any number of characters, including zero */ ! 79: if (c == '*') ! 80: { ! 81: if (*p == 0) ! 82: return 1; ! 83: for (; *s; s++) ! 84: if ((c = recmatch(p, s)) != 0) ! 85: return c; ! 86: return 2; /* 2 means give up--shmatch will return false */ ! 87: } ! 88: ! 89: #ifndef VMS /* No bracket matching in VMS */ ! 90: /* Parse and process the list of characters and ranges in brackets */ ! 91: if (c == '[') ! 92: { ! 93: int e; /* flag true if next char to be taken literally */ ! 94: char *q; /* pointer to end of [-] group */ ! 95: int r; /* flag true to match anything but the range */ ! 96: ! 97: if (*s == 0) /* need a character to match */ ! 98: return 0; ! 99: p += (r = *p == '!'); /* see if reverse */ ! 100: for (q = p, e = 0; *q; q++) /* find closing bracket */ ! 101: if (e) ! 102: e = 0; ! 103: else ! 104: if (*q == '\\') ! 105: e = 1; ! 106: else if (*q == ']') ! 107: break; ! 108: if (*q != ']') /* nothing matches if bad syntax */ ! 109: return 0; ! 110: for (c = 0, e = *p == '-'; p < q; p++) /* go through the list */ ! 111: { ! 112: if (e == 0 && *p == '\\') /* set escape flag if \ */ ! 113: e = 1; ! 114: else if (e == 0 && *p == '-') /* set start of range if - */ ! 115: c = *(p-1); ! 116: else ! 117: { ! 118: if (*(p+1) != '-') ! 119: for (c = c ? c : *p; c <= *p; c++) /* compare range */ ! 120: if (case_map(c) == case_map(*s)) ! 121: return r ? 0 : recmatch(q + 1, s + 1); ! 122: c = e = 0; /* clear range, escape flags */ ! 123: } ! 124: } ! 125: return r ? recmatch(q + 1, s + 1) : 0; /* bracket match failed */ ! 126: } ! 127: #endif /* !VMS */ ! 128: ! 129: /* If escape ('\'), just compare next character */ ! 130: if (c == '\\') ! 131: if ((c = *p++) == 0) /* if \ at end, then syntax error */ ! 132: return 0; ! 133: ! 134: /* Just a character--compare it */ ! 135: return case_map(c) == case_map(*s) ? recmatch(p, ++s) : 0; ! 136: } ! 137: ! 138: ! 139: int shmatch(p, s) ! 140: char *p; /* sh pattern to match */ ! 141: char *s; /* string to match it to */ ! 142: /* Compare the sh pattern p with the string s and return true if they match, ! 143: false if they don't or if there is a syntax error in the pattern. */ ! 144: { ! 145: return recmatch(p, s) == 1; ! 146: } ! 147: ! 148: ! 149: #ifdef MSDOS ! 150: ! 151: int dosmatch(p, s) ! 152: char *p; /* dos pattern to match */ ! 153: char *s; /* string to match it to */ ! 154: /* Break the pattern and string into name and extension parts and match ! 155: each separately using shmatch(). */ ! 156: { ! 157: char *p1, *p2; /* pattern sections */ ! 158: char *s1, *s2; /* string sections */ ! 159: int r; /* result */ ! 160: ! 161: if ((p1 = malloc(strlen(p) + 1)) == NULL || ! 162: (s1 = malloc(strlen(s) + 1)) == NULL) ! 163: { ! 164: if (p1 != NULL) ! 165: free((voidp *)p1); ! 166: return 0; ! 167: } ! 168: strcpy(p1, p); ! 169: strcpy(s1, s); ! 170: if ((p2 = strrchr(p1, '.')) != NULL) ! 171: *p2++ = 0; ! 172: else ! 173: p2 = ""; ! 174: if ((s2 = strrchr(s1, '.')) != NULL) ! 175: *s2++ = 0; ! 176: else ! 177: s2 = ""; ! 178: r = shmatch(p2, s2) && shmatch(p1, s1); ! 179: free((voidp *)p1); ! 180: free((voidp *)s1); ! 181: return r; ! 182: } ! 183: #endif /* MSDOS */ ! 184: ! 185: voidp far **search(b, a, n, cmp) ! 186: voidp *b; /* pointer to value to search for */ ! 187: voidp far **a; /* table of pointers to values, sorted */ ! 188: extent n; /* number of pointers in a[] */ ! 189: int (*cmp) OF((voidp *, voidp far *)); /* comparison function for search */ ! 190: /* Search for b in the pointer list a[0..n-1] using the compare function ! 191: cmp(b, c) where c is an element of a[i] and cmp() returns negative if ! 192: *b < *c, zero if *b == *c, or positive if *b > *c. If *b is found, ! 193: search returns a pointer to the entry in a[], else search() returns ! 194: NULL. The nature and size of *b and *c (they can be different) are ! 195: left up to the cmp() function. A binary search is used, and it is ! 196: assumed that the list is sorted in ascending order. */ ! 197: { ! 198: voidp far **i; /* pointer to midpoint of current range */ ! 199: voidp far **l; /* pointer to lower end of current range */ ! 200: int r; /* result of (*cmp)() call */ ! 201: voidp far **u; /* pointer to upper end of current range */ ! 202: ! 203: l = (voidp far **)a; u = l + (n-1); ! 204: while (u >= l) ! 205: if ((r = (*cmp)(b, *(i = l + ((u - l) >> 1)))) < 0) ! 206: u = i - 1; ! 207: else if (r > 0) ! 208: l = i + 1; ! 209: else ! 210: return (voidp far **)i; ! 211: return NULL; /* If b were in list, it would belong at l */ ! 212: } ! 213: ! 214: #endif /* !UTIL */ ! 215: ! 216: ! 217: /* Table of CRC-32's of all single byte values (made by makecrc.c) */ ! 218: local ulg crctab[] = { ! 219: 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, ! 220: 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, ! 221: 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, ! 222: 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, ! 223: 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, ! 224: 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, ! 225: 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, ! 226: 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, ! 227: 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, ! 228: 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, ! 229: 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, ! 230: 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, ! 231: 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, ! 232: 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, ! 233: 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, ! 234: 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, ! 235: 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, ! 236: 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, ! 237: 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, ! 238: 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, ! 239: 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, ! 240: 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, ! 241: 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, ! 242: 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, ! 243: 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, ! 244: 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, ! 245: 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, ! 246: 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, ! 247: 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, ! 248: 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, ! 249: 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, ! 250: 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, ! 251: 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, ! 252: 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, ! 253: 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, ! 254: 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, ! 255: 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, ! 256: 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, ! 257: 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, ! 258: 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, ! 259: 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, ! 260: 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, ! 261: 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, ! 262: 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, ! 263: 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, ! 264: 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, ! 265: 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, ! 266: 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, ! 267: 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, ! 268: 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, ! 269: 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, ! 270: 0x2d02ef8dL ! 271: }; ! 272: ! 273: ! 274: ulg crc32(c, b) ! 275: ulg c; /* current contents of crc shift register */ ! 276: int b; /* byte (eight bits) to run through */ ! 277: /* Return the CRC-32 c updated with the eight bits in b. */ ! 278: { ! 279: return crctab[((int)c ^ b) & 0xff] ^ (c >> 8); ! 280: } ! 281: ! 282: ! 283: #ifndef UTIL /* UTIL picks out namecmp code (all utils) and crc32 (zipcloak) */ ! 284: ! 285: ulg updcrc(s, n) ! 286: char *s; /* pointer to bytes to pump through */ ! 287: extent n; /* number of bytes in s[] */ ! 288: /* Run a set of bytes through the crc shift register. If s is a NULL ! 289: pointer, then initialize the crc shift register contents instead. ! 290: Return the current crc in either case. */ ! 291: { ! 292: register ulg c; /* temporary variable */ ! 293: ! 294: static ulg crc = 0xffffffffL; /* shift register contents */ ! 295: ! 296: if (s == NULL) ! 297: c = 0xffffffffL; ! 298: else ! 299: { ! 300: c = crc; ! 301: while (n--) ! 302: c = crctab[((int)c ^ (*s++)) & 0xff] ^ (c >> 8); ! 303: } ! 304: crc = c; ! 305: return c ^ 0xffffffffL; /* (instead of ~c for 64-bit machines) */ ! 306: } ! 307: ! 308: #endif /* !UTIL */ ! 309: ! 310: ! 311: #if (defined(MSDOS) && !defined(OS2) && !defined(__GO32__) && !defined(WIN32)) ! 312: ! 313: local unsigned ident(unsigned chr) ! 314: { ! 315: return chr; /* in al */ ! 316: } ! 317: ! 318: void init_upper() ! 319: { ! 320: static struct country { ! 321: uch ignore[18]; ! 322: int (far *casemap)(int); ! 323: uch filler[16]; ! 324: } country_info; ! 325: ! 326: struct country far *info = &country_info; ! 327: union REGS regs; ! 328: struct SREGS sregs; ! 329: int c; ! 330: ! 331: regs.x.ax = 0x3800; /* get country info */ ! 332: regs.x.dx = FP_OFF(info); ! 333: sregs.ds = FP_SEG(info); ! 334: intdosx(®s, ®s, &sregs); ! 335: for (c = 0; c < 128; c++) { ! 336: upper[c] = (uch) toupper(c); ! 337: lower[c] = (uch) c; ! 338: } ! 339: for (; c < sizeof(upper); c++) { ! 340: upper[c] = (uch) (*country_info.casemap)(ident(c)); ! 341: /* ident() required because casemap takes its parameter in al */ ! 342: lower[c] = (uch) c; ! 343: } ! 344: for (c = 0; c < sizeof(upper); c++ ) { ! 345: int u = upper[c]; ! 346: if (u != c && lower[u] == (uch) u) { ! 347: lower[u] = (uch)c; ! 348: } ! 349: } ! 350: for (c = 'A'; c <= 'Z'; c++) { ! 351: lower[c] = (uch) (c - 'A' + 'a'); ! 352: } ! 353: } ! 354: #else ! 355: # ifndef OS2 ! 356: ! 357: void init_upper() ! 358: { ! 359: int c; ! 360: for (c = 0; c < sizeof(upper); c++) upper[c] = lower[c] = c; ! 361: for (c = 'a'; c <= 'z'; c++) upper[c] = c - 'a' + 'A'; ! 362: for (c = 'A'; c <= 'Z'; c++) lower[c] = c - 'A' + 'a'; ! 363: } ! 364: # endif /* OS2 */ ! 365: ! 366: #endif /* MSDOS && !__GO32__ && !OS2 */ ! 367: ! 368: int namecmp(string1, string2) ! 369: char *string1, *string2; ! 370: /* Compare the two strings ignoring case, and correctly taking into ! 371: * account national language characters. For operating systems with ! 372: * case sensitive file names, this function is equivalent to strcmp. ! 373: */ ! 374: { ! 375: int d; ! 376: ! 377: for (;;) ! 378: { ! 379: d = (int) (unsigned char) case_map(*string1) ! 380: - (int) (unsigned char) case_map(*string2); ! 381: ! 382: if (d || *string1 == 0 || *string2 == 0) ! 383: return d; ! 384: ! 385: string1++; ! 386: string2++; ! 387: } ! 388: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.