1 /*
2   Copyright (c) 1990-2001 Info-ZIP.  All rights reserved.
3 
4   See the accompanying file LICENSE, version 2000-Apr-09 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 
11   helpers.c
12 
13   Some useful functions Used by unzip and zip.
14 
15   ---------------------------------------------------------------------------*/
16 
17 /*****************************************************************************/
18 /*  Includes                                                                 */
19 /*****************************************************************************/
20 
21 #include "zip.h"
22 #include <ctype.h>
23 #include <time.h>
24 #include <sound.h>
25 
26 #include "macstuff.h"
27 #include "helpers.h"
28 #include "pathname.h"
29 
30 
31 /*****************************************************************************/
32 /*  Global Vars                                                              */
33 /*****************************************************************************/
34 
35 
36 extern int noisy;
37 extern char MacPathEnd;
38 extern char *zipfile;   /* filename of the Zipfile */
39 extern char *tempzip;   /* Temporary zip file name */
40 extern ZCONST unsigned char MacRoman_to_WinCP1252[128];
41 
42 
43 static char         argStr[1024];
44 static char         *argv[MAX_ARGS + 1];
45 
46 
47 
48 /*****************************************************************************/
49 /*  Functions                                                                */
50 /*****************************************************************************/
51 
52 
53 /*
54 **  Copy a C string to a Pascal string
55 **
56 */
57 
CToPCpy(unsigned char * pstr,char * cstr)58 unsigned char *CToPCpy(unsigned char *pstr, char *cstr)
59 {
60     register char *dptr;
61     register unsigned len;
62 
63         len=0;
64         dptr=(char *)pstr+1;
65     while (len<255 && (*dptr++ = *cstr++)!='\0') ++len;
66     *pstr= (unsigned char)len;
67   return pstr;
68 }
69 
70 
71 /*
72 **  Copy a Pascal string to a C string
73 **
74 */
75 
PToCCpy(unsigned char * pstr,char * cstr)76 char *PToCCpy(unsigned char *pstr, char *cstr)
77 {
78 strncpy(cstr, (char *) &pstr[1], *pstr);
79     cstr[pstr[0]] = '\0';  /* set endmarker for c-string */
80 return cstr;
81 }
82 
83 
84 /*
85 **  strcpy() and strcat() work-alikes which allow overlapping buffers.
86 */
87 
sstrcpy(char * to,const char * from)88 char *sstrcpy(char *to,const char *from)
89 {
90     memmove(to, from, 1+strlen(from));
91     return to;
92 }
93 
sstrcat(char * to,const char * from)94 char *sstrcat(char *to,const char *from)
95 {
96     sstrcpy(to + strlen(to), from);
97     return to;
98 }
99 
100 
101 
102 /*
103 **  Alloc memory and init it
104 **
105 */
106 
StrCalloc(unsigned short size)107 char *StrCalloc(unsigned short size)
108 {
109 char *strPtr = NULL;
110 
111 if ((strPtr = calloc(size, sizeof(char))) == NULL)
112     printerr("StrCalloc failed:", -1, size, __LINE__, __FILE__, "");
113 
114 Assert_it(strPtr,"strPtr == NULL","")
115 return strPtr;
116 }
117 
118 
119 
120 /*
121 **  Release only non NULL pointers
122 **
123 */
124 
StrFree(char * strPtr)125 char *StrFree(char *strPtr)
126 {
127 
128 if (strPtr != NULL)
129     {
130     free(strPtr);
131     }
132 
133 return NULL;
134 }
135 
136 
137 
138 
139 /*
140 **  Return a value in a binary string
141 **
142 */
143 
sBit2Str(unsigned short value)144 char *sBit2Str(unsigned short value)
145 {
146   static char str[sizeof(value)*8];
147   int biz    = 16;
148   int strwid = 16;
149   int i, j;
150   char *tempPtr = str;
151 
152       j = strwid - (biz + (biz >> 2)- (biz % 4 ? 0 : 1));
153 
154       for (i = 0; i < j; i++) {
155             *tempPtr++ = ' ';
156       }
157       while (--biz >= 0)
158       {
159             *tempPtr++ = ((value >> biz) & 1) + '0';
160             if (!(biz % 4) && biz) {
161                   *tempPtr++ = ' ';
162             }
163       }
164       *tempPtr = '\0';
165 
166   return str;
167 }
168 
169 
170 
171 
172 /*
173 **  Parse commandline style arguments
174 **
175 */
176 
ParseArguments(char * s,char *** arg)177 int ParseArguments(char *s, char ***arg)
178 {
179     int  n = 1, Quote = 0;
180     char *p = s, *p1, c;
181 
182     argv[0] = GetAppName();
183 
184     *arg = argv;
185 
186     p1 = (char *) argStr;
187     while ((c = *p++) != 0) {
188         if (c==' ') continue;
189         argv[n++] = p1;
190         if (n > MAX_ARGS)
191             return (n-1);
192         do {
193             if (c=='\\' && *p++)
194                 c = *p++;
195             else
196                 if ((c=='"') || (c == '\'')) {
197                     if (!Quote) {
198                         Quote = c;
199                         continue;
200                     }
201                     if (c == Quote) {
202                         Quote = 0;
203                         continue;
204                     }
205                 }
206             *p1++ = c;
207         } while (*p && ((c = *p++) != ' ' || Quote));
208         *p1++ = '\0';
209     }
210     return n;
211 }
212 
213 
214 
215 /*
216 **  Print commandline style arguments
217 **
218 */
219 
PrintArguments(int argc,char ** argv)220 void PrintArguments(int argc, char **argv)
221 {
222 
223 printf("\n Arguments:");
224 printf("\n --------------------------");
225 
226 while(--argc >= 0)
227     printf("\n argc: %d  argv: [%s]", argc, &*argv[argc]);
228 
229 printf("\n --------------------------\n\n");
230 return;
231 }
232 
233 
234 
235 /*
236 **  return some error-msg on file-system
237 **
238 */
239 
PrintUserHFSerr(int cond,int err,char * msg2)240 int PrintUserHFSerr(int cond, int err, char *msg2)
241 {
242 char *msg;
243 
244 if (cond != 0)
245     {
246     switch (err)
247         {
248          case -35:
249             msg = "No such Volume";
250          break;
251 
252          case -56:
253             msg = "No such Drive";
254          break;
255 
256          case -37:
257             msg = "Bad Volume Name";
258          break;
259 
260          case -49:
261             msg = "File is already open for writing";
262          break;
263 
264          case -43:
265             msg = "Directory/File not found";
266          break;
267 
268          case -120:
269             msg = "Directory/File not found or incomplete pathname";
270          break;
271 
272         default: return err;
273          }
274     fprintf(stderr, "\n\n Error: %s ->%s", msg, msg2);
275     exit(err);
276     }
277 
278 return 0;
279 }
280 
281 
282 
283 /*
284 **  Check mounted volumes and return number of volumes
285 **  with the same name.
286 */
287 
CheckMountedVolumes(char * FullPath)288 short CheckMountedVolumes(char *FullPath)
289 {
290 FSSpec  volumes[50];        /* 50 Volumes should be enough */
291 char VolumeName[257], volume[257];
292 short actVolCount, volIndex = 1, VolCount = 0;
293 OSErr err;
294 int i;
295 
296 GetVolumeFromPath(FullPath, VolumeName);
297 
298 err = OnLine(volumes, 50, &actVolCount, &volIndex);
299 printerr("OnLine:", (err != -35) && (err != 0), err, __LINE__, __FILE__, "");
300 
301 for (i=0; i < actVolCount; i++)
302     {
303     PToCCpy(volumes[i].name,volume);
304     if (stricmp(volume, VolumeName) == 0) VolCount++;
305     }
306 printerr("OnLine: ", (VolCount == 0), VolCount, __LINE__, __FILE__, FullPath);
307 
308 return VolCount;
309 }
310 
311 
312 
313 
314 
315 
316 
317 
318 /*
319 **  compares strings, ignoring differences in case
320 **
321 */
322 
stricmp(const char * p1,const char * p2)323 int stricmp(const char *p1, const char *p2)
324 {
325 int diff;
326 
327 while (*p1 && *p2)
328     {
329     if (*p1 != *p2)
330         {
331         if (isalpha(*p1) && isalpha(*p2))
332             {
333             diff = toupper(*p1) - toupper(*p2);
334             if (diff) return diff;
335             }
336             else break;
337         }
338         p1++;
339         p2++;
340     }
341 return *p1 - *p2;
342 }
343 
344 
345 
346 /*
347 ** Convert the MacOS-Strings (Filenames/Findercomments) to a most compatible.
348 ** These strings will be stored in the public area of the zip-archive.
349 ** Every foreign platform (outside macos) will access these strings
350 ** for extraction.
351 */
352 
MakeCompatibleString(char * MacOS_Str,const char SpcChar1,const char SpcChar2,const char SpcChar3,const char SpcChar4,short CurrTextEncodingBase)353 void MakeCompatibleString(char *MacOS_Str,
354             const char SpcChar1, const char SpcChar2,
355             const char SpcChar3, const char SpcChar4,
356             short CurrTextEncodingBase)
357 {
358     char *tmpPtr;
359     register uch curch;
360 
361     Assert_it(MacOS_Str,"MakeCompatibleString MacOS_Str == NULL","")
362     for (tmpPtr = MacOS_Str; (curch = *tmpPtr) != '\0'; tmpPtr++)
363     {
364         if (curch == SpcChar1)
365             *tmpPtr = SpcChar2;
366         else
367         if (curch == SpcChar3)
368             *tmpPtr = SpcChar4;
369         else  /* default */
370         /* now convert from MacRoman to ISO-8859-1 */
371         /* but convert only if MacRoman is activ */
372             if ((CurrTextEncodingBase == kTextEncodingMacRoman) &&
373                 (curch > 127))
374                    {
375                     *tmpPtr = (char)MacRoman_to_WinCP1252[curch - 128];
376                    }
377     }  /* end for */
378 }
379 
380 
381 
382 
CheckForSwitch(char * Switch,int argc,char ** argv)383 Boolean CheckForSwitch(char *Switch, int argc, char **argv)
384 {
385   char *p;              /* steps through option arguments */
386   int i;                /* arg counter, root directory flag */
387 
388   for (i = 1; i < argc; i++)
389   {
390     if (argv[i][0] == '-')
391     {
392       if (argv[i][1])
393         {
394         for (p = argv[i]+1; *p; p++)
395             {
396             if (*p == Switch[0])
397                 {
398                 return true;
399                 }
400             if ((Switch[1] != NULL) &&
401                 ((*p == Switch[0]) && (*p == Switch[1])))
402                 {
403                 return true;
404                 }
405             }
406          }
407      }
408   }
409 
410 return false;
411 }
412 
413 
414 
415 
416 
417 
418 
419 #if (defined(USE_SIOUX) || defined(MACUNZIP_STANDALONE))
420 
421 /*
422 **  checks the condition and returns an error-msg
423 **  this function is for internal use only
424 */
425 
printerr(const char * msg,int cond,int err,int line,char * file,const char * msg2)426 OSErr printerr(const char *msg, int cond, int err, int line, char *file,
427               const char *msg2)
428 {
429 
430 if (cond != 0)
431     {
432     fprintf(stderr, "\nint err: %d: %s %d [%d/%s] {%s}\n", clock(), msg, err,
433             line, file, msg2);
434     }
435 
436 return cond;
437 }
438 
439 
440 /*
441 fake-functions:
442 Not Implemented for metrowerks SIOUX
443 */
444 
leftStatusString(char * status)445 void leftStatusString(char *status)
446 {
447 status = status;
448 }
449 
450 
rightStatusString(char * status)451 void rightStatusString(char *status)
452 {
453 status = status;
454 }
455 
456 
457 
DoWarnUserDupVol(char * FullPath)458 void DoWarnUserDupVol( char *FullPath )
459 {
460   char VolName[257];
461   GetVolumeFromPath(FullPath,  VolName);
462 
463   printf("\n There are more than one volume that has the same name !!\n");
464 
465   printf("\n Volume: %s\n",VolName);
466 
467   printf("\n This port has one weak point:");
468   printf("\n It is based on pathnames. As you may be already know:");
469   printf("\n Pathnames are not unique on a Mac !");
470   printf("\n MacZip has problems to find the correct location of");
471   printf("\n the archive or the files.\n");
472 
473   printf("\n My (Big) recommendation:  Name all your volumes with an");
474   printf("\n unique name and MacZip will run without any problem.");
475 }
476 
477 
478 
479 #endif
480