~ubuntu-branches/ubuntu/precise/boinc/precise

« back to all changes in this revision

Viewing changes to zip/unzip/macos/source/pathname.c

Tags: 6.12.8+dfsg-1
* New upstream release.
* Simplified debian/rules

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
 
  pathname.c
12
 
 
13
 
  Function dealing with the pathname. Mostly C-string work.
14
 
 
15
 
  ---------------------------------------------------------------------------*/
16
 
 
17
 
/*****************************************************************************/
18
 
/*  Includes                                                                 */
19
 
/*****************************************************************************/
20
 
 
21
 
#include <string.h>
22
 
#include <stdio.h>
23
 
#include <unistd.h>
24
 
#include <sound.h>
25
 
 
26
 
#include "pathname.h"
27
 
#include "helpers.h"
28
 
#include "macstuff.h"
29
 
 
30
 
 
31
 
/*****************************************************************************/
32
 
/*  Global Vars                                                              */
33
 
/*****************************************************************************/
34
 
 
35
 
const char  ResourceMark[] = "XtraStuf.mac:";  /* see also macos.c */
36
 
 
37
 
 
38
 
#include "zip.h"
39
 
 
40
 
 
41
 
 
42
 
 
43
 
/*****************************************************************************/
44
 
/*  Functions                                                                */
45
 
/*****************************************************************************/
46
 
 
47
 
 
48
 
/*
49
 
 *----------------------------------------------------------------------
50
 
 *
51
 
 * FSpFindFolder --
52
 
 *
53
 
 *  This function is a version of the FindFolder function that
54
 
 *  returns the result as a FSSpec rather than a vRefNum and dirID.
55
 
 *
56
 
 * Results:
57
 
 *  Results will be simaler to that of the FindFolder function.
58
 
 *
59
 
 * Side effects:
60
 
 *  None.
61
 
 *
62
 
 *----------------------------------------------------------------------
63
 
 */
64
 
 
65
 
OSErr
66
 
FSpFindFolder(
67
 
    short vRefNum,      /* Volume reference number. */
68
 
    OSType folderType,      /* Folder type taken by FindFolder. */
69
 
    Boolean createFolder,   /* Should we create it if non-existant. */
70
 
    FSSpec *spec)       /* Pointer to resulting directory. */
71
 
{
72
 
    short foundVRefNum;
73
 
    long foundDirID;
74
 
    OSErr err;
75
 
 
76
 
    err = FindFolder(vRefNum, folderType, createFolder,
77
 
        &foundVRefNum, &foundDirID);
78
 
    if (err != noErr) {
79
 
    return err;
80
 
    }
81
 
 
82
 
    err = FSMakeFSSpecCompat(foundVRefNum, foundDirID, "\p", spec);
83
 
    return err;
84
 
}
85
 
 
86
 
 
87
 
/*
88
 
**  return volumename from pathname
89
 
**
90
 
*/
91
 
 
92
 
unsigned short GetVolumeFromPath(const char *FullPath, char *VolumeName)
93
 
{
94
 
const char *VolEnd, *tmpPtr1;
95
 
char *tmpPtr2 = VolumeName;
96
 
 
97
 
AssertStr(FullPath,"GetVolumeFromPath")
98
 
 
99
 
for (VolEnd = FullPath; *VolEnd != '\0' && *VolEnd != ':'; VolEnd++)
100
 
      ;
101
 
if (*VolEnd == '\0') return 0;
102
 
 
103
 
for (tmpPtr1 = FullPath; tmpPtr1 != VolEnd;)
104
 
    {
105
 
    *tmpPtr2++ = *tmpPtr1++;
106
 
    }
107
 
 
108
 
*tmpPtr2 = '\0';
109
 
 
110
 
return (unsigned short) strlen(VolumeName);
111
 
}
112
 
 
113
 
 
114
 
 
115
 
/***********************************/
116
 
/* Function FindNewExtractFolder() */
117
 
/***********************************/
118
 
 
119
 
char *FindNewExtractFolder(char *ExtractPath, Boolean uniqueFolder)
120
 
