2 Copyright © 1995-2008, The AROS Development Team. All rights reserved.
8 /*****************************************************************************
16 Rename [{FROM}] <name> [TO|AS] <name> [QUIET]
18 FROM/A/M,TO=AS/A,QUIET/S
26 Renames a directory or file. Rename can also act like the UNIX mv
27 command, which moves a file or files to another location on disk.
31 FROM -- The name(s) of the file(s) to rename or move. There may
32 be many files specified, this is used when moving files
35 TO|AS -- The name which we wish to call the file.
37 QUIET -- Suppress any output from the command.
41 Standard DOS error codes.
47 Rename letter1.doc letter2.doc letters
49 Moves letter1.doc and letter2.doc to the directory letters.
51 Rename ram:a ram:b quiet
52 Rename from ram:a to ram:b quiet
53 Rename from=ram:a to=ram:b quiet
55 All versions, renames file "a" to "b" and does not output any
56 diagnostic information.
64 Rename() can only move a file to another directory, if and only if
65 the to path has the from filename appended to the end.
68 Rename("ram:a", "ram:clipboards/a");
70 Rename("ram:a", "ram:clipboards/");
72 ******************************************************************************/
75 #include <aros/debug.h>
77 #include <proto/dos.h>
78 #include <proto/exec.h>
81 #include <dos/dosasl.h>
82 #include <dos/rdargs.h>
83 #include <exec/memory.h>
84 #include <exec/types.h>
89 #define ARG_TEMPLATE "FROM/A/M,TO=AS/A,QUIET/S"
91 #define APPNAME "Rename"
102 #define MAX_PATH_LEN 2048
104 const TEXT version
[] = "$VER: Rename 41.2 (23.11.2000)\n";
107 int doRename(STRPTR
*from
, STRPTR to
, BOOL quiet
);
116 IPTR args
[NOOFARGS
] = { (IPTR
) NULL
, (IPTR
) NULL
, FALSE
};
118 int retval
= RETURN_FAIL
;
120 rda
= ReadArgs(ARG_TEMPLATE
, args
, NULL
);
124 STRPTR
*from
= (STRPTR
*)args
[ARG_FROM
];
125 STRPTR to
= (STRPTR
)args
[ARG_TO
];
126 BOOL quiet
= args
[ARG_QUIET
] != 0;
128 retval
= doRename(from
, to
, quiet
);
134 PrintFault(IoErr(), APPNAME
);
135 retval
= RETURN_ERROR
;
142 int doRename(STRPTR
*from
, STRPTR to
, BOOL quiet
)
144 #define ERROR(n) retval = (n); goto cleanup
146 struct AnchorPath
*ap
;
150 BOOL destIsDir
= FALSE
;
151 BOOL destExists
= FALSE
;
160 ap
= (struct AnchorPath
*)AllocVec(sizeof(struct AnchorPath
) + MAX_PATH_LEN
+ MAX_PATH_LEN
,
161 MEMF_ANY
| MEMF_CLEAR
);
168 pathName
= ((UBYTE
*) (ap
+ 1)) + MAX_PATH_LEN
;
170 ap
->ap_BreakBits
= SIGBREAKF_CTRL_C
;
171 ap
->ap_Flags
= APF_DOWILD
;
172 ap
->ap_Strlen
= MAX_PATH_LEN
;
173 if (MatchFirst(from
[0], ap
) != 0)
176 if (ioerr
== ERROR_OBJECT_NOT_FOUND
)
178 Printf("Can't rename %s as %s because ", from
[0], to
);
182 itsWild
= ap
->ap_Flags
& APF_ITSWILD
;
185 /* First we check if the destination is a directory */
186 tolock
= Lock(to
, SHARED_LOCK
);
189 struct FileInfoBlock
*fib
= AllocDosObject(DOS_FIB
, NULL
);
196 PrintFault(IoErr(), APPNAME
);
201 i
= Examine(tolock
, fib
);
202 entrytype
= fib
->fib_EntryType
;
203 FreeDosObject(DOS_FIB
, fib
);
214 PrintFault(IoErr(), APPNAME
);
221 /* Check if dest is not a dir and src is pattern or multi */
222 if (!destIsDir
&& (itsWild
|| from
[1]))
224 Printf("Destination \"%s\" is not a directory.\n", to
);
229 /* Handle single file name change */
230 isSingle
=!destIsDir
;
231 /* 15th Jan 2004 bugfix, (destIsDir && ...) not (!destisDir && ...) ! - Piru */
232 if (destIsDir
&& !from
[1])
236 fromlock
= Lock(from
[0], ACCESS_READ
);
239 isSingle
= SameLock(fromlock
, tolock
) == LOCK_SAME
;
244 /* 4th May 2003 bugfix: be quiet about single object renames - Piru */
249 if (ParsePattern(from
[0], pathName
, MAX_PATH_LEN
) > -1 &&
250 Rename(pathName
, to
))
256 Printf("Can't rename %s as %s because ", from
[0], to
);
262 if (!NameFromLock(tolock
, pathName
, MAX_PATH_LEN
))
264 if (IoErr() == ERROR_LINE_TOO_LONG
)
266 PrintFault(IoErr(), APPNAME
);
277 stccpy(pathName
, to
, MAX_PATH_LEN
);
281 /* Now either only one specific file should be renamed or the
282 destination is really a directory. We can use the same routine
285 fileStart
= pathName
+ strlen(pathName
);
287 ap
->ap_BreakBits
= SIGBREAKF_CTRL_C
;
288 ap
->ap_Strlen
= MAX_PATH_LEN
;
290 for (i
= 0; from
[i
]; i
++)
292 for (match
= MatchFirst(from
[i
], ap
); match
== 0; match
= MatchNext(ap
))
294 /* Check for identical 'from' and 'to'? */
298 /* Clear former filename */
300 if (!AddPart(pathName
, FilePart(ap
->ap_Buf
), MAX_PATH_LEN
))
304 PrintFault(ERROR_LINE_TOO_LONG
, APPNAME
);
305 SetIoErr(ERROR_LINE_TOO_LONG
);
313 Printf("Renaming %s as %s\n", ap
->ap_Buf
, pathName
);
316 if (!Rename(ap
->ap_Buf
, pathName
))
321 Printf("Can't rename %s as %s because ", ap
->ap_Buf
, pathName
);
329 if (ap
->ap_FoundBreak
& SIGBREAKF_CTRL_C
)
331 PrintFault(ERROR_BREAK
, NULL
);
333 retval
= RETURN_WARN
;
349 PrintFault(ioerr
, NULL
);
351 //retval = ERROR_FAIL;