Prefs/ScreenMode: change the way depth is selected
[AROS.git] / workbench / c / MakeDir.c
blob6f44cb00428c8b0211c00a546e2339e4014a3c20
1 /*
2 Copyright © 1995-2014, 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.6 (3.4.2014)\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 result = RETURN_OK;
74 LONG error = 0;
75 BPTR lock;
77 rda = ReadArgs("NAME/M/A,ALL/S", args, NULL);
79 if(rda != NULL)
81 int i = 0;
82 STRPTR *name = (STRPTR *)args[ARG_NAME];
84 if((name == NULL) || (*name == NULL))
86 error = ERROR_REQUIRED_ARG_MISSING;
87 result = RETURN_FAIL;
89 else
91 for(i = 0; name[i] != NULL; i++)
93 if (args[ARG_ALL])
94 lock = CreateDirAll(name[i]);
95 else
96 lock = CreateDir(name[i]);
98 /* The AmigaDOS semantics are quite strange here. When it is
99 impossible to create a certain directory, MakeDir goes on
100 to try to create the rest of the specified directories and
101 returns the LAST return value for the operation. */
102 if(lock != BNULL)
104 UnLock(lock);
105 result = RETURN_OK;
107 else
109 error = IoErr();
110 PutStr("Cannot create directory ");
111 PutStr(name[i]);
112 PutStr("\n");
113 result = RETURN_ERROR;
118 FreeArgs(rda);
120 else
121 result = RETURN_FAIL;
123 if(result != RETURN_OK)
124 PrintFault(error, "MakeDir");
126 return result;
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);
146 LONG error = 0;
148 CurrentDir(oldcurdir = CurrentDir(0));
150 for (;;)
152 UBYTE c = *pt++;
154 if (c == ':' || c == '/' || c == '\0')
156 if (c == ':')
158 skip = 0;
160 if (!first)
162 error = ERROR_DEVICE_NOT_MOUNTED;
163 break;
165 first = FALSE;
166 oc = pt[skip];
167 pt[skip] = '\0';
168 //Printf("Lock \"%s\"\n", (LONG) name);
169 l = Lock(name, ACCESS_READ);
171 else
173 skip = 0;
174 if (c == '/')
176 while (pt[skip] == '/')
178 skip++;
182 oc = pt[skip];
183 pt[skip] = '\0';
184 //Printf("Lock \"%s\"\n", (LONG) name);
185 l = Lock(name, ACCESS_READ);
186 if (!l)
188 pt[skip] = oc;
189 skip = *name != '/' && c == '/' ? -1 : 0;
190 oc = pt[skip];
191 pt[skip] = '\0';
193 //Printf("CreateDir \"%s\"\n", (LONG) name);
194 l = name[0] == '/' || name[0] == '\0' ? 0 : CreateDir(name);
195 if (l)
197 if (!ChangeMode(CHANGE_LOCK, l, ACCESS_READ))
199 UnLock(l);
200 l = Lock(name, ACCESS_READ);
204 else
206 LONG res;
208 /* Make sure it's a directory */
209 if (!(res = Examine(l, fib)) || fib->fib_DirEntryType < 0)
211 UnLock(l);
212 if (res)
214 error = (c == '\0' ? ERROR_OBJECT_EXISTS : ERROR_OBJECT_WRONG_TYPE);
216 break;
218 pt += skip;
219 skip = 0;
223 if (!l)
225 break;
228 o = CurrentDir(l);
229 if (o != oldcurdir)
231 UnLock(o);
234 pt[skip] = oc;
235 name = pt;
237 if (c == '\0')
239 //Printf("return success\n");
240 return CurrentDir(oldcurdir);
245 pt[skip] = oc;
247 o = CurrentDir(oldcurdir);
248 if (o != oldcurdir)
250 UnLock(o);
253 //Printf("return error\n");
254 SetIoErr(error);
255 return BNULL;