{
121
 
char buffer[NAME_MAX], *tmpPtr, *namePtr;
122
 
char *last_dotpos         = ExtractPath;
123
 
short count = 0, folderCount = 0;
124
 
OSErr err;
125
 
FSSpec Spec;
126
 
long theDirID;
127
 
Boolean isDirectory;
128
 
unsigned short namelen, pathlen = strlen(ExtractPath);
129
 
unsigned long ext_length  = 0;
130
 
unsigned long num_to_cut  = 0;
131
 
long firstpart_length = pathlen;
132
 
 
133
 
AssertStr(ExtractPath,"FindNewExtractFolder ExtractPath == NULL")
134
 
 
135
 
for (tmpPtr = ExtractPath; *tmpPtr; tmpPtr++)
136
 
    if (*tmpPtr == ':')
137
 
        {
138
 
        folderCount++;
139
 
        namePtr = tmpPtr;
140
 
        }
141
 
 
142
 
if (folderCount > 1) {
143
 
    namelen = strlen(namePtr);
144
 
} else {
145
 
    namelen = strlen(ExtractPath);
146
 
}
147
 
 
148
 
if (uniqueFolder) {
149
 
    for (count = 0; count < 99; count++)
150
 
        {
151
 
        memset(buffer,0,sizeof(buffer));
152
 
 
153
 
        if (namelen >= 28)
154
 
            ExtractPath[pathlen-2] = 0x0;
155
 
        else
156
 
            ExtractPath[pathlen-1] = 0x0;
157
 
 
158
 
        sprintf(buffer,"%s%d",ExtractPath,count);
159
 
        GetCompletePath(ExtractPath, buffer, &Spec,&err);
160
 
        err = FSpGetDirectoryID(&Spec, &theDirID, &isDirectory);
161
 
        if (err == -43) break;
162
 
        }
163
 
} else {
164
 
    /* Look for the last extension pos */
165
 
    for (tmpPtr = ExtractPath; *tmpPtr; tmpPtr++)
166
 
        if (*tmpPtr == '.') last_dotpos = tmpPtr;
167
 
 
168
 
    ext_length = strlen(last_dotpos);
169
 
 
170
 
    if (ext_length < 6) {  /* up to 5 chars are treated as a */
171
 
                           /* normal extension like ".html" or ".class"  */
172
 
        int nameLength = last_dotpos - ExtractPath;
173
 
        if (nameLength > 1) {
174
 
            ExtractPath[nameLength] = 0x0;
175
 
        } else {
176
 
            ExtractPath[pathlen-1] = 0x0;
177
 
        }
178
 
    } else {
179
 
        ExtractPath[pathlen-1] = 0x0;
180
 
    }
181
 
 
182
 
    GetCompletePath(ExtractPath, ExtractPath, &Spec,&err);
183
 
}
184
 
 
185
 
/* Foldernames must always end with a colon  */
186
 
sstrcat(ExtractPath,":");
187
 
return ExtractPath;
188
 
}
189
 
 
190
 
 
191
 
 
192
 
/*
193
 
**  creates an archive file name
194
 
**
195
 
*/
196
 
 
197
 
void createArchiveName(char *thePath)
198
 
