source: trunk/dll/copyf.c@ 1039

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

Removed unnecessary xfrees and included fortify.h where needed; moved several misplaced (x)frees;

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