source: trunk/dll/copyf.c@ 1082

Last change on this file since 1082 was 1082, checked in by Gregg Young, 17 years ago

Changes so FM2 will use TMP/TEMP directory for all temp files; Replaced save_dir2 with global variable so BldFullPathName could easily replace code that performed the same function; Added #ifdef FORTIFY to free_ function that are only used when fortified.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 20.8 KB
RevLine 
[29]1
2/***********************************************************************
3
4 $Id: copyf.c 1082 2008-07-19 22:37:36Z gyoung $
5
6 Copy functions
7
8 Copyright (c) 1993-98 M. Kimes
[1082]9 Copyright (c) 2001, 2008 Steven H.Levine
[29]10
[173]11 14 Sep 02 SHL Drop obsolete debug code
12 14 Oct 02 SHL Drop obsolete debug code
13 10 Nov 02 SHL docopyf - don't forget to terminate longname
[347]14 optimize longname logic
[173]15 01 Aug 04 SHL Rework lstrip/rstrip usage
16 28 May 05 SHL Drop debug code
[347]17 14 Jul 06 SHL Use Runtime_Error
[793]18 20 Aug 07 GKY Move #pragma alloc_text to end for OpenWatcom compat
[827]19 01 Sep 07 GKY Use xDosSetPathInfo to fix case where FS3 buffer crosses 64k boundry
[985]20 29 Feb 08 GKY Use xfree where appropriate
[1082]21 19 Jul 08 GKY Modify MakeTempName for use making temp directory names
[29]22
23***********************************************************************/
24
[907]25#include <stdlib.h>
26#include <string.h>
27#include <stdarg.h>
28#include <ctype.h>
29
[2]30#define INCL_DOS
31#define INCL_DOSERRORS
32#define INCL_WIN
[841]33#define INCL_LONGLONG
[2]34
[907]35#include "fm3str.h"
36#include "errutil.h" // Dos_Error...
37#include "strutil.h" // GetPString
[2]38#include "fm3dll.h"
[1039]39#include "fortify.h"
[2]40
[347]41static PSZ pszSrcFile = __FILE__;
42
[2]43#ifndef WinMoveObject
[551]44HOBJECT APIENTRY WinMoveObject(HOBJECT hObjectofObject,
45 HOBJECT hObjectofDest, ULONG ulReserved);
[2]46#endif
47#ifndef WinCopyObject
[551]48HOBJECT APIENTRY WinCopyObject(HOBJECT hObjectofObject,
49 HOBJECT hObjectofDest, ULONG ulReserved);
[2]50#endif
51
[1082]52char *MakeTempName(char *buffer, char *temproot, INT type)
[347]53{
[843]54 FILESTATUS3 fs3;
[551]55 APIRET rc;
56 char *p, *o;
[2]57
[1082]58 if (strlen(buffer) > 3 && buffer[strlen(buffer) - 1] != '\\')
59 strcat(buffer, "\\");
[2]60 p = o = buffer + strlen(buffer);
[1082]61 switch (type) {
62 case 0:
63 sprintf(p, "%08lx.%03lx", rand() & 4095L, mypid);
64 break;
65 case 1:
66 sprintf(p, "%s%04lx.%03lx", "$FM2", rand() & 4095L, mypid);
67 break;
68 case 2:
69 sprintf(p, "%s.%03x", temproot, (rand() & 4095));
70 break;
71 default:
72 break;
73 }
[2]74 p = buffer + (strlen(buffer) - 1);
[551]75 for (;;) {
[2]76 DosError(FERR_DISABLEHARDERR);
[843]77 rc = DosQueryPathInfo(buffer, FIL_STANDARD, &fs3, sizeof(fs3));
[551]78 if (rc == ERROR_DISK_CHANGE) {
[2]79 DosError(FERR_ENABLEHARDERR);
[843]80 rc = DosQueryPathInfo(buffer, FIL_STANDARD, &fs3, sizeof(fs3));
[2]81 }
[551]82 if (rc)
[2]83 break;
[551]84 Loop:
85 if (p < o) {
[2]86 *buffer = 0;
87 return NULL;
88 }
[551]89 if ((*p) + 1 < 'Z' + 1) {
[2]90 (*p)++;
[551]91 while (strchr("*?<>\":/\\|+=;,[]. ", *p))
92 (*p)++;
[2]93 *p = toupper(*p);
94 }
95 else {
96 p--;
[551]97 if (p >= o && *p == '.')
98 p--;
[2]99 goto Loop;
100 }
101 }
102 return buffer;
103}
104
[551]105CHAR *TruncName(CHAR * oldname, CHAR * buffer)
[347]106{
[551]107 CHAR *p, *f, *s, *o;
[843]108 FILESTATUS3 fs3;
[551]109 APIRET rc;
[2]110
[551]111 if (!buffer || !oldname || !*oldname) {
112 if (buffer)
[2]113 *buffer = 0;
114 return NULL;
115 }
[551]116 strcpy(buffer, oldname);
117 f = strrchr(buffer, '\\');
118 if (!f)
119 f = strrchr(buffer, '/');
120 if (!f)
[2]121 f = buffer;
122 else
123 f++;
124 p = f;
125 o = p;
126 f = oldname + (f - buffer);
127 strupr(buffer);
[551]128 while (*f == '.') /* skip leading '.'s */
[2]129 f++;
130 s = f;
[551]131 while (*f && *f != '.' && f < s + 8) { /* skip past rootname */
[2]132 *p = toupper(*f);
133 p++;
134 f++;
135 }
[551]136 while (*f == '.')
[2]137 f++;
138 s = f;
[551]139 f = strrchr(f, '.');
140 if (f) {
141 while (*f == '.')
[2]142 f++;
143 }
[551]144 if (f && *(f + 1))
[2]145 s = f;
146 else
147 f = s;
[551]148 if (*f) {
[2]149 *p = '.';
150 p++;
[551]151 while (*f && *f != '.' && f < s + 3) {
[2]152 *p = toupper(*f);
153 p++;
154 f++;
155 }
156 }
157 *p = 0;
158
159 p = o;
[551]160 while (*p) {
161 if (strchr("*?<>\":/\\|+=;,[] ", *p) || *p < 0x20)
[2]162 *p = '_';
[551]163 if (*p == '.' && *(p + 1) == '.')
[2]164 *(p + 1) = '_';
165 p++;
166 }
167
168 p = o + (strlen(o) - 1);
[551]169 for (;;) {
[2]170 DosError(FERR_DISABLEHARDERR);
[843]171 rc = DosQueryPathInfo(buffer, FIL_STANDARD, &fs3, sizeof(fs3));
[551]172 if (rc == ERROR_DISK_CHANGE) {
[2]173 DosError(FERR_ENABLEHARDERR);
[843]174 rc = DosQueryPathInfo(buffer, FIL_STANDARD, &fs3, sizeof(fs3));
[2]175 }
[551]176 if (rc)
[2]177 break;
[551]178 Loop:
179 if (p < o) {
[2]180 *buffer = 0;
181 return NULL;
182 }
[551]183 if ((*p) + 1 < 'Z' + 1) {
[2]184 (*p)++;
[551]185 while (strchr("*?<>\":/\\|+=;,[]. ", *p))
186 (*p)++;
[2]187 *p = toupper(*p);
188 }
189 else {
190 p--;
[551]191 if (p >= o && *p == '.')
192 p--;
[2]193 goto Loop;
194 }
195 }
196 return buffer;
197}
198
[551]199CHAR *GetLongName(CHAR * oldname, CHAR * longname)
[347]200{
[551]201 if (!longname)
[2]202 return NULL;
203 *longname = 0;
[551]204 if (!oldname || !*oldname)
[2]205 return NULL;
[551]206 if (IsFullName(oldname)) {
[2]207
[551]208 APIRET rc;
209 EAOP2 eaop;
[2]210 PGEA2LIST pgealist;
211 PFEA2LIST pfealist;
[551]212 PGEA2 pgea;
213 PFEA2 pfea;
214 CHAR *value;
[2]215
[551]216 strcpy(longname, oldname);
[2]217 value = longname;
[551]218 while (*value) {
219 if (*value == '/')
220 *value = '\\';
[2]221 value++;
222 }
[551]223 value = strrchr(longname, '\\');
224 if (value) {
[2]225 value++;
226 *value = 0;
227 }
[551]228 pgealist = xmallocz(sizeof(GEA2LIST) + 32, pszSrcFile, __LINE__);
[347]229 if (pgealist) {
[2]230 pgea = &pgealist->list[0];
[551]231 strcpy(pgea->szName, LONGNAME);
[2]232 pgea->cbName = strlen(pgea->szName);
233 pgea->oNextEntryOffset = 0L;
234 pgealist->cbList = (sizeof(GEA2LIST) + pgea->cbName);
[551]235 pfealist = xmallocz(1536, pszSrcFile, __LINE__);
[347]236 if (pfealist) {
[551]237 pfealist->cbList = 1024;
238 eaop.fpGEA2List = pgealist;
239 eaop.fpFEA2List = pfealist;
240 eaop.oError = 0L;
241 DosError(FERR_DISABLEHARDERR);
242 rc = DosQueryPathInfo(oldname,
243 FIL_QUERYEASFROMLIST,
244 (PVOID) & eaop, (ULONG) sizeof(EAOP2));
245 if (!rc) {
246 pfea = &eaop.fpFEA2List->list[0];
247 value = pfea->szName + pfea->cbName + 1;
248 value[pfea->cbValue] = 0;
249 if (*(USHORT *) value == EAT_ASCII)
250 strncat(longname,
251 value + (sizeof(USHORT) * 2),
252 CCHMAXPATH - strlen(longname));
253 longname[CCHMAXPATH - 1] = 0;
254 }
[1039]255 free(pfealist);
[2]256 }
[1039]257 free(pgealist);
[2]258 }
259 }
260 return longname;
261}
262
[551]263BOOL ZapLongName(char *filename)
[347]264{
[29]265 return WriteLongName(filename, "");
[2]266}
267
[551]268BOOL WriteLongName(CHAR * filename, CHAR * longname)
[347]269{
[551]270 APIRET rc;
271 EAOP2 eaop;
[2]272 PFEA2LIST pfealist = NULL;
[551]273 ULONG ealen;
274 USHORT len;
275 CHAR *eaval, *p;
[2]276
[551]277 if (!filename || !*filename || !longname)
[2]278 return FALSE;
[551]279 p = strrchr(longname, '\\');
280 if (p)
281 memmove(longname, p + 1, strlen(p + 1) + 1);
282 p = strrchr(longname, '/');
283 if (p)
284 memmove(longname, p + 1, strlen(p + 1) + 1);
[123]285 bstrip(longname);
[2]286 len = strlen(longname);
[551]287 if (len)
[2]288 ealen = sizeof(FEA2LIST) + 10 + len + 4;
289 else
290 ealen = sizeof(FEALIST) + 10;
[551]291 rc = DosAllocMem((PPVOID) & pfealist,
292 ealen + 32L, OBJ_TILE | PAG_COMMIT | PAG_READ | PAG_WRITE);
[347]293 if (rc)
[551]294 Dos_Error(MB_CANCEL, rc, HWND_DESKTOP, pszSrcFile, __LINE__,
295 GetPString(IDS_OUTOFMEMORY));
[347]296 else {
[551]297 memset(pfealist, 0, ealen + 1);
[2]298 pfealist->cbList = ealen;
[841]299 pfealist->list[0].oNextEntryOffset = 0;
[2]300 pfealist->list[0].fEA = 0;
301 pfealist->list[0].cbName = 9;
[551]302 strcpy(pfealist->list[0].szName, LONGNAME);
303 if (len) {
[2]304 eaval = pfealist->list[0].szName + 10;
[551]305 *(USHORT *) eaval = (USHORT) EAT_ASCII;
[2]306 eaval += sizeof(USHORT);
[551]307 *(USHORT *) eaval = (USHORT) len;
[2]308 eaval += sizeof(USHORT);
[551]309 memcpy(eaval, longname, len);
[2]310 pfealist->list[0].cbValue = len + (sizeof(USHORT) * 2);
311 }
312 else
313 pfealist->list[0].cbValue = 0;
[551]314 eaop.fpGEA2List = (PGEA2LIST) 0;
[2]315 eaop.fpFEA2List = pfealist;
316 eaop.oError = 0L;
317 DosError(FERR_DISABLEHARDERR);
[827]318 rc = xDosSetPathInfo(filename, FIL_QUERYEASIZE,
319 &eaop, sizeof(eaop), DSPI_WRTTHRU);
[2]320 DosFreeMem(pfealist);
[551]321 if (rc)
[2]322 return FALSE;
323 }
324 return TRUE;
325}
326
[551]327BOOL AdjustWildcardName(CHAR * oldname, CHAR * newname)
[347]328{
[2]329 BOOL ret = FALSE;
330
[827]331 /* NOTE: newname should be CCHMAXPATH chars long! */
[2]332
[551]333 if (strchr(newname, '*') || strchr(newname, '?')) {
[2]334
[551]335 CHAR srce[CCHMAXPATHCOMP], dest[CCHMAXPATHCOMP], result[CCHMAXPATHCOMP],
336 *p;
[2]337
[551]338 p = strrchr(newname, '\\');
339 if (p && *(p + 1)) {
340 strcpy(dest, p + 1);
341 p = strrchr(oldname, '\\');
342 if (p && *(p + 1)) {
343 strcpy(srce, p + 1);
344 DosError(FERR_DISABLEHARDERR);
345 if (!DosEditName(1L, srce, dest, result, (ULONG) sizeof(result))) {
346 p = strrchr(newname, '\\');
347 p++;
348 strcpy(p, result);
349 ret = TRUE;
350 }
[2]351 }
352 }
353 }
354 return ret;
355}
356
[551]357CHAR default_disk(VOID)
[347]358{
[551]359 ULONG ulDriveNum, ulDriveMap;
[2]360
361 DosError(FERR_DISABLEHARDERR);
[551]362 DosQCurDisk(&ulDriveNum, &ulDriveMap);
363 return (CHAR) toupper((INT) ulDriveNum) + '@';
[2]364}
365
366#ifdef NEVER
367
[551]368APIRET docopyallf(INT type, CHAR * oldname, CHAR * newname, ...)
[347]369{
[847]370 FILEFINDBUF3 fb;
[551]371 ULONG nm;
372 HDIR hdir;
373 APIRET rc = 0;
374 CHAR *enddir, fullname[CCHMAXPATH];
[2]375
[551]376 va_start(ap, newname);
377 vsprintf(fullname, newname, ap);
[2]378 va_end(ap);
379
380 DosError(FERR_DISABLEHARDERR);
[847]381 if (!DosFindFirst(oldname)) {
[2]382 do {
383
384 /* build target name */
385
[551]386 if (fb.attrFile & FILE_DIRECTORY) {
387 DosError(FERR_ENABLEHARDERR);
388 rc = DosCreateDir();
389 if (rc == ERROR_INVALID_NAME || rc == ERROR_FILENAME_EXCED_RANGE) {
[2]390
[551]391 /* truncate directory name */
[827]392 /* create that directory */
[551]393 /* update containers for name used */
[2]394
[551]395 }
396 rc = docopyallf(type,, "%s",); /* recurse */
[2]397 }
398 else
[551]399 rc = docopyf(type,, "%s",); /* copy file */
[2]400 DosError(FERR_DISABLEHARDERR);
[847]401 } while (!rc && !DosFindNext());
[2]402 DosFindClose(hdir);
403 }
404 else
405 rc = ERROR_FILE_NOT_FOUND;
406 return rc;
407}
408
409#endif
410
[551]411APIRET docopyf(INT type, CHAR * oldname, CHAR * newname, ...)
[347]412{
[2]413 /*
414 * returns:
415 * 0: success
416 * -1: bad string parameter(s)
417 * -2: source didn't exist
418 * -3: bad type
[827]419 * anything else: API return
[2]420 */
421
[551]422 CHAR fullnewname[CCHMAXPATH + 1], longname[CCHMAXPATH],
423 shortname[CCHMAXPATH];
424 CHAR olddisk, newdisk, dir[CCHMAXPATH], *p, *pp;
425 APIRET ret = -1, rc;
[841]426 FILESTATUS3L st, st2, dummy;
[551]427 BOOL diskchange = FALSE, zaplong = FALSE;
428 va_list ap;
[2]429
[45]430 *fullnewname = *shortname = *dir = 0;
[2]431
[551]432 va_start(ap, newname);
433 vsprintf(fullnewname, newname, ap);
[2]434 va_end(ap);
435
[551]436 if (!oldname || !*oldname || !*fullnewname) /* bad string args */
437 return (APIRET) - 1;
[29]438
[2]439 DosError(FERR_DISABLEHARDERR);
[841]440 if (DosQueryPathInfo(oldname, FIL_STANDARDL, &st, sizeof(FILESTATUS3L)))
[551]441 return (APIRET) - 2; /* no source */
[29]442
[551]443 AdjustWildcardName(oldname, fullnewname);
[2]444 MakeFullName(oldname);
445 MakeFullName(fullnewname);
[551]446 olddisk = toupper(*oldname); /* source drive */
447 newdisk = toupper(*fullnewname); /* destination drive */
448 if (!(driveflags[toupper(*oldname) - 'A'] & DRIVE_NOLONGNAMES))
[45]449 *longname = 0;
[551]450 else {
[45]451 GetLongName(oldname, longname);
[551]452 if (*longname) {
[2]453 p = RootName(longname);
[551]454 if (p != longname)
455 memmove(longname, p, strlen(p) + 1);
[2]456 }
[45]457 }
458 /* If root name changed make sure longname EA goes away */
459 p = RootName(oldname);
460 pp = RootName(fullnewname);
[551]461 if (stricmp(p, pp)) {
[45]462 zaplong = TRUE;
[2]463 }
464
465 DosError(FERR_DISABLEHARDERR);
[551]466 switch (type) {
467 case WPSMOVE:
468 {
469 HOBJECT hobjsrc;
470 HOBJECT hobjdest;
[2]471
[551]472 ret = ERROR_FILE_NOT_FOUND;
473 hobjsrc = WinQueryObject(oldname);
474 if (hobjsrc) {
475 strcpy(dir, fullnewname);
476 p = strrchr(dir, '\\');
477 if (p < dir + 3)
478 p++;
479 *p = 0;
480 ret = ERROR_PATH_NOT_FOUND;
481 hobjdest = WinQueryObject(dir);
482 if (hobjdest) {
483 ret = ERROR_GEN_FAILURE;
484 hobjsrc = WinMoveObject(hobjsrc, hobjdest, 0);
485 if (hobjsrc)
486 ret = 0;
487 }
[2]488 }
[551]489 }
490 return ret;
[2]491
[551]492 case WPSCOPY:
493 {
494 HOBJECT hobjsrc;
495 HOBJECT hobjdest;
[2]496
[551]497 ret = ERROR_FILE_NOT_FOUND;
498 hobjsrc = WinQueryObject(oldname);
499 if (hobjsrc) {
500 strcpy(dir, fullnewname);
501 p = strrchr(dir, '\\');
502 if (p < dir + 3)
503 p++;
504 *p = 0;
505 ret = ERROR_PATH_NOT_FOUND;
506 hobjdest = WinQueryObject(dir);
507 if (hobjdest) {
508 ret = ERROR_GEN_FAILURE;
509 hobjsrc = WinCopyObject(hobjsrc, hobjdest, 0);
510 if (hobjsrc)
511 ret = 0;
512 }
[2]513 }
[551]514 }
515 return ret;
[2]516
[551]517 case MOVE:
518 *dir = 0;
519 if (olddisk == newdisk) { /* same drive */
520 /* make temporary copy in case move fails */
521 if (IsFile(fullnewname) != -1 && stricmp(oldname, fullnewname)) {
522 strcpy(dir, fullnewname);
523 p = strrchr(dir, '\\');
524 if (p)
525 *p = 0;
526 strcat(dir, "\\");
[1082]527 MakeTempName(dir, NULL, 0);
[551]528 if (DosMove(fullnewname, dir))
529 *dir = 0;
[2]530 }
[551]531 DosError(FERR_DISABLEHARDERR);
532 ret = DosMove(oldname, fullnewname); /* move it */
533 if (ret && *dir) { /* failed -- clean up */
534 DosError(FERR_DISABLEHARDERR);
535 if (!DosMove(dir, fullnewname))
536 Broadcast((HAB) 0, hwndMain, UM_UPDATERECORD, MPFROMP(dir), MPVOID);
537 }
538 else if (!ret && *dir) {
539 if (!IsFile(dir)) {
540 if (!strchr(dir, '?') && !strchr(dir, '*'))
541 wipeallf("%s\\*", dir);
542 DosError(FERR_DISABLEHARDERR);
543 if (DosDeleteDir(dir)) {
544 make_deleteable(dir);
545 DosDeleteDir(dir);
546 }
547 }
548 else if (IsFile(dir) > 0) {
549 DosError(FERR_DISABLEHARDERR);
550 if (DosForceDelete(dir)) {
551 make_deleteable(dir);
552 DosForceDelete(dir);
553 }
554 if (zaplong)
555 ZapLongName(dir);
556 Broadcast((HAB) 0, hwndMain, UM_UPDATERECORD, MPFROMP(dir), MPVOID);
557 }
558 }
559 }
560 else { /* different drives */
561 DosError(FERR_DISABLEHARDERR);
562 ret = DosCopy(oldname, fullnewname, DCPY_EXISTING); /* <=-NOTE! */
563 if (ret == ERROR_DISK_CHANGE) {
564 DosError(FERR_ENABLEHARDERR);
565 ret = DosCopy(oldname, fullnewname, DCPY_EXISTING);
566 diskchange = TRUE;
567 }
568 if (ret == ERROR_INVALID_NAME || ret == ERROR_FILENAME_EXCED_RANGE) {
569 if (TruncName(fullnewname, shortname)) { /* make 8.3 filename */
570 DosError(FERR_DISABLEHARDERR);
571 ret = DosCopy(oldname, shortname, DCPY_EXISTING);
572 if (!ret) { /* success -- write longname ea */
573 WriteLongName(shortname, fullnewname);
574 strcpy(fullnewname, shortname);
575 /* broadcast fixup msg to windows */
576 Broadcast((HAB) 0,
577 hwndMain, UM_UPDATERECORD, MPFROMP(shortname), MPVOID);
578 }
579 }
580 }
581 else if (!ret && *longname) {
[2]582
[551]583 CHAR fixname[CCHMAXPATH];
[2]584
[551]585 strcpy(fixname, fullnewname);
586 p = strrchr(fixname, '\\');
587 if (p) {
588 p++;
589 *p = 0;
590 }
591 strcat(fixname, longname);
592 DosError(FERR_DISABLEHARDERR);
593 DosMove(fullnewname, fixname);
594 strcpy(fullnewname, fixname);
595 if (zaplong)
596 ZapLongName(fixname);
597 Broadcast((HAB) 0,
598 hwndMain, UM_UPDATERECORD, MPFROMP(fixname), MPVOID);
[2]599 }
[551]600 if (!ret) { /* double-check success */
601 DosError(FERR_DISABLEHARDERR);
602 rc = DosQueryPathInfo(fullnewname,
[841]603 FIL_STANDARDL, &st2, sizeof(FILESTATUS3L));
[551]604 if (rc == ERROR_DISK_CHANGE) {
605 DosError(FERR_ENABLEHARDERR);
606 rc = DosQueryPathInfo(fullnewname,
[841]607 FIL_STANDARDL, &st2, sizeof(FILESTATUS3L));
[551]608 }
609 if (!rc && st2.cbFile == st.cbFile) { /* seems to have worked... */
610 DosError(FERR_DISABLEHARDERR);
611 if (diskchange) {
612 DosError(FERR_ENABLEHARDERR);
[841]613 DosQueryPathInfo(oldname, FIL_STANDARDL, &dummy, sizeof(FILESTATUS3L)); /* force disk change */
[551]614 }
615 if (!(st2.attrFile & FILE_DIRECTORY)) /* erase file */
616 unlinkf("%s", oldname);
617 else { /* remove directory */
618 wipeallf("%s\\*", oldname);
619 DosError(FERR_DISABLEHARDERR);
620 if (DosDeleteDir(oldname)) {
621 make_deleteable(oldname);
622 DosDeleteDir(oldname);
623 }
624 }
625 }
626 }
627 }
628 return ret;
[2]629
[551]630 case COPY:
631 DosError(FERR_DISABLEHARDERR);
632 ret = DosCopy(oldname, fullnewname, DCPY_EXISTING); /* <=-NOTE! */
633 if (ret == ERROR_DISK_CHANGE) {
634 DosError(FERR_ENABLEHARDERR);
635 ret = DosCopy(oldname, fullnewname, DCPY_EXISTING);
636 diskchange = TRUE;
637 }
638 if (ret == ERROR_INVALID_NAME || ret == ERROR_FILENAME_EXCED_RANGE) {
639 if (TruncName(fullnewname, shortname)) {
640 DosError((diskchange) ? FERR_ENABLEHARDERR : FERR_DISABLEHARDERR);
641 ret = DosCopy(oldname, shortname, DCPY_EXISTING);
642 if (!ret) {
643 WriteLongName(shortname, fullnewname);
644 strcpy(fullnewname, shortname);
645 Broadcast((HAB) 0,
646 hwndMain, UM_UPDATERECORD, MPFROMP(shortname), MPVOID);
647 }
[2]648 }
[551]649 }
650 else if (!ret && *longname) {
[2]651
[551]652 CHAR fixname[CCHMAXPATH];
[2]653
[551]654 strcpy(fixname, fullnewname);
655 p = strrchr(fixname, '\\');
656 if (p) {
657 p++;
658 *p = 0;
[2]659 }
[551]660 strcat(fixname, longname);
661 DosError(FERR_DISABLEHARDERR);
662 DosMove(fullnewname, fixname);
663 if (zaplong)
664 ZapLongName(fixname);
665 Broadcast((HAB) 0, hwndMain, UM_UPDATERECORD, MPFROMP(fixname), MPVOID);
666 }
667 return ret;
[2]668
[551]669 default: /* shouldn't happen */
670 Runtime_Error(pszSrcFile, __LINE__, "bad case %u", type);
671 break;
[2]672 }
[551]673 return (APIRET) - 3; /* bad type */
[2]674}
675
[551]676INT make_deleteable(CHAR * filename)
[347]677{
[2]678 INT ret = -1;
[847]679 FILESTATUS3 fsi;
[2]680
681 DosError(FERR_DISABLEHARDERR);
[847]682 if (!DosQueryPathInfo(filename, FIL_STANDARD, &fsi, sizeof(fsi))) {
[2]683 fsi.attrFile = 0;
684 DosError(FERR_DISABLEHARDERR);
[847]685 if (!xDosSetPathInfo(filename, FIL_STANDARD, &fsi, sizeof(fsi), 0))
[2]686 ret = 0;
687 }
688 return ret;
689}
690
[827]691INT wipeallf(CHAR *string, ...)
[347]692{
[2]693 /* unlink everything from directory on down... */
694
[847]695 FILEFINDBUF3 *f;
[551]696 HDIR search_handle;
697 ULONG num_matches;
698 CHAR *p, *ss, *str;
699 CHAR s[CCHMAXPATH], mask[257];
700 va_list ap;
701 INT rc;
[2]702
[551]703 va_start(ap, string);
704 vsprintf(s, string, ap);
[2]705 va_end(ap);
706
[551]707 if (!*s)
[2]708 return -1;
709 p = s;
[551]710 while ((p = strchr(p, '/')) != NULL) {
[2]711 *p = '\\';
712 p++;
713 }
714
[551]715 str = xstrdup(s, pszSrcFile, __LINE__);
716 if (!str)
[2]717 return -1;
718
[551]719 { /* safety net -- disallow deleting a root dir or partial name */
[2]720 CHAR temp;
721
[551]722 p = strrchr(str, '\\');
723 if (p) {
[2]724 p++;
725 temp = *p;
726 *p = 0;
[551]727 if (IsRoot(str) || !IsFullName(str)) {
728 /* under no circumstances! */
729 Runtime_Error(pszSrcFile, __LINE__, "bad name %s", str);
[1039]730 free(str);
[551]731 return -1;
[2]732 }
733 *p = temp;
734 }
735 }
736
737 p = s;
[551]738 p = strrchr(s, '\\'); /* strip s to just path */
739 if (!p)
740 p = strrchr(s, ':');
741 if (p) {
[2]742 p++;
[551]743 strncpy(mask, p, 256);
[2]744 mask[256] = 0;
745 *p = 0;
746 }
747 else {
748 *mask = 0;
749 *s = 0;
750 }
751
[551]752 ss = xmalloc(CCHMAXPATH, pszSrcFile, __LINE__);
[847]753 f = xmalloc(sizeof(FILEFINDBUF3), pszSrcFile, __LINE__);
[347]754 if (!ss || !f) {
[1009]755 xfree(ss, pszSrcFile, __LINE__);
756 xfree(f, pszSrcFile, __LINE__);
[1039]757 free(str);
[2]758 return -1;
759 }
760
761 search_handle = HDIR_CREATE;
[841]762 num_matches = 1;
[2]763
764 DosError(FERR_DISABLEHARDERR);
[847]765 if (!DosFindFirst(str, &search_handle, FILE_NORMAL | FILE_DIRECTORY |
[838]766 FILE_SYSTEM | FILE_READONLY | FILE_HIDDEN | FILE_ARCHIVED,
[847]767 f, sizeof(FILEFINDBUF3), &num_matches, FIL_STANDARD)) {
[2]768
[551]769 strcpy(ss, s);
[2]770 p = &ss[strlen(ss)];
771
772 do {
[551]773 strcpy(p, f->achName);
774 if (f->attrFile & FILE_DIRECTORY) {
775 if (strcmp(f->achName, ".") && strcmp(f->achName, "..")) {
776 wipeallf("%s/%s", ss, mask); /* recurse to wipe files */
777 DosError(FERR_DISABLEHARDERR);
778 if (DosDeleteDir(ss)) { /* remove directory */
779 make_deleteable(ss);
780 DosError(FERR_DISABLEHARDERR);
781 DosDeleteDir(ss);
782 }
783 }
[2]784 }
785 else {
[551]786 DosError(FERR_DISABLEHARDERR);
787 if (DosForceDelete(ss)) {
788 make_deleteable(ss);
789 DosError(FERR_DISABLEHARDERR);
790 rc = (INT) DosForceDelete(ss);
791 if (rc)
792 return rc;
793 }
[2]794 }
[847]795 num_matches = 1;
[2]796 DosError(FERR_DISABLEHARDERR);
[847]797 } while (!DosFindNext(search_handle, f, sizeof(FILEFINDBUF3),
798 &num_matches));
[2]799 DosFindClose(search_handle);
800 }
801
[1039]802 free(f);
803 free(ss);
804 free(str);
[2]805 return 0;
806}
807
[551]808INT unlink_allf(CHAR * string, ...)
[347]809{
[2]810 /* wildcard delete */
811
[847]812 FILEFINDBUF3 *f;
[551]813 HDIR search_handle;
[2]814 ULONG num_matches;
[551]815 CHAR *p, *ss, *str;
816 CHAR s[CCHMAXPATH];
[2]817 va_list ap;
818
[551]819 va_start(ap, string);
820 vsprintf(s, string, ap);
[2]821 va_end(ap);
822
[551]823 if (!*s)
[2]824 return -1;
825 p = s;
[551]826 while ((p = strchr(p, '/')) != NULL) {
[2]827 *p = '\\';
828 p++;
829 }
830
[551]831 str = xstrdup(s, pszSrcFile, __LINE__);
[347]832 if (!str)
[2]833 return -1;
834
835 p = s;
[551]836 p = strrchr(s, '\\'); /* strip s to just path */
837 if (!p)
838 p = strrchr(s, ':');
839 if (p) {
[2]840 p++;
841 *p = 0;
842 }
843 else
844 *s = 0;
845
[551]846 ss = xmalloc(CCHMAXPATH, pszSrcFile, __LINE__);
[847]847 f = xmalloc(sizeof(FILEFINDBUF3), pszSrcFile, __LINE__);
[347]848 if (!ss || !f) {
[1009]849 xfree(ss, pszSrcFile, __LINE__);
850 xfree(f, pszSrcFile, __LINE__);
[1039]851 free(str);
[2]852 return -1;
853 }
854
855 search_handle = HDIR_CREATE;
[838]856 num_matches = 1;
[2]857
858 DosError(FERR_DISABLEHARDERR);
[847]859 if (!DosFindFirst(str, &search_handle, FILE_NORMAL, f,
860 sizeof(FILEFINDBUF3), &num_matches, FIL_STANDARD)) {
[2]861
[551]862 strcpy(ss, s);
[2]863 p = &ss[strlen(ss)];
864
865 do {
[551]866 strcpy(p, f->achName);
867 unlinkf("%s", ss);
[838]868 num_matches = 1;
[2]869 DosError(FERR_DISABLEHARDERR);
[847]870 } while (!DosFindNext(search_handle, f, sizeof(FILEFINDBUF3),
871 &num_matches));
[2]872 DosFindClose(search_handle);
873 }
874
[1039]875 free(f);
876 free(ss);
877 free(str);
[2]878 return 0;
879}
880
[551]881INT unlinkf(CHAR * string, ...)
[347]882{
[2]883 CHAR buffer[CCHMAXPATH];
884 va_list ap;
885
[551]886 va_start(ap, string);
887 vsprintf(buffer, string, ap);
[2]888 va_end(ap);
889
[551]890 if (!strstr(buffer, ArcTempRoot)) {
[2]891 DosError(FERR_DISABLEHARDERR);
[551]892 if (DosDelete(buffer)) {
[2]893 make_deleteable(buffer);
894 DosError(FERR_DISABLEHARDERR);
895 return DosDelete(buffer);
896 }
897 }
898 else {
899 DosError(FERR_DISABLEHARDERR);
[551]900 if (DosForceDelete(buffer)) {
[2]901 make_deleteable(buffer);
902 DosError(FERR_DISABLEHARDERR);
903 return DosForceDelete(buffer);
904 }
905 }
906 return 0;
907}
[793]908
909#pragma alloc_text(LONGNAMES,TruncName,GetLongName,WriteLongName)
910#pragma alloc_text(LONGNAMES,ZapLongName,AdjustWildcardName)
[1082]911#pragma alloc_text(COPYF,default_disk,docopyf,MakeTempName)
[793]912#pragma alloc_text(UNLINKF,unlinkf,unlink_allf,make_deleteable,wipeallf)
Note: See TracBrowser for help on using the repository browser.