Detabbed
[AROS.git] / rom / dos / namefrom.c
blob9e67aec2e5be640f74036231ceeaf1989e8f8bb2
1 /*
2 Copyright © 1995-2007, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Retrieve the full pathname from a lock or a filehandle.
6 Lang: english
7 */
9 #include <proto/exec.h>
10 #include "dos_intern.h"
11 #include <proto/dos.h>
12 #include <aros/debug.h>
14 BOOL namefrom_internal(struct DosLibrary *DOSBase, BPTR lock, STRPTR buffer, LONG length)
16 STRPTR s1, s2, name;
17 D(STRPTR origbuffer;)
18 BPTR parentlock, origlock;
19 struct FileInfoBlock *fib;
20 struct MsgPort *port;
21 LONG error;
22 SIPTR code = DOSFALSE;
23 BOOL first = TRUE;
25 D(origbuffer = buffer);
26 D(bug("NameFromX(%x,%x,%d,%d)\n", BADDR(lock), buffer, length));
28 if (length < 1)
30 SetIoErr(ERROR_LINE_TOO_LONG);
31 return DOSFALSE;
34 fib = AllocDosObject(DOS_FIB, 0);
35 if (!fib)
37 SetIoErr(ERROR_NO_FREE_STORE);
38 return DOSFALSE;
41 if (lock != BNULL) {
42 port = ((struct FileLock*)BADDR(lock))->fl_Task;
43 } else {
44 port = DOSBase->dl_Root->rn_BootProc;
47 /* Construct the name from top to bottom */
48 name = buffer + length;
49 *--name = 0;
51 origlock = lock;
52 parentlock = BNULL;
54 /* Loop over path */
57 error = dopacket2(DOSBase, NULL, port, ACTION_EXAMINE_OBJECT, lock, MKBADDR(fib)) == 0;
58 //bug("name='%s'\n", fib->fib_FileName);
59 if (!error) {
60 parentlock = (BPTR)dopacket1(DOSBase, &code, port, ACTION_PARENT, lock);
61 if (!parentlock && !first)
62 error = code;
63 //bug("parentlock=%x\n", parentlock);
65 if (lock != origlock && lock)
66 UnLock(lock);
67 lock = parentlock;
69 /* Move name to the top of the buffer. */
70 if(!error)
72 fixfib(fib);
73 s1 = s2 = fib->fib_FileName;
75 while(*s2++)
80 if(!parentlock)
82 if (name > buffer)
84 *--name=':';
86 else
88 error = ERROR_LINE_TOO_LONG;
91 else if(!first)
93 if (name > buffer)
95 *--name = '/';
97 else
99 error = ERROR_LINE_TOO_LONG;
103 if (!error)
105 s2--;
107 if (name - (s2 - s1) >= buffer)
109 while(s2 > s1)
111 *--name = *--s2;
114 else
116 error = ERROR_LINE_TOO_LONG;
120 } /* if(!error) */
121 first = FALSE;
124 while(!error && parentlock);
126 /* Move the name from the top to the bottom of the buffer. */
127 if (!error)
129 UBYTE c, old_c = '\0';
133 c = *name++;
135 if ((c != '/') || (old_c != ':'))
137 *buffer++ = c;
140 old_c = c;
143 while (c);
146 FreeDosObject(DOS_FIB, fib);
148 /* All done. */
150 SetIoErr(error);
152 D(bug("[NameFromX]='%s':%d\n", origbuffer, error));
154 return error
155 ? DOSFALSE
156 : DOSTRUE;