source: trunk/dll/copyf.c@ 1570

Last change on this file since 1570 was 1520, checked in by John Small, 15 years ago

Syntatic improvement on changeset 1502.

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