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