source: trunk/dll/copyf.c@ 1193

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

Improved comment on new "#if 0" lines.

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