picture.datatype: gi_RastPort should not be directly accessed
[AROS.git] / rom / dos / rename.c
blob465aca8c29c423a36774aa3702c0963b22f8e953
1 /*
2 Copyright © 1995-2008, 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
50 Calls the action FSA_RENAME on the filesystem-handler.
52 *****************************************************************************/
54 AROS_LIBFUNC_INIT
56 struct DevProc *olddvp, *newdvp;
57 LONG status;
58 struct Process *me = (struct Process *)FindTask(NULL);
59 char buf1[256], vol[32];
60 char buf2[256];
61 int len;
62 BSTR bstrNewName, bstrOldName;
64 ASSERT_VALID_PROCESS(me);
66 len = SplitName(oldName, ':', vol, 0, sizeof(vol) - 1);
68 if (len > 0)
70 /* get real name */
71 BPTR lock = Lock(oldName, SHARED_LOCK);
72 if (lock)
74 if (NameFromLock(lock, buf1, sizeof(buf1) - 1))
75 oldName = buf1;
76 UnLock(lock);
79 else
81 /* convert to absolute path */
82 if (NameFromLock(me->pr_CurrentDir, buf1, sizeof(buf1) - 1))
84 int namelen = strlen(oldName);
85 len = strlen(buf1);
86 if (len + namelen < sizeof(buf1) - 1)
88 if (buf1[len - 1] != ':')
89 buf1[len++] = '/';
90 CopyMem(oldName, buf1 + len, namelen + 1);
91 oldName = buf1;
96 len = SplitName(newName, ':', vol, 0, sizeof(vol) - 1);
98 if (len > 0)
100 /* get real name of destination path */
101 BPTR lock;
102 char *pos;
103 const char *pos2;
105 strcpy(buf2, newName);
106 pos = strrchr(buf2, '/');
107 if (!pos)
109 pos = buf2 + len;
110 *pos = '\0';
112 else
113 *pos++ = '\0';
115 lock = Lock(buf2, SHARED_LOCK);
116 if (lock)
118 if (NameFromLock(lock, buf2, sizeof(buf2) - 1))
120 int namelen;
121 len = strlen(buf2);
122 pos2 = newName + (int)(pos - buf2);
123 namelen = strlen(pos2);
124 if (len + namelen < sizeof(buf2) - 1)
126 if (buf2[len - 1] != ':')
127 buf2[len++] = '/';
128 CopyMem(pos2, buf2 + len, namelen + 1);
129 newName = buf2;
132 UnLock(lock);
135 else
137 /* convert to absolute path */
138 if (NameFromLock(me->pr_CurrentDir, buf2, sizeof(buf2) - 1))
140 int namelen = strlen(newName);
141 len = strlen(buf2);
142 if (len + namelen < sizeof(buf2) - 1)
144 if (buf2[len - 1] != ':')
145 buf2[len++] = '/';
146 CopyMem(newName, buf2 + len, namelen + 1);
147 newName = buf2;
152 D(bug("[Dos] rename %s %s\n", oldName, newName));
154 /* get device pointers */
155 if ((olddvp = GetDeviceProc(oldName, NULL)) == NULL ||
156 (newdvp = GetDeviceProc(newName, NULL)) == NULL) {
157 FreeDeviceProc(olddvp);
158 return DOSFALSE;
161 /* make sure they're on the same device
162 * XXX this is insufficient, see comments in samedevice.c */
163 if (olddvp->dvp_Port != newdvp->dvp_Port) {
164 FreeDeviceProc(olddvp);
165 FreeDeviceProc(newdvp);
166 SetIoErr(ERROR_RENAME_ACROSS_DEVICES);
167 return DOSFALSE;
170 bstrNewName = C2BSTR(newName);
171 bstrOldName = C2BSTR(oldName);
172 status = dopacket4(DOSBase, NULL, olddvp->dvp_Port, ACTION_RENAME_OBJECT, olddvp->dvp_Lock, bstrOldName, newdvp->dvp_Lock, bstrNewName);
173 FREEC2BSTR(bstrOldName);
174 FREEC2BSTR(bstrNewName);
176 FreeDeviceProc(olddvp);
177 FreeDeviceProc(newdvp);
179 return status;
181 AROS_LIBFUNC_EXIT
182 } /* Rename */