{
199
 
char *tmpPtr, *namePtr;
200
 
short folderCount = 0;
201
 
unsigned short namelen, pathlen = strlen(thePath);
202
 
 
203
 
if (thePath[pathlen-1] == ':') thePath[pathlen-1] = 0x0;
204
 
 
205
 
for (tmpPtr = thePath; *tmpPtr; tmpPtr++)
206
 
    if (*tmpPtr == ':')
207
 
        {
208
 
        folderCount++;
209
 
        namePtr = tmpPtr;
210
 
        }
211
 
 
212
 
namelen = strlen(namePtr);
213
 
 
214
 
    /* we have to eliminate illegal chars:
215
 
     * The name space for Mac filenames and Zip filenames (unix style names)
216
 
     * do both include all printable extended-ASCII characters.  The only
217
 
     * difference we have to take care of is the single special character
218
 
     * used as path delimiter:
219
 
     * ':' on MacOS and '/' on Unix and '\' on Dos.
220
 
     * So, to convert between Mac filenames and Unix filenames without any
221
 
     * loss of information, we simply interchange ':' and '/'.  Additionally,
222
 
     * we try to convert the coding of the extended-ASCII characters into
223
 
     * InfoZip's standard ISO 8859-1 codepage table.
224
 
     */
225
 
  MakeCompatibleString(namePtr, '/', '_', '.', '-', -1);
226
 
 
227
 
 /* Avoid filenames like: "Archive..zip"  */
228
 
if (thePath[pathlen-1] == '.')
229
 
    {
230
 
    thePath[pathlen-1] = 0;
231
 
    }
232
 
 
233
 
if (folderCount >= 1)
234
 
    { /* path contains at least one folder */
235
 
 
236
 
    if (namelen >= 28)
237
 
        {
238
 
        pathlen = pathlen-4;
239
 
        }
240
 
 
241
 
    thePath[pathlen]   = '.';
242
 
    thePath[pathlen+1] = 'z';
243
 
    thePath[pathlen+2] = 'i';
244
 
    thePath[pathlen+3] = 'p';
245
 
    thePath[pathlen+4] = 0x0;
246
 
    return;
247
 
    }
248
 
else
249
 
    {  /* path contains no folder */
250
 
    FindDesktopFolder(thePath);
251
 
    createArchiveName(thePath);
252
 
    }
253
 
}
254
 
 
255
 
 
256
 
 
257
 
/*
258
 
** finds the desktop-folder on a volume with
259
 
** largest amount of free-space.
260
 
*/
261
 
 
262
 
void FindDesktopFolder(char *Path)
263
 
{
264
 
char buffer[255];
265
 
FSSpec  volumes[50];        /* 50 Volumes should be enough */
266
 
short   actVolCount, volIndex = 1, VolCount = 0;
267
 
OSErr   err;
268
 
short     i, foundVRefNum;
269
 
FSSpec spec;
270
 
UInt64 freeBytes;
271
 
UInt64 totalBytes;
272
 
UInt64 MaxFreeBytes;
273
 
 
274
 
err = OnLine(volumes, 50, &actVolCount, &volIndex);
275
 
printerr("OnLine:", (err != -35) && (err != 0), err, __LINE__, __FILE__, "");
276
 
 
277
 
MaxFreeBytes = 0;
278
 
 
279
 
for (i=0; i < actVolCount; i++)
280
 
    {
281
 
    XGetVInfo(volumes[i].vRefNum,
282
 
              volumes[i].name,
283
 
              &volumes[i].vRefNum,
284
 
              &freeBytes,
285
 
              &totalBytes);
286
 
 
287
 
    if (MaxFreeBytes < freeBytes) {
288
 
        MaxFreeBytes = freeBytes;
289
 
        foundVRefNum = volumes[i].vRefNum;
290
 
    }
291
 
 
292
 
    if ((freeBytes == 0) && (MaxFreeBytes < freeBytes)) {
293
 
        MaxFreeBytes = freeBytes;
294
 
        foundVRefNum = volumes[i].vRefNum;
295
 
    }
296
 
 
297
 
}
298
 
 
299
 
 FSpFindFolder(foundVRefNum, kDesktopFolderType,
300
 
            kDontCreateFolder,&spec);
301
 
 
302
 
 GetFullPathFromSpec(buffer, &spec , &err);
303
 
 sstrcat(buffer,Path);
304
 
 sstrcpy(Path,buffer);
305
 
}
306
 
 
307
 
 
308
 
/*
309
 
**  return the path without the filename
310
 
**
311
 
*/
312
 
 
313
 
char *TruncFilename(char *DirPath, const char *FilePath)
314
 
