added concrete implementations of putc(), getc(), getchar() and gets()
[tangerine.git] / workbench / c / MakeDir.c
blobcbaa1ae5605a7e59a8b1de1c8d935c2c2a2ced8b
1 /*
2 Copyright © 1995-2007, 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 #include <stdio.h>
17 const TEXT version[] = "$VER: MakeDir 42.5 (15.12.2007)\n";
19 /******************************************************************************
21 NAME
23 MakeDir
25 SYNOPSIS
27 NAME/M,ALL/S
29 LOCATION
31 Sys:C
33 FUNCTION
35 Create new empty directories with specified names.
37 INPUTS
39 NAME -- names of the directories that should be created
40 ALL -- creates intermediate directories
42 RESULT
44 NOTES
46 MakeDir does not create an icon for a new directory.
48 EXAMPLE
50 BUGS
52 SEE ALSO
54 INTERNALS
56 ******************************************************************************/
59 enum
61 ARG_NAME = 0,
62 ARG_ALL,
63 NOOFARGS
66 BPTR CreateDirAll(STRPTR name);
68 int __nocommandline;
70 int main(void)
72 IPTR args[NOOFARGS] = { (IPTR) NULL };
73 struct RDArgs *rda;
75 LONG error = RETURN_OK;
76 BPTR lock;
78 rda = ReadArgs("NAME/M,ALL/S", args, NULL);
80 if(rda != NULL)
82 int i = 0;
83 STRPTR *name = (STRPTR *)args[ARG_NAME];
85 if((name == NULL) || (*name == NULL))
87 SetIoErr(ERROR_REQUIRED_ARG_MISSING);
88 error = RETURN_FAIL;
90 else
92 for(i = 0; name[i] != NULL; i++)
94 if (args[ARG_ALL])
95 lock = CreateDirAll(name[i]);
96 else
97 lock = CreateDir(name[i]);
99 /* The AmigaDOS semantics are quite strange here. When it is
100 impossible to create a certain directory, MakeDir goes on
101 to try to create the rest of the specified directories and
102 returns the LAST return value for the operation. */
103 if(lock != NULL)
105 UnLock(lock);
106 error = RETURN_OK;
108 else
110 LONG lasterr = IoErr(); // We don't want error from PutStr()
111 PutStr("Cannot create directory ");
112 PutStr(name[i]);
113 PutStr("\n");
114 SetIoErr(lasterr);
115 error = RETURN_ERROR;
120 FreeArgs(rda);
122 else
123 error = RETURN_FAIL;
125 if(error != RETURN_OK)
126 PrintFault(IoErr(), "MakeDir");
128 return error;
131 /* CreateDirAll
133 * Walk path from left to right, Lock()ing each element. If locking fails,
134 * try CreateDir.
135 * This routine is smart enough to try optimize multiple '/'s.
138 BPTR CreateDirAll(STRPTR name)
140 STRPTR pt = name;
141 BOOL first = TRUE;
142 BPTR oldcurdir;
143 BPTR l, o;
144 UBYTE oc = 0;
145 int skip = 0;
146 UBYTE _fib[sizeof(struct FileInfoBlock) + 3];
147 struct FileInfoBlock *fib = (APTR) ((((IPTR) _fib) + 3) & ~3);
149 CurrentDir(oldcurdir = CurrentDir(0));
151 for (;;)
153 UBYTE c = *pt++;
155 if (c == ':' || c == '/' || c == '\0')
157 if (c == ':')
159 skip = 0;
161 if (!first)
163 SetIoErr(ERROR_DEVICE_NOT_MOUNTED);
164 break;
166 first = FALSE;
167 oc = pt[skip];
168 pt[skip] = '\0';
169 //Printf("Lock \"%s\"\n", (LONG) name);
170 l = Lock(name, ACCESS_READ);
172 else
174 skip = 0;
175 if (c == '/')
177 while (pt[skip] == '/')
179 skip++;
183 oc = pt[skip];
184 pt[skip] = '\0';
185 //Printf("Lock \"%s\"\n", (LONG) name);
186 l = Lock(name, ACCESS_READ);
187 if (!l)
189 pt[skip] = oc;
190 skip = *name != '/' && c == '/' ? -1 : 0;
191 oc = pt[skip];
192 pt[skip] = '\0';
194 //Printf("CreateDir \"%s\"\n", (LONG) name);
195 l = name[0] == '/' || name[0] == '\0' ? 0 : CreateDir(name);
196 if (l)
198 if (!ChangeMode(CHANGE_LOCK, l, ACCESS_READ))
200 UnLock(l);
201 l = Lock(name, ACCESS_READ);
205 else
207 LONG res;
209 /* Make sure it's a directory */
210 if (!(res = Examine(l, fib)) || fib->fib_DirEntryType < 0)
212 UnLock(l);
213 if (res)
215 SetIoErr(c == '\0' ? ERROR_OBJECT_EXISTS : ERROR_OBJECT_WRONG_TYPE);
217 break;
219 pt += skip;
220 skip = 0;
224 if (!l)
226 break;
229 o = CurrentDir(l);
230 if (o != oldcurdir)
232 UnLock(o);
235 pt[skip] = oc;
236 name = pt;
238 if (c == '\0')
240 //Printf("return success\n");
241 return CurrentDir(oldcurdir);
246 pt[skip] = oc;
248 o = CurrentDir(oldcurdir);
249 if (o != oldcurdir)
251 UnLock(o);
254 //Printf("return error\n");
255 return NULL;