2 Copyright © 1995-2010, The AROS Development Team. All rights reserved.
5 Desc: Resident CLI command
9 /******************************************************************************
18 NAME,FILE,REMOVE/S,ADD/S,REPLACE/S,PURE=FORCE/S,SYSTEM/S
26 Handles list of resident commands. Those commands will be
27 loaded once and then executed from memory.
29 Only pure commands can be made resident, i.e. they must
30 be re-entrant and re-executable. Such commands have the "P"
33 If called without arguments it lists the resident commands.
37 NAME -- The reference name of the resident command. If no
38 name is given the filepart of the file argument
40 FILE -- The file name of the command. It must be an
42 REMOVE -- Deactivates a resident command.
43 ADD -- Adds multiple versions of the same command.
44 REPLACE -- If a resident command already exists, it will be
45 replaced. That's the default option.
46 FORCE -- Add commands which don't have the "P" bit set.
47 SYSTEM -- Adds a command to the system resident list. Those
48 commands can't be removed.
66 ******************************************************************************/
68 #include <proto/dos.h>
69 #include <dos/dosextens.h>
71 #include <exec/lists.h>
72 #include <exec/nodes.h>
73 #include <exec/memory.h>
77 #include <aros/shcommands.h>
85 static struct SegNode
*NewSegNode(struct ExecBase
*SysBase
, STRPTR name
, LONG uc
);
87 AROS_SH7(Resident
, 41.2,
88 AROS_SHA(STRPTR
, ,NAME
, ,NULL
),
89 AROS_SHA(STRPTR
, ,FILE, ,NULL
),
90 AROS_SHA(BOOL
, ,REMOVE
,/S
,FALSE
),
91 AROS_SHA(BOOL
, ,ADD
,/S
,FALSE
),
92 AROS_SHA(BOOL
, ,REPLACE
,/S
,FALSE
),
93 AROS_SHA(BOOL
,PURE
=,FORCE
,/S
,FALSE
),
94 AROS_SHA(BOOL
, ,SYSTEM
,/S
,FALSE
))
99 if (SHArg(FILE) || SHArg(NAME
))
103 struct FileInfoBlock
*fib
;
112 name
= FilePart(SHArg(NAME
));
119 struct Segment
*found
;
122 found
= FindSegment(name
, NULL
, TRUE
);
126 SetIoErr(ERROR_OBJECT_NOT_FOUND
);
129 if (!RemSegment(found
))
131 if (found
->seg_UC
== CMD_INTERNAL
)
132 found
->seg_UC
= CMD_DISABLED
;
134 SetIoErr(ERROR_OBJECT_IN_USE
);
139 PrintFault(IoErr(), SHArg(NAME
));
148 struct Segment
*found
;
151 found
= FindSegment(name
, NULL
, TRUE
);
152 if (found
&& found
->seg_UC
== CMD_DISABLED
)
154 found
->seg_UC
= CMD_INTERNAL
;
161 if (!SHArg(ADD
)) SHArg(REPLACE
) = TRUE
;
163 if (!SHArg(FORCE
) && (fib
= (struct FileInfoBlock
*)AllocDosObject(DOS_FIB
, NULL
)))
167 if ((lock
= Lock(file
, SHARED_LOCK
)))
169 if (Examine(lock
, fib
))
171 if ((fib
->fib_Protection
& FIBF_PURE
) == 0)
172 SetIoErr(ERROR_OBJECT_WRONG_TYPE
);
178 FreeDosObject(DOS_FIB
, fib
);
181 if (IoErr() || !(seglist
= LoadSeg(file
)))
183 PrintFault(IoErr(), file
);
189 struct Segment
*found
;
192 found
= FindSegment(name
, NULL
, FALSE
);
196 if (found
->seg_UC
!= 0)
199 PrintFault(ERROR_OBJECT_IN_USE
, file
);
204 UnLoadSeg(found
->seg_Seg
);
205 found
->seg_Seg
= seglist
;
213 /* WB1.x backwards compatibility hack, do not allow
214 * override of built-in resident or to add l:shell-seg (CLI) */
215 if (!stricmp(name
, "resident") || !stricmp(name
, "cli")) {
216 SetIoErr(ERROR_OBJECT_WRONG_TYPE
);
218 return 1; /* yes, return code = 1 in this special case */
221 if (!AddSegment(name
, seglist
, SHArg(SYSTEM
)?CMD_SYSTEM
:0))
224 PrintFault(IoErr(), "Resident");
232 struct Segment
*curr
;
234 struct DosInfo
*dinf
= BADDR(DOSBase
->dl_Root
->rn_Info
);
235 BOOL isbreak
= FALSE
;
237 NEWLIST((struct List
*)&l
);
241 curr
= (struct Segment
*)BADDR(dinf
->di_ResList
);
244 n
= NewSegNode(SysBase
, AROS_BSTR_ADDR(MKBADDR(&curr
->seg_Name
[0])), curr
->seg_UC
);
248 SetIoErr(ERROR_NO_FREE_STORE
);
252 AddTail((struct List
*)&l
, (struct Node
*)n
);
253 curr
= (struct Segment
*)BADDR(curr
->seg_Next
);
259 PrintFault(IoErr(), "Resident");
263 PutStr("NAME USECOUNT\n\n");
264 while ((n
= (struct SegNode
*)RemHead((struct List
*)&l
)))
266 if (SetSignal(0L, SIGBREAKF_CTRL_C
) & SIGBREAKF_CTRL_C
)
269 if (n
->data
[1] == CMD_SYSTEM
)
270 Printf("%-30s SYSTEM\n", (CONST_STRPTR
)n
->data
[0]);
272 if (n
->data
[1] == CMD_INTERNAL
)
273 Printf("%-30s INTERNAL\n", (CONST_STRPTR
)n
->data
[0]);
275 if (n
->data
[1] == CMD_DISABLED
)
276 Printf("%-30s DISABLED\n", (CONST_STRPTR
)n
->data
[0]);
278 Printf("%-30s %-ld\n", (CONST_STRPTR
)n
->data
[0], (ULONG
)n
->data
[1]);
280 FreeVec((APTR
)n
->data
[0]);
284 SetIoErr(ERROR_BREAK
);
285 PrintFault(IoErr(), "Resident");
295 static STRPTR
myStrDup(struct ExecBase
*SysBase
, STRPTR str
)
297 size_t len
= strlen(str
)+1;
298 STRPTR ret
= (STRPTR
) AllocVec(len
, MEMF_ANY
);
302 CopyMem(str
, ret
, len
);
309 static struct SegNode
*NewSegNode(struct ExecBase
*SysBase
, STRPTR name
,
312 struct SegNode
*sn
= AllocVec(sizeof (struct SegNode
), MEMF_ANY
);
316 sn
->data
[0] = (IPTR
) myStrDup(SysBase
, name
);