{
315
 
char *tmpPtr;
316
 
char *dirPtr = NULL;
317
 
 
318
 
AssertStr(DirPath,"TruncFilename")
319
 
Assert_it(Spec,"TruncFilename","")
320
 
 
321
 
sstrcpy(DirPath, FilePath);
322
 
 
323
 
for (tmpPtr = DirPath; *tmpPtr; tmpPtr++)
324
 
    if (*tmpPtr == ':')
325
 
        dirPtr = tmpPtr;
326
 
 
327
 
if (dirPtr)
328
 
    *++dirPtr = '\0';
329
 
else
330
 
    printerr("TruncFilename: FilePath has no Folders", -1,
331
 
         -1, __LINE__, __FILE__, FilePath);
332
 
 
333
 
return DirPath;
334
 
}
335
 
 
336
 
 
337
 
 
338
 
/*
339
 
**  return only filename
340
 
**
341
 
*/
342
 
 
343
 
char *GetFilename(char *FileName, const char *FilePath)
344
 
{
345
 
const char *tmpPtr;
346
 
const char *dirPtr = NULL;
347
 
 
348
 
Assert_it(FileName,"GetFilename","")
349
 
Assert_it(FilePath,"GetFilename","")
350
 
 
351
 
for (tmpPtr = FilePath; *tmpPtr; tmpPtr++)
352
 
    {
353
 
    if (*tmpPtr == ':')
354
 
        {
355
 
        dirPtr = tmpPtr;
356
 
        }
357
 
    }
358
 
 
359
 
if (dirPtr)
360
 
    {
361
 
    ++dirPtr;  /* jump over the ':' */
362
 
    }
363
 
else
364
 
    {
365
 
    return strcpy(FileName, FilePath); /* FilePath has no Folders */
366
 
    }
367
 
 
368
 
return strcpy(FileName, dirPtr);
369
 
}
370
 
 
371
 
 
372
 
 
373
 
/*
374
 
**  return fullpathname from folder/dir-id
375
 
**
376
 
*/
377
 
 
378
 
char *GetFullPathFromID(char *CompletePath, short vRefNum, long dirID,
379
 
                        ConstStr255Param name, OSErr *err)
380
 
{
381
 
FSSpec      spec;
382
 
 
383
 
    *err = FSMakeFSSpecCompat(vRefNum, dirID, name, &spec);
384
 
    printerr("FSMakeFSSpecCompat:", (*err != -43) && (*err != 0), *err,
385
 
             __LINE__, __FILE__, "");
386
 
    if ( (*err == noErr) || (*err == fnfErr) )
387
 
        {
388
 
        return GetFullPathFromSpec(CompletePath, &spec, err);
389
 
        }
390
 
 
391
 
return NULL;
392
 
}
393
 
 
394
 
 
395
 
 
396
 
/*
397
 
**  convert real-filename to archive-filename
398
 
**
399
 
*/
400
 
 
401
 
char *Real2RfDfFilen(char *RfDfFilen, const char *RealPath,
402
 
                    short CurrentFork, short MacZipMode, Boolean DataForkOnly)
403
 
{
404
 
 
405
 
AssertStr(RealPath,"Real2RfDfFilen")
406
 
AssertStr(RfDfFilen,"Real2RfDfFilen")
407
 
 
408
 
if (DataForkOnly) /* make no changes */
409
 
    {
410
 
    return sstrcpy(RfDfFilen, RealPath);
411
 
    }
412
 
 
413
 
switch (MacZipMode)
414
 
    {
415
 
    case JohnnyLee_EF:
416
 
        {
417
 
        sstrcpy(RfDfFilen, RealPath);
418
 
        if (CurrentFork == DataFork)            /* data-fork  */
419
 
            return sstrcat(RfDfFilen, "d");
420
 
        if (CurrentFork == ResourceFork)        /* resource-fork */
421
 
            return sstrcat(RfDfFilen, "r");
422
 
        break;
423
 
        }
424
 
 
425
 
    case NewZipMode_EF:
426
 
        {
427
 
        switch (CurrentFork)
428
 
            {
429
 
            case DataFork:
430
 
                {
431
 
                sstrcpy(RfDfFilen, RealPath);
432
 
                return RfDfFilen;  /* data-fork  */
433
 
                break;
434
 
                }
435
 
            case ResourceFork:
436
 
                {
437
 
                sstrcpy(RfDfFilen, ResourceMark);
438
 
                sstrcat(RfDfFilen, RealPath);  /* resource-fork */
439
 
                return RfDfFilen;
440
 
                break;
441
 
                }
442
 
            default:
443
 
                {
444
 
                printerr("Real2RfDfFilen:", -1, -1,
445
 
                         __LINE__, __FILE__, RealPath);
446
 
                return NULL;  /* function should never reach this point */
447
 
                }
448
 
            }
449
 
        break;
450
 
        }
451
 
    default:
452
 
        {
453
 
        printerr("Real2RfDfFilen:", -1, -1, __LINE__, __FILE__, RealPath);
454
 
        return NULL;  /* function should never reach this point */
455
 
        }
456
 
    }
457
 
 
458
 
printerr("Real2RfDfFilen:", -1, -1, __LINE__, __FILE__, RealPath);
459
 
return NULL;  /* function should never come reach this point */
460
 
}
461
 
 
462
 
 
463
 
 
464
 
