Subversion Repositories SvarDOS

Compare Revisions

Ignore whitespace Rev 448 → Rev 449

/svarcom/trunk/cmd/echo.c
29,7 → 29,7
static int cmd_echo(struct cmd_funcparam *p) {
unsigned short offs = FP_OFF(p->cmdline) + 5;
unsigned short segm = FP_SEG(p->cmdline);
unsigned char far *echostatus = MK_FP(p->rmod_seg, RMOD_OFFSET_ECHOFLAG);
unsigned char far *echostatus = MK_FP(p->rmod->rmodseg, RMOD_OFFSET_ECHOFLAG);
 
/* display help only if /? is the only argument */
if ((p->argc == 1) && (imatch(p->argv[0], "/?"))) {
/svarcom/trunk/cmd/exit.c
34,7 → 34,7
outputnl("EXIT\r\n");
outputnl("Quits the COMMAND.COM program (command interpreter)");
} else {
sayonara(p->rmod_seg);
sayonara(p->rmod);
}
return(-1);
}
/svarcom/trunk/cmd.c
45,7 → 45,7
int argc; /* number of arguments */
const char *argv[256]; /* pointers to each argument */
unsigned short env_seg; /* segment of environment block */
unsigned short rmod_seg; /* segment of the resident module */
struct rmod_props far *rmod; /* rmod settings */
unsigned short argoffset; /* offset of cmdline where first argument starts */
const char far *cmdline; /* original cmdline (terminated by a NULL) */
char BUFFER[BUFFER_SIZE]; /* a buffer for whatever is needed */
189,7 → 189,7
}
 
 
int cmd_process(unsigned short rmod_seg, unsigned short env_seg, const char far *cmdline, char *BUFFER) {
int cmd_process(struct rmod_props far *rmod, unsigned short env_seg, const char far *cmdline, char *BUFFER) {
const struct CMD_ID *cmdptr;
unsigned short argoffset;
struct cmd_funcparam *p = (void *)BUFFER;
230,7 → 230,7
/* prepare function parameters and feed it to the cmd handling function */
p->argc = cmd_explode(BUFFER + sizeof(*p), cmdline + argoffset, p->argv);
p->env_seg = env_seg;
p->rmod_seg = rmod_seg;
p->rmod = rmod;
p->argoffset = argoffset;
p->cmdline = cmdline;
 
/svarcom/trunk/cmd.h
25,8 → 25,10
#ifndef CMD_H
#define CMD_H
 
#include "rmodinit.h"
 
/* process internal commands */
int cmd_process(unsigned short env_rmod, unsigned short env_seg, const char far *cmdline, char *BUFFER);
int cmd_process(struct rmod_props far *rmod, unsigned short env_seg, const char far *cmdline, char *BUFFER);
 
/* explodes a command into an array of arguments where last arg is NULL
* returns number of args */
/svarcom/trunk/command.c
79,10 → 79,9
#include "rmodinit.h"
#include "sayonara.h"
 
#define FLAG_EXEC_AND_QUIT 1
 
struct config {
unsigned char flags;
unsigned char flags; /* command.com flags, as defined in rmodinit.h */
char *execcmd;
unsigned short envsiz;
};
131,6 → 130,11
if (cfg->envsiz < 64) cfg->envsiz = 0;
break;
 
case 'p': /* permanent shell (can't exit) */
case 'P':
cfg->flags |= FLAG_PERMANENT;
break;
 
case '?':
outputnl("Starts the SvarCOM command interpreter");
outputnl("");
137,6 → 141,7
outputnl("COMMAND /E:nnn [/[C|K] command]");
outputnl("");
outputnl("/E:nnn Sets the environment size to nnn bytes");
outputnl("/P Makes the new command interpreter permanent (can't exit)");
outputnl("/C Executes the specified command and returns");
outputnl("/K Executes the specified command and continues running");
exit(1);
324,21 → 329,25
static unsigned short far *rmod_envseg;
static unsigned short far *lastexitcode;
static unsigned char BUFFER[4096];
static struct rmod_props far *rmod;
 
parse_argv(&cfg);
 
rmod_seg = rmod_find();
if (rmod_seg == 0xffff) {
rmod_seg = rmod_install(cfg.envsiz);
if (rmod_seg == 0xffff) {
rmod = rmod_find();
if (rmod == NULL) {
rmod = rmod_install(cfg.envsiz);
if (rmod == NULL) {
outputnl("ERROR: rmod_install() failed");
return(1);
}
/* copy flags to rmod's storage */
rmod->flags = cfg.flags;
/* printf("rmod installed at seg 0x%04X\r\n", rmod_seg); */
} else {
/* printf("rmod found at seg 0x%04x\r\n", rmod_seg); */
}
 
rmod_seg = rmod->rmodseg;
rmod_envseg = MK_FP(rmod_seg, RMOD_OFFSET_ENVSEG);
lastexitcode = MK_FP(rmod_seg, RMOD_OFFSET_LEXITCODE);
 
459,7 → 468,7
}
 
/* try matching (and executing) an internal command */
if (cmd_process(rmod_seg, *rmod_envseg, cmdline, BUFFER) >= -1) {
if (cmd_process(rmod, *rmod_envseg, cmdline, BUFFER) >= -1) {
/* internal command executed */
redir_revert(); /* revert stdout (in case it was redirected) */
continue;
475,8 → 484,8
if I am still alive then external command failed to execute */
outputnl("Bad command or file name");
 
} while ((cfg.flags & FLAG_EXEC_AND_QUIT) == 0);
} while ((rmod->flags & FLAG_EXEC_AND_QUIT) == 0);
 
sayonara(rmod_seg);
sayonara(rmod);
return(0);
}
/svarcom/trunk/rmodinit.c
33,12 → 33,14
#include "rmodinit.h"
 
 
/* returns segment where rmod is installed */
unsigned short rmod_install(unsigned short envsize) {
/* returns far pointer to rmod's settings block on success */
struct rmod_props far *rmod_install(unsigned short envsize) {
char far *myptr, far *mcb;
unsigned short far *owner;
const unsigned short sizeof_rmodandprops_paras = rmod_len + sizeof(struct rmod_props) + 15 / 16;
unsigned int rmodseg = 0xffff;
unsigned int envseg = 0;
struct rmod_props far *res = NULL;
 
/* read my current env segment from PSP */
_asm {
52,6 → 54,10
}
 
/* printf("original (PSP) env buffer at %04X\r\n", envseg); */
 
/* if envseg is zero, then enforce our own one (MSDOS 5 does not provide a default env) */
if ((envseg == 0) && (envsize == 0)) envsize = 256;
 
/* if custom envsize requested, convert it to number of paragraphs */
if (envsize != 0) {
envsize += 15;
79,7 → 85,7
int 0x21
/* ask for a memory block and save the given segment to rmodseg */
mov ah, 0x48
mov bx, (rmod_len + 15) / 16
mov bx, sizeof_rmodandprops_paras
int 0x21
jc ALLOC_FAIL
mov rmodseg, ax
105,7 → 111,7
 
if (rmodseg == 0xffff) {
outputnl("malloc error");
return(0xffff);
return(NULL);
}
 
/* copy rmod to its destination */
124,6 → 130,18
*owner = rmodseg;
_fmemcpy(mcb + 8, "SVARENV", 8);
 
/* if env block is newly allocated, fill it with a few NULLs */
if (envsize != 0) {
owner = MK_FP(envseg, 0);
owner[0] = 0;
owner[1] = 0;
}
 
/* prepare result (rmod props) */
res = MK_FP(rmodseg, rmod_len);
_fmemset(res, 0, sizeof(*res));
res->rmodseg = rmodseg;
 
/* write env segment to rmod buffer */
owner = MK_FP(rmodseg, RMOD_OFFSET_ENVSEG);
*owner = envseg;
179,13 → 197,13
pop ax
}
 
return(rmodseg);
return(res);
}
 
 
/* look up my parent: if it's rmod then return its segment,
* otherwise return 0xffff */
unsigned short rmod_find(void) {
/* look up my parent: if it's rmod then return a ptr to its props struct,
* otherwise return NULL */
struct rmod_props far *rmod_find(void) {
unsigned short *parent = (void *)0x0C; /* parent's seg in PSP[Ch] ("prev. int22 handler") */
unsigned short far *ptr;
const unsigned short sig[] = {0x1983, 0x1985, 0x2017, 0x2019};
192,9 → 210,9
unsigned char i;
/* is it rmod? */
ptr = MK_FP(*parent, 0);
for (i = 0; i < 4; i++) if (ptr[i] != sig[i]) return(0xffff);
for (i = 0; i < 4; i++) if (ptr[i] != sig[i]) return(NULL);
/* match successfull (rmod is my parent) */
return(*parent);
return(MK_FP(*parent, rmod_len));
}
 
 
/svarcom/trunk/rmodinit.h
25,6 → 25,14
#ifndef RMODINIT_H
#define RMODINIT_H
 
#define FLAG_EXEC_AND_QUIT 1
#define FLAG_PERMANENT 2
 
struct rmod_props {
unsigned short rmodseg;
unsigned char flags;
};
 
#define RMOD_OFFSET_ENVSEG 0x08
#define RMOD_OFFSET_LEXITCODE 0x0A
#define RMOD_OFFSET_INPBUFF 0x0C
35,8 → 43,8
#define RMOD_OFFSET_ORIGPARENT 0xA2
#define RMOD_OFFSET_ROUTINE 0xA6
 
unsigned short rmod_install(unsigned short envsize);
unsigned short rmod_find(void);
struct rmod_props far *rmod_install(unsigned short envsize);
struct rmod_props far *rmod_find(void);
void rmod_updatecomspecptr(unsigned short rmod_seg, unsigned short env_seg);
 
#endif
/svarcom/trunk/sayonara.c
31,14 → 31,18
 
/* rewires my parent pointer, uninstalls rmod let DOS terminate me, UNLESS
* my parent is unknown */
void sayonara(unsigned short rmodseg) {
void sayonara(struct rmod_props far *rmod) {
unsigned short rmodseg = rmod->rmodseg;
unsigned long far *orgparent = MK_FP(rmodseg, RMOD_OFFSET_ORIGPARENT);
unsigned long *myparent = (void *)0x0A;
unsigned short far *rmodenv_ptr = MK_FP(rmodseg, RMOD_OFFSET_ENVSEG);
unsigned short rmodenv = *rmodenv_ptr;
 
/* set my parent back to original value (if 0 = shell is permanent) */
if (*orgparent == 0) return;
/* detect "I am the origin shell" situations */
if (*orgparent == 0xffff) return; /* original parent set to 0xffff (DOS-C / FreeDOS) */
if (rmod->flags & FLAG_PERMANENT) return; /* COMMAND.COM /P */
 
/* set my parent back to original value */
*myparent = *orgparent;
 
_asm {
/svarcom/trunk/sayonara.h
25,8 → 25,10
#ifndef SAYONARA_H
#define SAYONARA_H
 
#include "rmodinit.h"
 
/* rewires my parent pointer, uninstalls rmod let DOS terminate me, UNLESS
* my parent is unknown */
void sayonara(unsigned short rmodseg);
void sayonara(struct rmod_props far *rmod);
 
#endif
/svarcom/trunk/todo.txt
13,7 → 13,7
pipes redirections
basic BAT support (without workflow controls, FOR loops etc)
merge adjacent assembly blocks in rmod_install()
/P switch for permanent copy
investigate why COMSPEC is not set properly
 
 
AT SOME LATER TIME: