added concrete implementations of putc(), getc(), getchar() and gets()
[tangerine.git] / workbench / c / shellcommands / Path.c
blob4d1bfe29e69cc37c6e3e132d22589ac4cb5a5511
1 /*
2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
3 $Id$
5 */
7 /*****************************************************************************
9 NAME
11 Path [{<dir>}] [ADD] [SHOW] [RESET] [REMOVE] [QUIET] [HEAD]
13 SYNOPSIS
15 PATH/M,ADD/S,SHOW/S,RESET/S,REMOVE/S,QUIET/S,HEAD/S
17 LOCATION
19 Workbench:c
21 FUNCTION
23 Changes the search path for commands. Without arguments it shows the path.
25 INPUTS
27 PATH -- path
28 ADD -- adds path
29 SHOW -- shows path
30 RESET -- removes existing path and replaces it by new path
31 REMOVE -- removes the given path
32 QUIET -- suppresses dialog when a path is not found
33 HEAD -- inserts path at beginning of path list
35 RESULT
37 NOTES
39 EXAMPLE
41 path dh0:work add
43 BUGS
45 SEE ALSO
47 INTERNALS
49 HISTORY
52 ******************************************************************************/
54 #include <exec/memory.h>
55 #include <proto/exec.h>
57 #include <dos/dos.h>
58 #include <dos/dosextens.h>
60 #include <proto/dos.h>
61 #include <dos_commanderrors.h>
63 #define SH_GLOBAL_DOSBASE 1
64 #include <aros/shcommands.h>
66 #include <aros/debug.h>
68 typedef struct CommandLineInterface* CommandLineInterfacePtr;
70 typedef struct
72 BPTR next;
73 BPTR lock;
74 } PathEntry, *PathEntryPtr;
76 #define PE(x) ((PathEntry *)(BADDR(x)))
78 static PathEntryPtr FindPathEntry(CommandLineInterfacePtr cli, STRPTR pathName,
79 PathEntryPtr* predStorage);
81 static PathEntryPtr InsertPathEntry(PathEntryPtr predecessor, STRPTR pathName);
83 static BOOL IsDirectory(BPTR lock);
85 AROS_SH7(Path, 45.3,
86 AROS_SHA(STRPTR *, ,PATH,/M,NULL),
87 AROS_SHA(BOOL, ,ADD,/S,NULL),
88 AROS_SHA(BOOL, ,SHOW,/S,NULL),
89 AROS_SHA(BOOL, ,RESET,/S,NULL),
90 AROS_SHA(BOOL, ,REMOVE,/S,NULL),
91 AROS_SHA(BOOL, ,QUIET,/S,NULL),
92 AROS_SHA(BOOL, ,HEAD,/S,NULL))
94 AROS_SHCOMMAND_INIT
96 CommandLineInterfacePtr
97 cli = Cli();
99 if(!cli)
101 PrintFault(ERROR_SCRIPT_ONLY, "Path");
103 return RETURN_ERROR;
106 if (SHArg(RESET))
108 PathEntryPtr
109 cur = PE(cli->cli_CommandDir);
111 while (cur)
113 PathEntryPtr
114 next = PE(cur->next);
116 UnLock(cur->lock);
118 FreeVec(cur->next);
120 cur = next;
123 cli->cli_CommandDir = NULL;
126 STRPTR*
127 names = SHArg(PATH);
129 if (names && *names)
132 idx;
134 if (SHArg(REMOVE) && !SHArg(RESET))
136 PathEntryPtr
137 pred = NULL,
138 entry = NULL;
140 for (idx = 0; names[idx]; ++idx)
142 entry = FindPathEntry(cli, names[idx], &pred);
144 /* free the path entry */
145 if (NULL != entry)
147 if (NULL != pred)
149 pred->next = entry->next;
151 else
153 cli->cli_CommandDir = entry->next;
156 if (NULL != entry->lock)
158 UnLock(entry->lock);
161 FreeVec(entry);
165 else /* add */
167 PathEntryPtr
168 insertAfter = &cli->cli_CommandDir;
170 if (!SHArg(HEAD))
172 /* Search last entry */
173 while (NULL != insertAfter->next)
175 insertAfter = PE(insertAfter->next);
179 for (idx = 0; names[idx]; ++idx)
181 if (NULL != FindPathEntry(cli, names[idx], NULL))
183 /* don't add if already in path */
184 continue;
186 else
188 insertAfter = InsertPathEntry(insertAfter, names[idx]);
193 else
195 SHArg(SHOW) = SHArg(RESET) == NULL;
198 if (SHArg(SHOW))
200 UBYTE Buffer[2048];
202 PutStr("Current Directory\n");
204 PathEntryPtr
205 cur = NULL;
207 for (cur = PE(cli->cli_CommandDir); cur; cur = PE(cur->next))
209 NameFromLock (cur->lock, Buffer, sizeof (Buffer));
211 PutStr(Buffer);
212 PutStr("\n");
215 PutStr("C:\n");
218 return RETURN_OK;
220 AROS_SHCOMMAND_EXIT
224 /** find the specfied path name in the specified CLI's path list.
226 * @autodoc:function if the path specified by pathName is in the path list of
227 * the specified CLI the corresponding path entry is returned. the path entry's
228 * predecessor is stored in the specified location if the storage pointer is
229 * not NULL.
232 static PathEntryPtr
233 FindPathEntry(CommandLineInterfacePtr cli, STRPTR pathName,
234 PathEntryPtr* predStorage)
236 PathEntryPtr
237 entry = NULL;
239 if (NULL != cli && NULL != cli->cli_CommandDir && NULL != pathName)
241 BPTR
242 pathLock = Lock(pathName, ACCESS_READ);
244 if (NULL != pathLock)
246 PathEntryPtr
247 pred = NULL,
248 curr = PE(cli->cli_CommandDir);
250 while (NULL != curr)
252 LONG
253 value = SameLock(pathLock, curr->lock);
255 if (LOCK_SAME == value)
257 entry = curr;
259 if (NULL != predStorage)
261 *predStorage = pred;
263 break;
265 else
267 pred = curr;
268 curr = PE(curr->next);
272 UnLock(pathLock);
276 return(entry);
280 /* insert a path entry for the specified path
282 * create and insert a path entry for the specified path name. the new path
283 * entry is inserted after the specified predecessor.
285 * returns the path entry or NULL for failure.
287 static PathEntryPtr
288 InsertPathEntry(PathEntryPtr predecessor, STRPTR pathName)
290 PathEntryPtr
291 pathEntry = NULL;
294 PathEntryPtr
295 newEntry = AllocVec(sizeof(PathEntry), MEMF_ANY);
297 BPTR
298 lock = Lock(pathName, SHARED_LOCK);
300 BOOL
301 isDirectory = (NULL != lock)
302 ? IsDirectory(lock)
303 : FALSE;
305 if (newEntry != NULL && lock != NULL && isDirectory)
307 newEntry->lock = lock;
308 newEntry->next = predecessor->next;
310 predecessor->next = MKBADDR(newEntry);
312 pathEntry = newEntry;
314 else
316 if (lock == NULL)
318 PrintFault(IoErr(), pathName);
320 else
322 if (!isDirectory)
324 PrintFault(ERROR_OBJECT_WRONG_TYPE, pathName);
327 UnLock(lock);
330 if (newEntry != NULL)
332 FreeVec(newEntry);
337 return(pathEntry);
341 /* check if the object specified is a directory */
342 static BOOL
343 IsDirectory(BPTR lock)
345 BOOL
346 isDirectory = FALSE;
348 struct FileInfoBlock*
349 fib = AllocDosObject(DOS_FIB, NULL);
351 if (Examine(lock, fib))
353 LONG
354 entryType = fib->fib_EntryType;
356 if (entryType >= ST_ROOT && entryType <= ST_LINKDIR)
358 if (entryType != ST_SOFTLINK)
360 isDirectory = TRUE;
362 else
364 BPTR
365 dupLock = DupLock(lock);
367 if (NULL != dupLock)
369 BPTR
370 file = OpenFromLock(dupLock);
372 if (NULL != file)
374 /* lock was on a file. dupLock is relinquished by OpenFromLock */
375 Close(file);
377 isDirectory = FALSE;
379 else
381 UnLock(dupLock);
384 else
386 isDirectory = FALSE;
391 FreeDosObject(DOS_FIB, fib);
394 return(isDirectory);