source: trunk/dll/copyf.c@ 985

Last change on this file since 985 was 985, checked in by Gregg Young, 18 years ago

Update sizes dialog (ticket 44); Make max command line length user settable (ticket 199); use xfree for free in most cases (ticket 212); initial code to check for valid ini file (ticket 102); Some additional refactoring and structure rework; Some documentation updates;

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