prism2.device: Compiler delint
[AROS.git] / workbench / c / MakeDir.c
blobdc0870ce48d274705b4b0af4158e925b83e5fb8a
1 /*
2 Copyright © 1995-2008, The AROS Development Team. All rights reserved.
3 $Id$
5 MakeDir CLI command.
6 */
8 #include <exec/memory.h>
9 #include <exec/execbase.h>
10 #include <proto/exec.h>
11 #include <dos/dos.h>
12 #include <proto/dos.h>
13 #include <utility/tagitem.h>
15 const TEXT version[] = "$VER: MakeDir 42.5 (15.12.2007)\n";
17 /******************************************************************************
19 NAME
21 MakeDir
23 SYNOPSIS
25 NAME/M/A,ALL/S
27 LOCATION
31 FUNCTION
33 Create new empty directories with specified names.
35 INPUTS
37 NAME -- names of the directories that should be created
38 ALL -- creates intermediate directories
40 RESULT
42 NOTES
44 MakeDir does not create an icon for a new directory.
46 EXAMPLE
48 BUGS
50 SEE ALSO
52 INTERNALS
54 ******************************************************************************/
57 enum
59 ARG_NAME = 0,
60 ARG_ALL,
61 NOOFARGS
64 BPTR CreateDirAll(STRPTR name);
66 int __nocommandline;
68 int main(void)
70 IPTR args[NOOFARGS] = { (IPTR) NULL };
71 struct RDArgs *rda;
73 LONG error = RETURN_OK;
74 BPTR lock;
76 rda = ReadArgs("NAME/M/A,ALL/S", args, NULL);
78 if(rda != NULL)
80 int i = 0;
81 STRPTR *name = (STRPTR *)args[ARG_NAME];
83 if((name == NULL) || (*name == NULL))
85 SetIoErr(ERROR_REQUIRED_ARG_MISSING);
86 error = RETURN_FAIL;
88 else
90 for(i = 0; name[i] != NULL; i++)
92 if (args[ARG_ALL])
93 lock = CreateDirAll(name[i]);
94 else
95 lock = CreateDir(name[i]);
97 /* The AmigaDOS semantics are quite strange here. When it is
98 impossible to create a certain directory, MakeDir goes on
99 to try to create the rest of the specified directories and
100 returns the LAST return value for the operation. */
101 if(lock != BNULL)
103 UnLock(lock);
104 error = RETURN_OK;
106 else
108 LONG lasterr = IoErr(); // We don't want error from PutStr()
109 PutStr("Cannot create directory ");
110 PutStr(name[i]);
111 PutStr("\n");
112 SetIoErr(lasterr);
113 error = RETURN_ERROR;
118 FreeArgs(rda);
120 else
121 error = RETURN_FAIL;
123 if(error != RETURN_OK)
124 PrintFault(IoErr(), "MakeDir");
126 return error;
129 /* CreateDirAll
131 * Walk path from left to right, Lock()ing each element. If locking fails,
132 * try CreateDir.
133 * This routine is smart enough to try optimize multiple '/'s.
136 BPTR CreateDirAll(STRPTR name)
138 STRPTR pt = name;
139 BOOL first = TRUE;
140 BPTR oldcurdir;
141 BPTR l, o;
142 UBYTE oc = 0;
143 int skip = 0;
144 UBYTE _fib[sizeof(struct FileInfoBlock) + 3];
145 struct FileInfoBlock *fib = (APTR) ((((IPTR) _fib) + 3) & ~3);
147 CurrentDir(oldcurdir = CurrentDir(0));
149 for (;;)
151 UBYTE c = *pt++;
153 if (c == ':' || c == '/' || c == '\0')
155 if (c == ':')
157 skip = 0;
159 if (!first)
161 SetIoErr(ERROR_DEVICE_NOT_MOUNTED);
162 break;
164 first = FALSE;
165 oc = pt[skip];
166 pt[skip] = '\0';
167 //Printf("Lock \"%s\"\n", (LONG) name);
168 l = Lock(name, ACCESS_READ);
170 else
172 skip = 0;
173 if (c == '/')
175 while (pt[skip] == '/')
177 skip++;
181 oc = pt[skip];
182 pt[skip] = '\0';
183 //Printf("Lock \"%s\"\n", (LONG) name);
184 l = Lock(name, ACCESS_READ);
185 if (!l)
187 pt[skip] = oc;
188 skip = *name != '/' && c == '/' ? -1 : 0;
189 oc = pt[skip];
190 pt[skip] = '\0';
192 //Printf("CreateDir \"%s\"\n", (LONG) name);
193 l = name[0] == '/' || name[0] == '\0' ? 0 : CreateDir(name);
194 if (l)
196 if (!ChangeMode(CHANGE_LOCK, l, ACCESS_READ))
198 UnLock(l);
199 l = Lock(name, ACCESS_READ);
203 else
205 LONG res;
207 /* Make sure it's a directory */
208 if (!(res = Examine(l, fib)) || fib->fib_DirEntryType < 0)
210 UnLock(l);
211 if (res)
213 SetIoErr(c == '\0' ? ERROR_OBJECT_EXISTS : ERROR_OBJECT_WRONG_TYPE);
215 break;
217 pt += skip;
218 skip = 0;
222 if (!l)
224 break;
227 o = CurrentDir(l);
228 if (o != oldcurdir)
230 UnLock(o);
233 pt[skip] = oc;
234 name = pt;
236 if (c == '\0')
238 //Printf("return success\n");
239 return CurrentDir(oldcurdir);
244 pt[skip] = oc;
246 o = CurrentDir(oldcurdir);
247 if (o != oldcurdir)
249 UnLock(o);
252 //Printf("return error\n");
253 return BNULL;