source: trunk/dll/copyf.c@ 1163

Last change on this file since 1163 was 1163, checked in by John Small, 17 years ago

Ticket 187: Draft 1: Functions only

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