/*
465
 
**  convert archive-filename into a real filename
466
 
**
467
 
*/
468
 
 
469
 
char *RfDfFilen2Real(char *RealFn, const char *RfDfFilen, short MacZipMode,
470
 
                     Boolean DataForkOnly, short *CurrentFork)
471
 
{
472
 
short   length;
473
 
int     result;
474
 
 
475
 
AssertStr(RfDfFilen,"RfDfFilen2Real")
476
 
 
477
 
if (DataForkOnly ||
478
 
    (MacZipMode == UnKnown_EF) ||
479
 
    (MacZipMode < JohnnyLee_EF))
480
 
    {
481
 
    *CurrentFork = DataFork;
482
 
    return sstrcpy(RealFn,RfDfFilen);
483
 
    }
484
 
 
485
 
result = strncmp(RfDfFilen, ResourceMark, sizeof(ResourceMark)-2);
486
 
if (result == 0)
487
 
    {
488
 
    MacZipMode = NewZipMode_EF;
489
 
    }
490
 
 
491
 
switch (MacZipMode)
492
 
    {
493
 
    case JohnnyLee_EF:
494
 
        {
495
 
        sstrcpy(RealFn, RfDfFilen);
496
 
        length = strlen(RealFn);       /* determine Fork type */
497
 
        if (RealFn[length-1] == 'd') *CurrentFork = DataFork;
498
 
        else *CurrentFork = ResourceFork;
499
 
        RealFn[length-1] = '\0';       /* simply cut one char  */
500
 
        return RealFn;
501
 
        break;
502
 
        }
503
 
 
504
 
    case NewZipMode_EF:
505
 
        {                                   /* determine Fork type */
506
 
        result = strncmp(RfDfFilen, ResourceMark, sizeof(ResourceMark)-2);
507
 
        if (result != 0)
508
 
            {
509
 
            *CurrentFork = DataFork;
510
 
            sstrcpy(RealFn, RfDfFilen);
511
 
            return RealFn;  /* data-fork  */
512
 
            }
513
 
        else
514
 
            {
515
 
            *CurrentFork = ResourceFork;
516
 
            if (strlen(RfDfFilen) > (sizeof(ResourceMark) - 1))
517
 
                {
518
 
                sstrcpy(RealFn, &RfDfFilen[sizeof(ResourceMark)-1]);
519
 
                }
520
 
            else RealFn[0] = '\0';
521
 
            return RealFn;  /* resource-fork */
522
 
            }
523
 
        break;
524
 
        }
525
 
    default:
526
 
        {
527
 
        *CurrentFork = NoFork;
528
 
        printerr("RfDfFilen2Real():", -1, MacZipMode,
529
 
                 __LINE__, __FILE__, RfDfFilen);
530
 
        return NULL;  /* function should never reach this point */
531
 
        }
532
 
    }
533
 
 
534
 
printerr("RfDfFilen2Real():", -1, MacZipMode, __LINE__, __FILE__, RfDfFilen);
535
 
return NULL;  /* function should never reach this point */
536
 
}
537
 
 
538
 
 
539
 
 
540
 
