boinc/zip/unzip/macos/source/helpers.c

482 lines
9.5 KiB
C

/*
Copyright (c) 1990-2001 Info-ZIP. All rights reserved.
See the accompanying file LICENSE, version 2000-Apr-09 or later
(the contents of which are also included in zip.h) for terms of use.
If, for some reason, all these files are missing, the Info-ZIP license
also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
*/
/*---------------------------------------------------------------------------
helpers.c
Some useful functions Used by unzip and zip.
---------------------------------------------------------------------------*/
/*****************************************************************************/
/* Includes */
/*****************************************************************************/
#include "zip.h"
#include <ctype.h>
#include <time.h>
#include <sound.h>
#include "macstuff.h"
#include "helpers.h"
#include "pathname.h"
/*****************************************************************************/
/* Global Vars */
/*****************************************************************************/
extern int noisy;
extern char MacPathEnd;
extern char *zipfile; /* filename of the Zipfile */
extern char *tempzip; /* Temporary zip file name */
extern ZCONST unsigned char MacRoman_to_WinCP1252[128];
static char argStr[1024];
static char *argv[MAX_ARGS + 1];
/*****************************************************************************/
/* Functions */
/*****************************************************************************/
/*
** Copy a C string to a Pascal string
**
*/
unsigned char *CToPCpy(unsigned char *pstr, char *cstr)
{
register char *dptr;
register unsigned len;
len=0;
dptr=(char *)pstr+1;
while (len<255 && (*dptr++ = *cstr++)!='\0') ++len;
*pstr= (unsigned char)len;
return pstr;
}
/*
** Copy a Pascal string to a C string
**
*/
char *PToCCpy(unsigned char *pstr, char *cstr)
{
strncpy(cstr, (char *) &pstr[1], *pstr);
cstr[pstr[0]] = '\0'; /* set endmarker for c-string */
return cstr;
}
/*
** strcpy() and strcat() work-alikes which allow overlapping buffers.
*/
char *sstrcpy(char *to,const char *from)
{
memmove(to, from, 1+strlen(from));
return to;
}
char *sstrcat(char *to,const char *from)
{
sstrcpy(to + strlen(to), from);
return to;
}
/*
** Alloc memory and init it
**
*/
char *StrCalloc(unsigned short size)
{
char *strPtr = NULL;
if ((strPtr = calloc(size, sizeof(char))) == NULL)
printerr("StrCalloc failed:", -1, size, __LINE__, __FILE__, "");
Assert_it(strPtr,"strPtr == NULL","")
return strPtr;
}
/*
** Release only non NULL pointers
**
*/
char *StrFree(char *strPtr)
{
if (strPtr != NULL)
{
free(strPtr);
}
return NULL;
}
/*
** Return a value in a binary string
**
*/
char *sBit2Str(unsigned short value)
{
static char str[sizeof(value)*8];
int biz = 16;
int strwid = 16;
int i, j;
char *tempPtr = str;
j = strwid - (biz + (biz >> 2)- (biz % 4 ? 0 : 1));
for (i = 0; i < j; i++) {
*tempPtr++ = ' ';
}
while (--biz >= 0)
{
*tempPtr++ = ((value >> biz) & 1) + '0';
if (!(biz % 4) && biz) {
*tempPtr++ = ' ';
}
}
*tempPtr = '\0';
return str;
}
/*
** Parse commandline style arguments
**
*/
int ParseArguments(char *s, char ***arg)
{
int n = 1, Quote = 0;
char *p = s, *p1, c;
argv[0] = GetAppName();
*arg = argv;
p1 = (char *) argStr;
while ((c = *p++) != 0) {
if (c==' ') continue;
argv[n++] = p1;
if (n > MAX_ARGS)
return (n-1);
do {
if (c=='\\' && *p++)
c = *p++;
else
if ((c=='"') || (c == '\'')) {
if (!Quote) {
Quote = c;
continue;
}
if (c == Quote) {
Quote = 0;
continue;
}
}
*p1++ = c;
} while (*p && ((c = *p++) != ' ' || Quote));
*p1++ = '\0';
}
return n;
}
/*
** Print commandline style arguments
**
*/
void PrintArguments(int argc, char **argv)
{
printf("\n Arguments:");
printf("\n --------------------------");
while(--argc >= 0)
printf("\n argc: %d argv: [%s]", argc, &*argv[argc]);
printf("\n --------------------------\n\n");
return;
}
/*
** return some error-msg on file-system
**
*/
int PrintUserHFSerr(int cond, int err, char *msg2)
{
char *msg;
if (cond != 0)
{
switch (err)
{
case -35:
msg = "No such Volume";
break;
case -56:
msg = "No such Drive";
break;
case -37:
msg = "Bad Volume Name";
break;
case -49:
msg = "File is already open for writing";
break;
case -43:
msg = "Directory/File not found";
break;
case -120:
msg = "Directory/File not found or incomplete pathname";
break;
default: return err;
}
fprintf(stderr, "\n\n Error: %s ->%s", msg, msg2);
exit(err);
}
return 0;
}
/*
** Check mounted volumes and return number of volumes
** with the same name.
*/
short CheckMountedVolumes(char *FullPath)
{
FSSpec volumes[50]; /* 50 Volumes should be enough */
char VolumeName[257], volume[257];
short actVolCount, volIndex = 1, VolCount = 0;
OSErr err;
int i;
GetVolumeFromPath(FullPath, VolumeName);
err = OnLine(volumes, 50, &actVolCount, &volIndex);
printerr("OnLine:", (err != -35) && (err != 0), err, __LINE__, __FILE__, "");
for (i=0; i < actVolCount; i++)
{
PToCCpy(volumes[i].name,volume);
if (stricmp(volume, VolumeName) == 0) VolCount++;
}
printerr("OnLine: ", (VolCount == 0), VolCount, __LINE__, __FILE__, FullPath);
return VolCount;
}
/*
** compares strings, ignoring differences in case
**
*/
int stricmp(const char *p1, const char *p2)
{
int diff;
while (*p1 && *p2)
{
if (*p1 != *p2)
{
if (isalpha(*p1) && isalpha(*p2))
{
diff = toupper(*p1) - toupper(*p2);
if (diff) return diff;
}
else break;
}
p1++;
p2++;
}
return *p1 - *p2;
}
/*
** Convert the MacOS-Strings (Filenames/Findercomments) to a most compatible.
** These strings will be stored in the public area of the zip-archive.
** Every foreign platform (outside macos) will access these strings
** for extraction.
*/
void MakeCompatibleString(char *MacOS_Str,
const char SpcChar1, const char SpcChar2,
const char SpcChar3, const char SpcChar4,
short CurrTextEncodingBase)
{
char *tmpPtr;
register uch curch;
Assert_it(MacOS_Str,"MakeCompatibleString MacOS_Str == NULL","")
for (tmpPtr = MacOS_Str; (curch = *tmpPtr) != '\0'; tmpPtr++)
{
if (curch == SpcChar1)
*tmpPtr = SpcChar2;
else
if (curch == SpcChar3)
*tmpPtr = SpcChar4;
else /* default */
/* now convert from MacRoman to ISO-8859-1 */
/* but convert only if MacRoman is activ */
if ((CurrTextEncodingBase == kTextEncodingMacRoman) &&
(curch > 127))
{
*tmpPtr = (char)MacRoman_to_WinCP1252[curch - 128];
}
} /* end for */
}
Boolean CheckForSwitch(char *Switch, int argc, char **argv)
{
char *p; /* steps through option arguments */
int i; /* arg counter, root directory flag */
for (i = 1; i < argc; i++)
{
if (argv[i][0] == '-')
{
if (argv[i][1])
{
for (p = argv[i]+1; *p; p++)
{
if (*p == Switch[0])
{
return true;
}
if ((Switch[1] != NULL) &&
((*p == Switch[0]) && (*p == Switch[1])))
{
return true;
}
}
}
}
}
return false;
}
#if (defined(USE_SIOUX) || defined(MACUNZIP_STANDALONE))
/*
** checks the condition and returns an error-msg
** this function is for internal use only
*/
OSErr printerr(const char *msg, int cond, int err, int line, char *file,
const char *msg2)
{
if (cond != 0)
{
fprintf(stderr, "\nint err: %d: %s %d [%d/%s] {%s}\n", clock(), msg, err,
line, file, msg2);
}
return cond;
}
/*
fake-functions:
Not Implemented for metrowerks SIOUX
*/
void leftStatusString(char *status)
{
status = status;
}
void rightStatusString(char *status)
{
status = status;
}
void DoWarnUserDupVol( char *FullPath )
{
char VolName[257];
GetVolumeFromPath(FullPath, VolName);
printf("\n There are more than one volume that has the same name !!\n");
printf("\n Volume: %s\n",VolName);
printf("\n This port has one weak point:");
printf("\n It is based on pathnames. As you may be already know:");
printf("\n Pathnames are not unique on a Mac !");
printf("\n MacZip has problems to find the correct location of");
printf("\n the archive or the files.\n");
printf("\n My (Big) recommendation: Name all your volumes with an");
printf("\n unique name and MacZip will run without any problem.");
}
#endif
const char *BOINC_RCSID_f6b4b545d7 = "$Id$";