prism2.device: Compiler delint
[AROS.git] / workbench / c / shellcommands / Resident.c
blobc53fe173ad9cd9b2a8c70c008632c3a70fdee90f
1 /*
2 Copyright © 1995-2010, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Resident CLI command
6 Lang: English
7 */
10 #include <proto/dos.h>
11 #include <dos/dosextens.h>
12 #include <string.h>
13 #include <exec/lists.h>
14 #include <exec/nodes.h>
15 #include <exec/memory.h>
17 #include <string.h>
19 #include <aros/shcommands.h>
21 struct SegNode
23 struct MinNode node;
24 IPTR data[2];
27 static struct SegNode *NewSegNode(struct ExecBase *SysBase, STRPTR name, LONG uc);
29 AROS_SH7(Resident, 41.2,
30 AROS_SHA(STRPTR, ,NAME, ,NULL),
31 AROS_SHA(STRPTR, ,FILE, ,NULL),
32 AROS_SHA(BOOL, ,REMOVE,/S,FALSE),
33 AROS_SHA(BOOL, ,ADD,/S,FALSE),
34 AROS_SHA(BOOL, ,REPLACE,/S,FALSE),
35 AROS_SHA(BOOL,PURE=,FORCE,/S,FALSE),
36 AROS_SHA(BOOL, ,SYSTEM,/S,FALSE))
38 AROS_SHCOMMAND_INIT
41 if (SHArg(FILE) || SHArg(NAME))
43 STRPTR name, file;
44 BPTR seglist;
45 struct FileInfoBlock *fib;
47 if (SHArg(FILE))
49 name = SHArg(NAME);
50 file = SHArg(FILE);
52 else
54 name = FilePart(SHArg(NAME));
55 file = SHArg(NAME);
58 SetIoErr(0);
59 if (SHArg(REMOVE))
61 struct Segment *found;
63 Forbid();
64 found = FindSegment(name, NULL, TRUE);
65 if (!found)
67 Permit();
68 SetIoErr(ERROR_OBJECT_NOT_FOUND);
70 else
71 if (!RemSegment(found))
73 if (found->seg_UC == CMD_INTERNAL)
74 found->seg_UC = CMD_DISABLED;
75 else
76 SetIoErr(ERROR_OBJECT_IN_USE);
79 if (IoErr())
81 PrintFault(IoErr(), SHArg(NAME));
82 return RETURN_FAIL;
85 return RETURN_OK;
88 if (SHArg(REPLACE))
90 struct Segment *found;
92 Forbid();
93 found = FindSegment(name, NULL, TRUE);
94 if (found && found->seg_UC == CMD_DISABLED)
96 found->seg_UC = CMD_INTERNAL;
97 Permit();
98 return RETURN_OK;
100 Permit();
103 if (!SHArg(ADD)) SHArg(REPLACE) = TRUE;
105 if (!SHArg(FORCE) && (fib = (struct FileInfoBlock *)AllocDosObject(DOS_FIB, NULL)))
107 BPTR lock;
109 if ((lock = Lock(file, SHARED_LOCK)))
111 if (Examine(lock, fib))
113 if ((fib->fib_Protection & FIBF_PURE) == 0)
114 SetIoErr(ERROR_OBJECT_WRONG_TYPE);
117 UnLock(lock);
120 FreeDosObject(DOS_FIB, fib);
123 if (IoErr() || !(seglist = LoadSeg(file)))
125 PrintFault(IoErr(), file);
126 return RETURN_FAIL;
129 if (SHArg(REPLACE))
131 struct Segment *found;
133 Forbid();
134 found = FindSegment(name, NULL, FALSE);
136 if (found)
138 if (found->seg_UC != 0)
140 Permit();
141 PrintFault(ERROR_OBJECT_IN_USE, file);
142 UnLoadSeg(seglist);
143 return RETURN_FAIL;
146 UnLoadSeg(found->seg_Seg);
147 found->seg_Seg = seglist;
148 Permit();
150 return RETURN_OK;
152 /* Fall through */
155 /* WB1.x backwards compatibility hack, do not allow
156 * override of built-in resident or to add l:shell-seg (CLI) */
157 if (!stricmp(name, "resident") || !stricmp(name, "cli")) {
158 SetIoErr(ERROR_OBJECT_WRONG_TYPE);
159 UnLoadSeg(seglist);
160 return 1; /* yes, return code = 1 in this special case */
163 if (!AddSegment(name, seglist, SHArg(SYSTEM)?CMD_SYSTEM:0))
165 UnLoadSeg(seglist);
166 PrintFault(IoErr(), "Resident");
167 return RETURN_FAIL;
170 else
173 struct MinList l;
174 struct Segment *curr;
175 struct SegNode *n;
176 struct DosInfo *dinf = BADDR(DOSBase->dl_Root->rn_Info);
177 BOOL isbreak = FALSE;
179 NEWLIST((struct List *)&l);
181 SetIoErr(0);
182 Forbid();
183 curr = (struct Segment *)BADDR(dinf->di_ResList);
184 while (curr)
186 n = NewSegNode(SysBase, AROS_BSTR_ADDR(MKBADDR(&curr->seg_Name[0])), curr->seg_UC);
188 if (!n)
190 SetIoErr(ERROR_NO_FREE_STORE);
191 break;
194 AddTail((struct List *)&l, (struct Node *)n);
195 curr = (struct Segment *)BADDR(curr->seg_Next);
197 Permit();
199 if (IoErr())
201 PrintFault(IoErr(), "Resident");
202 return RETURN_FAIL;
205 PutStr("NAME USECOUNT\n\n");
206 while ((n = (struct SegNode *)RemHead((struct List *)&l)))
208 if (SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C)
209 isbreak = TRUE;
210 if (!isbreak) {
211 if (n->data[1] == CMD_SYSTEM)
212 VPrintf("%-30s SYSTEM\n", n->data);
213 else
214 if (n->data[1] == CMD_INTERNAL)
215 VPrintf("%-30s INTERNAL\n", n->data);
216 else
217 if (n->data[1] == CMD_DISABLED)
218 VPrintf("%-30s DISABLED\n", n->data);
219 else
220 VPrintf("%-30s %-ld\n", n->data);
222 FreeVec((APTR)n->data[0]);
223 FreeVec(n);
225 if (isbreak) {
226 SetIoErr(ERROR_BREAK);
227 PrintFault(IoErr(), "Resident");
228 return RETURN_FAIL;
232 return RETURN_OK;
234 AROS_SHCOMMAND_EXIT
237 static STRPTR StrDup(struct ExecBase *SysBase, STRPTR str)
239 size_t len = strlen(str)+1;
240 STRPTR ret = (STRPTR) AllocVec(len, MEMF_ANY);
242 if (ret)
244 CopyMem(str, ret, len);
247 return ret;
251 static struct SegNode *NewSegNode(struct ExecBase *SysBase, STRPTR name,
252 LONG uc)
254 struct SegNode *sn = AllocVec(sizeof (struct SegNode), MEMF_ANY);
256 if (sn)
258 sn->data[0] = (IPTR) StrDup(SysBase, name);
259 if (sn->data[0])
261 sn->data[1] = uc;
262 return sn;
265 FreeVec(sn);
268 return NULL;