/*
541
 
**  return the applications name (argv[0])
542
 
**
543
 
*/
544
 
 
545
 
char *GetAppName(void)
546
 
{
547
 
ProcessSerialNumber psn;
548
 
static Str255       AppName;
549
 
ProcessInfoRec      pinfo;
550
 
OSErr               err;
551
 
 
552
 
GetCurrentProcess(&psn);
553
 
pinfo.processName = AppName;
554
 
pinfo.processInfoLength = sizeof(pinfo);
555
 
pinfo.processAppSpec = NULL;
556
 
 
557
 
err = GetProcessInformation(&psn,&pinfo);
558
 
AppName[AppName[0]+1] = 0x00;
559
 
 
560
 
return (char *)&AppName[1];
561
 
}
562
 
 
563
 
 
564
 
 
565
 
/*
566
 
**  return fullpathname from FSSpec
567
 
**
568
 
*/
569
 
 
570
 
char *GetFullPathFromSpec(char *FullPath, FSSpec *Spec, OSErr *err)
571
 
{
572
 
Handle hFullPath;
573
 
short len;
574
 
 
575
 
Assert_it(Spec,"GetFullPathFromSpec","")
576
 
 
577
 
*err = FSpGetFullPath(Spec, &len, &hFullPath);
578
 
printerr("FSpGetFullPath:", (*err != -43) && (*err != 0), *err,
579
 
         __LINE__, __FILE__, "");
580
 
 
581
 
memmove(FullPath, (Handle) *hFullPath, len);
582
 
FullPath[len] = '\0';  /* make c-string */
583
 
 
584
 
DisposeHandle((Handle)hFullPath);   /* we don't need it any more */
585
 
 
586
 
printerr("Warning path length exceeds limit: ", len >= NAME_MAX, len,
587
 
         __LINE__, __FILE__, " chars ");
588
 
 
589
 
return FullPath;
590
 
}
591
 
 
592
 
 
593
 
 
594
 
 
595
 
/*
596
 
* This function expands a given partial path to a complete path.
597
 
* Path expansions are relative to the running app.
598
 
* This function follows the notation:
599
 
*   1. relative path:
600
 
*       a: ":subfolder:filename"    -> ":current folder:subfolder:filename"
601
 
*       b: "::folder2:filename"     -> folder2 is beside the current
602
 
*                                      folder on the same level
603
 
*       c: "filename"               -> in current folder
604
 
*
605
 
* An absolute path will be returned.
606
 
 
607
 
The following characteristics of Macintosh pathnames should be noted:
608
 
 
609
 
       A full pathname never begins with a colon, but must contain at
610
 
       least one colon.
611
 
       A partial pathname always begins with a colon separator except in
612
 
       the case where the file partial pathname is a simple file or
613
 
       directory name.
614
 
       Single trailing separator colons in full or partial pathnames are
615
 
       ignored except in the case of full pathnames to volumes.
616
 
       In full pathnames to volumes, the trailing separator colon is required.
617
 
       Consecutive separator colons can be used to ascend a level from a
618
 
       directory to its parent directory. Two consecutive separator colons
619
 
       will ascend one level, three consecutive separator colons will ascend
620
 
       two levels, and so on. Ascending can only occur from a directory;
621
 
       not a file.
622
 
*/
623
 
 
624
 
char *GetCompletePath(char *CompletePath, const char *name, FSSpec *Spec,
625
 
                      OSErr *err)
626
 
