invoke bootiso-quick for pc-x86_64 distfiles-quick's target
[AROS.git] / workbench / c / MakeDir.c
blob0ce699a7b12cb3af349f5fe6deac9dd499ca7f99
1 /*
2 Copyright © 1995-2014, The AROS Development Team. All rights reserved.
3 $Id$
5 MakeDir CLI command.
6 */
8 #include <proto/exec.h>
9 #include <dos/dos.h>
10 #include <proto/dos.h>
11 #include <utility/tagitem.h>
13 const TEXT version[] = "$VER: MakeDir 42.7 (7.8.2016)\n";
15 /******************************************************************************
17 NAME
19 MakeDir
21 SYNOPSIS
23 NAME/M/A,ALL/S
25 LOCATION
29 FUNCTION
31 Create new empty directories with specified names.
33 INPUTS
35 NAME -- names of the directories that should be created
36 ALL -- creates intermediate directories
38 RESULT
40 NOTES
42 MakeDir does not create an icon for a new directory.
44 EXAMPLE
46 BUGS
48 SEE ALSO
50 INTERNALS
52 ******************************************************************************/
55 enum
57 ARG_NAME = 0,
58 ARG_ALL,
59 NOOFARGS
62 BPTR CreateDirAll(STRPTR name);
64 int __nocommandline;
66 int main(void)
68 IPTR args[NOOFARGS] = { (IPTR) NULL };
69 struct RDArgs *rda;
71 LONG result = RETURN_OK;
72 LONG error = 0;
73 BPTR lock;
75 rda = ReadArgs("NAME/M/A,ALL/S", args, NULL);
77 if(rda != NULL)
79 int i = 0;
80 STRPTR *name = (STRPTR *)args[ARG_NAME];
82 if((name == NULL) || (*name == NULL))
84 error = ERROR_REQUIRED_ARG_MISSING;
85 result = RETURN_FAIL;
87 else
89 for(i = 0; name[i] != NULL; i++)
91 if (args[ARG_ALL])
92 lock = CreateDirAll(name[i]);
93 else
94 lock = CreateDir(name[i]);
96 if(lock != BNULL)
98 UnLock(lock);
99 if (result != RETURN_ERROR)
100 result = RETURN_OK;
102 else
104 error = IoErr();
105 PutStr("Cannot create directory ");
106 PutStr(name[i]);
107 PutStr("\n");
108 result = RETURN_ERROR;
113 FreeArgs(rda);
115 else
117 error = ERROR_REQUIRED_ARG_MISSING;
118 result = RETURN_FAIL;
121 if(result != RETURN_OK)
122 PrintFault(error, "MakeDir");
124 return result;
127 /* CreateDirAll
129 * Walk path from left to right, Lock()ing each element. If locking fails,
130 * try CreateDir.
131 * This routine is smart enough to try optimize multiple '/'s.
134 BPTR CreateDirAll(STRPTR name)
136 STRPTR pt = name;
137 BOOL first = TRUE;
138 BPTR oldcurdir;
139 BPTR l, o;
140 UBYTE oc = 0;
141 int skip = 0;
142 UBYTE _fib[sizeof(struct FileInfoBlock) + 3];
143 struct FileInfoBlock *fib = (APTR) ((((IPTR) _fib) + 3) & ~3);
144 LONG error = 0;
146 CurrentDir(oldcurdir = CurrentDir(0));
148 for (;;)
150 UBYTE c = *pt++;
152 if (c == ':' || c == '/' || c == '\0')
154 if (c == ':')
156 skip = 0;
158 if (!first)
160 error = ERROR_DEVICE_NOT_MOUNTED;
161 break;
163 first = FALSE;
164 oc = pt[skip];
165 pt[skip] = '\0';
166 //Printf("Lock \"%s\"\n", (LONG) name);
167 l = Lock(name, ACCESS_READ);
169 else
171 skip = 0;
172 if (c == '/')
174 while (pt[skip] == '/')
176 skip++;
180 oc = pt[skip];
181 pt[skip] = '\0';
182 //Printf("Lock \"%s\"\n", (LONG) name);
183 l = Lock(name, ACCESS_READ);
184 if (!l)
186 pt[skip] = oc;
187 skip = *name != '/' && c == '/' ? -1 : 0;
188 oc = pt[skip];
189 pt[skip] = '\0';
191 //Printf("CreateDir \"%s\"\n", (LONG) name);
192 l = name[0] == '/' || name[0] == '\0' ? 0 : CreateDir(name);
193 if (l)
195 if (!ChangeMode(CHANGE_LOCK, l, ACCESS_READ))
197 UnLock(l);
198 l = Lock(name, ACCESS_READ);
202 else
204 LONG res;
206 /* Make sure it's a directory */
207 if (!(res = Examine(l, fib)) || fib->fib_DirEntryType < 0)
209 UnLock(l);
210 if (res)
212 error = (c == '\0' ? ERROR_OBJECT_EXISTS : ERROR_OBJECT_WRONG_TYPE);
214 break;
216 pt += skip;
217 skip = 0;
221 if (!l)
223 break;
226 o = CurrentDir(l);
227 if (o != oldcurdir)
229 UnLock(o);
232 pt[skip] = oc;
233 name = pt;
235 if (c == '\0')
237 //Printf("return success\n");
238 return CurrentDir(oldcurdir);
243 pt[skip] = oc;
245 o = CurrentDir(oldcurdir);
246 if (o != oldcurdir)
248 UnLock(o);
251 //Printf("return error\n");
252 SetIoErr(error);
253 return BNULL;