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
, FALSE
);
124 found
= FindSegment(name
, NULL
, TRUE
);
128 SetIoErr(ERROR_OBJECT_NOT_FOUND
);
131 if (!RemSegment(found
))
133 if (found
->seg_UC
== CMD_INTERNAL
)
134 found
->seg_UC
= CMD_DISABLED
;
136 SetIoErr(ERROR_OBJECT_IN_USE
);
141 PrintFault(IoErr(), SHArg(NAME
));
150 struct Segment
*found
;
153 found
= FindSegment(name
, NULL
, TRUE
);
154 if (found
&& found
->seg_UC
== CMD_DISABLED
)
156 found
->seg_UC
= CMD_INTERNAL
;
163 if (!SHArg(ADD
)) SHArg(REPLACE
) = TRUE
;
165 if (!SHArg(FORCE
) && (fib
= (struct FileInfoBlock
*)AllocDosObject(DOS_FIB
, NULL
)))
169 if ((lock
= Lock(file
, SHARED_LOCK
)))
171 if (Examine(lock
, fib
))
173 if ((fib
->fib_Protection
& FIBF_PURE
) == 0)
174 SetIoErr(ERROR_OBJECT_WRONG_TYPE
);
180 FreeDosObject(DOS_FIB
, fib
);
183 if (IoErr() || !(seglist
= LoadSeg(file
)))
185 PrintFault(IoErr(), file
);
191 struct Segment
*found
;
194 found
= FindSegment(name
, NULL
, FALSE
);
198 if (found
->seg_UC
!= 0)
201 PrintFault(ERROR_OBJECT_IN_USE
, file
);
206 UnLoadSeg(found
->seg_Seg
);
207 found
->seg_Seg
= seglist
;
215 /* WB1.x backwards compatibility hack, do not allow
216 * override of built-in resident or to add l:shell-seg (CLI) */
217 if (!stricmp(name
, "resident") || !stricmp(name
, "cli")) {
218 SetIoErr(ERROR_OBJECT_WRONG_TYPE
);
220 return 1; /* yes, return code = 1 in this special case */
223 if (!AddSegment(name
, seglist
, SHArg(SYSTEM
)?CMD_SYSTEM
:0))
226 PrintFault(IoErr(), "Resident");
234 struct Segment
*curr
;
236 struct DosInfo
*dinf
= BADDR(DOSBase
->dl_Root
->rn_Info
);
237 BOOL isbreak
= FALSE
;
239 NEWLIST((struct List
*)&l
);
243 curr
= (struct Segment
*)BADDR(dinf
->di_ResList
);
246 n
= NewSegNode(SysBase
, AROS_BSTR_ADDR(MKBADDR(&curr
->seg_Name
[0])), curr
->seg_UC
);
250 SetIoErr(ERROR_NO_FREE_STORE
);
254 AddTail((struct List
*)&l
, (struct Node
*)n
);
255 curr
= (struct Segment
*)BADDR(curr
->seg_Next
);
261 PrintFault(IoErr(), "Resident");
265 PutStr("NAME USECOUNT\n\n");
266 while ((n
= (struct SegNode
*)RemHead((struct List
*)&l
)))
268 if (SetSignal(0L, SIGBREAKF_CTRL_C
) & SIGBREAKF_CTRL_C
)
271 if (n
->data
[1] == CMD_SYSTEM
)
272 Printf("%-30s SYSTEM\n", (CONST_STRPTR
)n
->data
[0]);
274 if (n
->data
[1] == CMD_INTERNAL
)
275 Printf("%-30s INTERNAL\n", (CONST_STRPTR
)n
->data
[0]);
277 if (n
->data
[1] == CMD_DISABLED
)
278 Printf("%-30s DISABLED\n", (CONST_STRPTR
)n
->data
[0]);
280 Printf("%-30s %-ld\n", (CONST_STRPTR
)n
->data
[0], (ULONG
)n
->data
[1]);
282 FreeVec((APTR
)n
->data
[0]);
286 SetIoErr(ERROR_BREAK
);
287 PrintFault(IoErr(), "Resident");
297 static STRPTR
myStrDup(struct ExecBase
*SysBase
, STRPTR str
)
299 size_t len
= strlen(str
)+1;
300 STRPTR ret
= (STRPTR
) AllocVec(len
, MEMF_ANY
);
304 CopyMem(str
, ret
, len
);
311 static struct SegNode
*NewSegNode(struct ExecBase
*SysBase
, STRPTR name
,
314 struct SegNode
*sn
= AllocVec(sizeof (struct SegNode
), MEMF_ANY
);
318 sn
->data
[0] = (IPTR
) myStrDup(SysBase
, name
);