{
627
 
Boolean hasDirName = false;
628
 
char currentdir[NAME_MAX];
629
 
char *tmpPtr;
630
 
unsigned short pathlen;
631
 
 
632
 
AssertStr(name,"GetCompletePath")
633
 
Assert_it(Spec,"GetCompletePath","")
634
 
Assert_it((CompletePath != name),"GetCompletePath","")
635
 
 
636
 
for (tmpPtr = name; *tmpPtr; tmpPtr++)
637
 
    if (*tmpPtr == ':') hasDirName = true;
638
 
 
639
 
if (name[0] != ':')   /* case c: path including volume name or only filename */
640
 
    {
641
 
    if (hasDirName)
642
 
        {   /* okey, starts with volume name, so it must be a complete path */
643
 
        sstrcpy(CompletePath, name);
644
 
        }
645
 
    else
646
 
        {   /* only filename: add cwd and return */
647
 
        getcwd(currentdir, NAME_MAX);
648
 
        sstrcat(currentdir, name);
649
 
        sstrcpy(CompletePath, currentdir);
650
 
        }
651
 
    }
652
 
else if (name[1] == ':')    /* it's case b: "::folder2:filename"  */
653
 
    {
654
 
    printerr("GetCompletePath ", -1, *err, __LINE__, __FILE__, "not implemented");
655
 
            /* it's not yet implemented; do we really need this case ?*/
656
 
    return NULL;
657
 
    }
658
 
else                        /* it's case a: ":subfolder:filename" */
659
 
    {
660
 
    getcwd(CompletePath, NAME_MAX);     /* we don't need a second colon */
661
 
    CompletePath[strlen(CompletePath)-1] = '\0';
662
 
    sstrcat(CompletePath, name);
663
 
    }
664
 
 
665
 
pathlen = strlen(CompletePath);
666
 
*err = FSpLocationFromFullPath(pathlen, CompletePath, Spec);
667
 
 
668
 
return CompletePath;
669
 
}
670
 
 
671
 
 
672
 
 
673
 
char *MakeFilenameShorter(const char *LongFilename)
674
 
{
675
 
static char filename[35];  /* contents should be never longer than 32 chars */
676
 
static unsigned char Num = 0; /* change the number for every call */
677
 
                              /* this var will rollover without a problem */
678
 
char tempLongFilename[1024], charnum[5];
679
 
char *last_dotpos         = tempLongFilename;
680
 
unsigned long full_length = strlen(LongFilename);
681
 
unsigned long ext_length  = 0;
682
 
unsigned long num_to_cut  = 0;
683
 
long firstpart_length;
684
 
char *tmpPtr;
685
 
short MaxLength = 31;
686
 
 
687
 
if (full_length <= MaxLength) /* filename is not long */
688
 
    {
689
 
    return strcpy(filename,LongFilename);
690
 
    }
691
 
 
692
 
Num++;
693
 
strcpy(tempLongFilename,LongFilename);
694
 
 
695
 
/* Look for the last extension pos */
696
 
for (tmpPtr = tempLongFilename; *tmpPtr; tmpPtr++)
697
 
    if (*tmpPtr == '.') last_dotpos = tmpPtr;
698
 
 
699
 
ext_length = strlen(last_dotpos);
700
 
firstpart_length = last_dotpos - tempLongFilename;
701
 
 
702
 
if (ext_length > 6)  /* up to 5 chars are treated as a */
703
 
    {                /* normal extension like ".html" or ".class"  */
704
 
    firstpart_length = 0;
705
 
    }
706
 
 
707
 
num_to_cut = full_length - MaxLength;
708
 
 
709
 
/* number the files to make the names unique */
710
 
sprintf(charnum,"~%x", Num);
711
 
num_to_cut += strlen(charnum);
712
 
 
713
 
if (firstpart_length == 0)
714
 
    {
715
 
    firstpart_length = full_length;
716
 
    tempLongFilename[firstpart_length - num_to_cut] = 0;
717
 
    sprintf(filename,"%s%s", tempLongFilename, charnum);
718
 
    }
719
 
else
720
 
    {
721
 
    tempLongFilename[firstpart_length - num_to_cut] = 0;
722
 
    sprintf(filename,"%s%s%s", tempLongFilename, charnum, last_dotpos);
723
 
    }
724
 
 
725
 
return filename;
726
 
}
727
 
 
728
 
const char *BOINC_RCSID_20a7780104 = "$Id: pathname.c 4979 2005-01-02 18:29:53Z ballen $";