helpers.c
上传用户:andy_li
上传日期:2007-01-06
资源大小:1019k
文件大小:10k
源码类别:

压缩解压

开发平台:

MultiPlatform

  1. /*---------------------------------------------------------------------------
  2.   helpers.c
  3.   Some useful functions Used by unzip and zip.
  4.   ---------------------------------------------------------------------------*/
  5. /*****************************************************************************/
  6. /*  Includes                                                                 */
  7. /*****************************************************************************/
  8. #include "zip.h"
  9. #include <ctype.h>
  10. #include <time.h>
  11. #include "macstuff.h"
  12. #include "helpers.h"
  13. #include "pathname.h"
  14. /*****************************************************************************/
  15. /*  Global Vars                                                              */
  16. /*****************************************************************************/
  17. extern int noisy;
  18. extern char MacPathEnd;
  19. extern char *zipfile;   /* filename of the Zipfile */
  20. extern char *tempzip;   /* Temporary zip file name */
  21. static char         argStr[1024];
  22. static char         *argv[MAX_ARGS + 1];
  23. /*****************************************************************************/
  24. /*  Prototypes                                                               */
  25. /*****************************************************************************/
  26. /*****************************************************************************/
  27. /*  Macros, typedefs                                                         */
  28. /*****************************************************************************/
  29.   /*
  30.    * ARGH.  Mac times are based on 1904 Jan 1 00:00, not 1970 Jan 1 00:00.
  31.    *  So we have to diddle time_t's appropriately:  add or subtract 66 years'
  32.    *  worth of seconds == number of days times 86400 == (66*365 regular days +
  33.    *  17 leap days ) * 86400 == (24090 + 17) * 86400 == 2082844800L seconds.
  34.    *  We hope time_t is an unsigned long (ulg) on the Macintosh...
  35.    */
  36. /*
  37. This Offset is only used by MacFileDate_to_UTime()
  38. */
  39. #define NATIVE_TO_STATS(x)  (x) -= (unsigned long)2082844800L
  40. /*****************************************************************************/
  41. /*  Functions                                                                */
  42. /*****************************************************************************/
  43. /*
  44. **  Copy a C string to a Pascal string
  45. **
  46. */
  47. unsigned char *CToPCpy(unsigned char *pstr, char *cstr)
  48. {
  49.     register char *dptr;
  50.     register unsigned len;
  51.         len=0;
  52.         dptr=(char *)pstr+1;
  53.     while (len<255 && (*dptr++ = *cstr++)!='') ++len;
  54.     *pstr= (unsigned char)len;
  55.   return pstr;
  56. }
  57. /*
  58. **  Copy a Pascal string to a C string
  59. **
  60. */
  61. char *PToCCpy(unsigned char *pstr, char *cstr)
  62. {
  63. strncpy(cstr, (char *) &pstr[1], *pstr);
  64.     cstr[pstr[0]] = '';  /* set endmarker for c-string */
  65. return cstr;
  66. }
  67. /*
  68. **  Alloc memory and init it
  69. **
  70. */
  71. char *StrCalloc(unsigned short size)
  72. {
  73. char *strPtr = NULL;
  74. if ((strPtr = calloc(size, sizeof(char))) == NULL)
  75.     printerr("StrCalloc failed:", -1, size, __LINE__, __FILE__, "");
  76. return strPtr;
  77. }
  78. /*
  79. **  Release only non NULL pointers
  80. **
  81. */
  82. char *StrFree(char *strPtr)
  83. {
  84. if (strPtr != NULL)
  85.     {
  86.     free(strPtr);
  87.     }
  88. return NULL;
  89. }
  90. /*
  91. **  Return a value in a binary string
  92. **
  93. */
  94. char *sBit2Str(unsigned short value)
  95. {
  96. short pos = 0;
  97. static char str[sizeof(value)*8];
  98. memset(str, '0', sizeof(value)*8);  /* set string-buffer */
  99. for (pos = sizeof(value)*8; pos != 0; value >>= 1)
  100.     {
  101.     if (value & 01)
  102.         str[pos] = '1';
  103.     else str[pos] = '0';
  104.     pos--;
  105.     }
  106. str[(sizeof(value)*8)+1] = '';
  107. return str;
  108. }
  109. /*
  110. **  Parse commandline style arguments
  111. **
  112. */
  113. int ParseArguments(char *s, char ***arg)
  114. {
  115.     int  n = 1, Quote = 0;
  116.     char *p = s, *p1, c;
  117.     argv[0] = GetAppName();
  118.     *arg = argv;
  119.     p1 = (char *) argStr;
  120.     while ((c = *p++) != 0) {
  121.         if (c==' ') continue;
  122.         argv[n++] = p1;
  123.         if (n > MAX_ARGS)               /* mm 970404 */
  124.             return (n-1);               /* mm 970404 */
  125.         do {
  126.             if (c=='\' && *p++)
  127.                 c = *p++;
  128.             else
  129.                 if ((c=='"') || (c == ''')) {
  130.                     if (!Quote) {
  131.                         Quote = c;
  132.                         continue;
  133.                     }
  134.                     if (c == Quote) {
  135.                         Quote = 0;
  136.                         continue;
  137.                     }
  138.                 }
  139.             *p1++ = c;
  140.         } while (*p && ((c = *p++) != ' ' || Quote));
  141.         *p1++ = '';
  142.     }
  143.     return n;
  144. }
  145. /*
  146. **  Print commandline style arguments
  147. **
  148. */
  149. void PrintArguments(int argc, char **argv)
  150. {
  151. printf("n Arguments:");
  152. printf("n --------------------------");
  153. while(--argc >= 0)
  154.     printf("n argc: %d  argv: [%s]", argc, &*argv[argc]);
  155. printf("n --------------------------nn");
  156. return;
  157. }
  158. /*
  159. **  return some error-msg on file-system
  160. **
  161. */
  162. int PrintUserHFSerr(int cond, int err, char *msg2)
  163. {
  164. char *msg;
  165. if (cond != 0)
  166.     {
  167.     switch (err)
  168.         {
  169.          case -35:
  170.             msg = "No such Volume";
  171.          break;
  172.          case -56:
  173.             msg = "No such Drive";
  174.          break;
  175.          case -37:
  176.             msg = "Bad Volume Name";
  177.          break;
  178.          case -49:
  179.             msg = "File is already open for writing";
  180.          break;
  181.          case -43:
  182.             msg = "Directory/File not found";
  183.          break;
  184.          case -120:
  185.             msg = "Directory/File not found or incomplete pathname";
  186.          break;
  187.         default: return err;
  188.          }
  189.     fprintf(stderr, "nn Error: %s ->%s", msg, msg2);
  190.     exit(err);
  191.     }
  192. return 0;
  193. }
  194. /*
  195. **  Check mounted volumes and return number of volumes
  196. **  with the same name.
  197. */
  198. short CheckMountedVolumes(char *FullPath)
  199. {
  200. FSSpec  volumes[50];        /* 50 Volumes should be enough */
  201. char VolumeName[257], volume[257];
  202. short actVolCount, volIndex = 1, VolCount = 0;
  203. OSErr err;
  204. int i;
  205. GetVolumeFromPath(FullPath, VolumeName);
  206. err = OnLine(volumes, 50, &actVolCount, &volIndex);
  207. printerr("OnLine:", (err != -35) && (err != 0), err, __LINE__, __FILE__, "");
  208. for (i=0; i < actVolCount; i++)
  209.     {
  210.     PToCCpy(volumes[i].name,volume);
  211.     if (stricmp(volume, VolumeName) == 0) VolCount++;
  212.     }
  213. printerr("OnLine: ", (VolCount == 0), VolCount, __LINE__, __FILE__, FullPath);
  214. return VolCount;
  215. }
  216. /*
  217. **  compares strings, ignoring differences in case
  218. **
  219. */
  220. int stricmp(const char *p1, const char *p2)
  221. {
  222. int diff;
  223. while (*p1 && *p2)
  224.     {
  225.     if (*p1 != *p2)
  226.         {
  227.         if (isalpha(*p1) && isalpha(*p2))
  228.             {
  229.             diff = toupper(*p1) - toupper(*p2);
  230.             if (diff) return diff;
  231.             }
  232.             else break;
  233.         }
  234.         p1++;
  235.         p2++;
  236.     }
  237. return *p1 - *p2;
  238. }
  239. /*
  240. **  creates an archive file name
  241. **
  242. */
  243. void createArchiveName(char *thePath)
  244. {
  245. char *tmpPtr;
  246. short folderCount = 0;
  247. char name[256];
  248. unsigned short pathlen = strlen(thePath);
  249. for (tmpPtr = thePath; *tmpPtr; tmpPtr++)
  250.     if (*tmpPtr == ':') folderCount++;
  251. if (folderCount > 1) { /* path contains at least one folder */
  252.     if (pathlen <= 30) thePath[pathlen-2] = 0x0;
  253.     else thePath[pathlen-4] = 0x0;
  254. strcat(thePath,".zip");
  255. } else {  /* path contains no folder */
  256.     strcpy(name, thePath);
  257.     FindDesktopFolder(thePath);
  258.     if (pathlen <= 30) name[pathlen-2] = 0x0;
  259.     else name[pathlen-4] = 0x0;
  260. strcat(thePath,name);
  261. strcat(thePath,".zip");
  262. }
  263. }
  264. /*
  265. ** finds the desktop-folder on a volume with
  266. ** largest amount of free-space.
  267. */
  268. void FindDesktopFolder(char *Path)
  269. {
  270. FSSpec  volumes[50];        /* 50 Volumes should be enough */
  271. short   actVolCount, volIndex = 1, VolCount = 0;
  272. OSErr   err;
  273. short     i, foundVRefNum;
  274. FSSpec spec;
  275. UnsignedWide freeBytes;
  276. UnsignedWide totalBytes;
  277. UnsignedWide MaxFreeBytes;
  278. err = OnLine(volumes, 50, &actVolCount, &volIndex);
  279. printerr("OnLine:", (err != -35) && (err != 0), err, __LINE__, __FILE__, "");
  280. MaxFreeBytes.hi = 0;
  281. MaxFreeBytes.lo = 0;
  282. for (i=0; i < actVolCount; i++)
  283.     {
  284.     XGetVInfo(volumes[i].vRefNum,
  285.               volumes[i].name,
  286.   &volumes[i].vRefNum,
  287.   &freeBytes,
  288.   &totalBytes);
  289. if (MaxFreeBytes.hi < freeBytes.hi) {
  290. MaxFreeBytes.hi = freeBytes.hi;
  291. MaxFreeBytes.lo = freeBytes.lo;
  292. foundVRefNum = volumes[i].vRefNum;
  293. printf("n1 Path: %s n", Path);
  294. }
  295. if ((freeBytes.hi == 0) && (MaxFreeBytes.lo < freeBytes.lo)) {
  296. MaxFreeBytes.hi = freeBytes.hi;
  297. MaxFreeBytes.lo = freeBytes.lo;
  298. foundVRefNum = volumes[i].vRefNum;
  299. }
  300. }
  301.  FSpFindFolder(foundVRefNum, kDesktopFolderType,
  302.             kDontCreateFolder,&spec);
  303.  GetFullPathFromSpec(Path, &spec , &err);
  304. }
  305. #if (defined(USE_SIOUX) || defined(MACUNZIP_STANDALONE))
  306. /*
  307. **  checks the condition and returns an error-msg
  308. **  this function is for internal use only
  309. */
  310. OSErr printerr(const char *msg, int cond, int err, int line, char *file,
  311.               const char *msg2)
  312. {
  313. if (cond != 0)
  314.     {
  315.     fprintf(stderr, "nint err: %d: %s %d [%d/%s] {%s}n", clock(), msg, err,
  316.             line, file, msg2);
  317.     }
  318. return cond;
  319. }
  320. /*
  321. fake-functions:
  322. Not Implemented for metrowerks SIOUX
  323. */
  324. void leftStatusString(char *status)
  325. {
  326. status = status;
  327. }
  328. void rightStatusString(char *status)
  329. {
  330. status = status;
  331. }
  332. void DoWarnUserDupVol( char *FullPath )
  333. {
  334.   char VolName[257];
  335.   GetVolumeFromPath(FullPath,  VolName);
  336.   printf("n There are more than one volume that has the same name !!n");
  337.   printf("n Volume: %sn",VolName);
  338.   printf("n This port has one weak point:");
  339.   printf("n It is based on pathnames. As you may be already know:");
  340.   printf("n Pathnames are not unique on a Mac !");
  341.   printf("n MacZip has problems to find the correct location of");
  342.   printf("n the archive or the files.n");
  343.   printf("n My (Big) recommendation:  Name all your volumes with an");
  344.   printf("n unique name and MacZip will run without any problem.");
  345. }
  346. #endif