delint
[AROS.git] / rom / dos / rename.c
blobb92618e51c4474cdfd4bf541b0e6d0adc0495de1
1 /*
2 Copyright © 1995-2013, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Rename a file
6 Lang: english
7 */
9 #include <aros/debug.h>
10 #include <proto/exec.h>
11 #include "dos_intern.h"
12 #include <string.h>
14 /*****************************************************************************
16 NAME */
17 #include <exec/types.h>
18 #include <proto/dos.h>
20 AROS_LH2(LONG, Rename,
22 /* SYNOPSIS */
23 AROS_LHA(CONST_STRPTR, oldName, D1),
24 AROS_LHA(CONST_STRPTR, newName, D2),
26 /* LOCATION */
27 struct DosLibrary *, DOSBase, 13, Dos)
29 /* FUNCTION
30 Renames a given file. The old name and the new name must point to the
31 same volume.
33 INPUTS
34 oldName - Name of the file to rename
35 newName - New name of the file to rename
37 RESULT
38 boolean - DOSTRUE or DOSFALSE. IoErr() provides additional information
39 on DOSFALSE.
41 NOTES
43 EXAMPLE
45 BUGS
47 SEE ALSO
49 INTERNALS
51 *****************************************************************************/
53 AROS_LIBFUNC_INIT
55 struct DevProc *olddvp, *newdvp;
56 LONG status;
57 struct Process *me = (struct Process *)FindTask(NULL);
58 char buf1[256], vol[32];
59 char buf2[256];
60 int len;
61 BSTR bstrNewName, bstrOldName;
63 ASSERT_VALID_PROCESS(me);
65 len = SplitName(oldName, ':', vol, 0, sizeof(vol) - 1);
67 if (len > 0)
69 /* get real name */
70 BPTR lock = Lock(oldName, SHARED_LOCK);
71 if (lock)
73 if (NameFromLock(lock, buf1, sizeof(buf1) - 1))
74 oldName = buf1;
75 UnLock(lock);
78 else
80 /* convert to absolute path */
81 if (NameFromLock(me->pr_CurrentDir, buf1, sizeof(buf1) - 1))
83 int namelen = strlen(oldName);
84 len = strlen(buf1);
85 if (len + namelen < sizeof(buf1) - 1)
87 if (buf1[len - 1] != ':')
88 buf1[len++] = '/';
89 CopyMem(oldName, buf1 + len, namelen + 1);
90 oldName = buf1;
95 len = SplitName(newName, ':', vol, 0, sizeof(vol) - 1);
97 if (len > 0)
99 /* get real name of destination path */
100 BPTR lock;
101 char *pos;
102 const char *pos2;
104 strcpy(buf2, newName);
105 pos = strrchr(buf2, '/');
106 if (!pos)
108 pos = buf2 + len;
109 *pos = '\0';
111 else
112 *(++pos) = '\0'; /* Keep slashes in name, to support a/b//c => a/c case */
114 lock = Lock(buf2, SHARED_LOCK);
115 if (lock)
117 if (NameFromLock(lock, buf2, sizeof(buf2) - 1))
119 int namelen;
120 len = strlen(buf2);
121 pos2 = newName + (int)(pos - buf2);
122 namelen = strlen(pos2);
123 if (len + namelen < sizeof(buf2) - 1)
125 if (buf2[len - 1] != ':')
126 buf2[len++] = '/';
127 CopyMem(pos2, buf2 + len, namelen + 1);
128 newName = buf2;
131 UnLock(lock);
134 else
136 /* convert to absolute path */
137 if (NameFromLock(me->pr_CurrentDir, buf2, sizeof(buf2) - 1))
139 int namelen = strlen(newName);
140 len = strlen(buf2);
141 if (len + namelen < sizeof(buf2) - 1)
143 if (buf2[len - 1] != ':')
144 buf2[len++] = '/';
145 CopyMem(newName, buf2 + len, namelen + 1);
146 newName = buf2;
151 D(bug("[Dos] rename %s %s\n", oldName, newName));
153 /* get device pointers */
154 if ((olddvp = GetDeviceProc(oldName, NULL)) == NULL ||
155 (newdvp = GetDeviceProc(newName, NULL)) == NULL) {
156 FreeDeviceProc(olddvp);
157 return DOSFALSE;
160 /* make sure they're on the same device
161 * XXX this is insufficient, see comments in samedevice.c */
162 if (olddvp->dvp_Port != newdvp->dvp_Port) {
163 FreeDeviceProc(olddvp);
164 FreeDeviceProc(newdvp);
165 SetIoErr(ERROR_RENAME_ACROSS_DEVICES);
166 return DOSFALSE;
169 bstrNewName = C2BSTR(newName);
170 bstrOldName = C2BSTR(oldName);
171 status = dopacket4(DOSBase, NULL, olddvp->dvp_Port, ACTION_RENAME_OBJECT, olddvp->dvp_Lock, bstrOldName, newdvp->dvp_Lock, bstrNewName);
172 FREEC2BSTR(bstrOldName);
173 FREEC2BSTR(bstrNewName);
175 FreeDeviceProc(olddvp);
176 FreeDeviceProc(newdvp);
178 return status;
180 AROS_LIBFUNC_EXIT
181 } /* Rename */