source: trunk/dll/copyf.c@ 1206

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

Ticket 187: Move datadevlarations/definitions out of fm3dll.h

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