source: trunk/dll/copyf.c@ 1469

Last change on this file since 1469 was 1469, checked in by Steven Levine, 16 years ago

Enhance compare directories - support AND'ed selections, rework CompSelect for size and speed,
allow fast cancel, drop unused reset logic, more context menu items

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