Subversion Repositories SvarDOS

Compare Revisions

Ignore whitespace Rev 398 → Rev 399

/svarcom/trunk/cmd/dir.c
85,6 → 85,10
outputnl("/A NOT IMPLEMENTED YET");
return(-1);
break;
case 'b':
case 'B':
flags |= DIR_FLAG_BARE;
break;
case 'p':
case 'P':
flags |= DIR_FLAG_PAUSE;
105,8 → 109,29
 
if (filespecptr == NULL) filespecptr = ".";
 
file_truename(filespecptr, p->BUFFER);
{
unsigned short r = file_truename(filespecptr, p->BUFFER);
if (r != 0) {
outputnl(doserr(r));
return(-1);
}
}
 
if ((flags & DIR_FLAG_BARE) == 0) {
unsigned char drv = p->BUFFER[0];
if (drv >= 'a') {
drv -= 'a';
} else {
drv -= 'A';
}
cmd_vol_internal(drv, p->BUFFER + 1024);
sprintf(p->BUFFER + 1024, "Directory of %s", p->BUFFER);
/* trim at first '?', if any */
for (i = 0; p->BUFFER[i + 1024] != 0; i++) if (p->BUFFER[i + 1024] == '?') p->BUFFER[i + 1024] = 0;
outputnl(p->BUFFER + 1024);
outputnl("");
}
 
/* if dir then append \????????.??? */
i = file_getattr(p->BUFFER);
if ((i > 0) && (i & DOS_ATTR_DIR)) strcat(p->BUFFER, "\\????????.???");
/svarcom/trunk/cmd/vol.c
0,0 → 1,126
/*
* vol [drive:]
*/
 
static void cmd_vol_internal(unsigned char drv, char *buff) {
unsigned short *buff16 = (void *)(buff);
unsigned short err = 0;
struct DTA *dta = (void *)0x80; /* use the default DTA at location 80h in PSP */
 
outputnl(""); /* start with an empty line to mimic MS-DOS */
 
/* look for volume label in root dir via a FindFirst call */
sprintf(buff, "%c:\\????????.???", drv + 'A');
_asm {
push ax
push cx
push dx
mov [err], 0 /* preset errflag to zero */
mov ah, 0x4e /* FindFirst */
mov dx, buff
mov cx, 0x08 /* match volume labels only */
int 0x21 /* dta filled or CF set on error */
jnc DONE
mov [err], ax
DONE:
pop dx
pop cx
pop ax
}
 
if (err != 0) {
sprintf(buff, "Volume in drive %c has no label", drv + 'A');
} else {
/* if label > 8 chars then drop the dot (DRIVE_LA.BEL -> DRIVE_LABEL) */
if (strlen(dta->fname) > 8) memmove(dta->fname + 8, dta->fname + 9, 4);
sprintf(buff, "Volume in drive %c is %s", drv + 'A', dta->fname);
}
outputnl(buff);
 
/* try to fetch the disk's serial number (DOS 4+ internal call) */
err = 0;
_asm {
push ax
push bx
push dx
mov ax, 0x6900
mov bl, drv /* A=1, B=2, etc */
inc bl /* adjust BL to +1 since drv is 0-based (A=0, B=1, etc) */
xor bh, bh /* "info level", must be 0 */
mov dx, buff /* pointer to a location where a DiskInfo struct will be written */
int 0x21
jnc DONE
mov [err], ax /* err code */
DONE:
pop dx
pop bx
pop ax
}
/* Format of DiskInfo struct (source: RBIL)
Offset Size Description (Table 01766)
00h WORD 0000h (info level)
02h DWORD disk serial number (binary)
06h 11 BYTEs volume label or "NO NAME " if none present
11h 8 BYTEs filesystem type */
if ((err == 0) && (buff16[1] | buff16[2])) {
sprintf(buff + 64, "Volume Serial Number is %04X-%04X", buff16[2], buff16[1]);
outputnl(buff + 64);
}
}
 
 
static int cmd_vol(struct cmd_funcparam *p) {
char drv = 0;
char curdrv = 0;
unsigned short i;
 
if (cmd_ishlp(p)) {
outputnl("Displays the disk volume label and serial number, if they exist.");
outputnl("");
outputnl("VOL [drive:]");
return(-1);
}
 
for (i = 0; i < p->argc; i++) {
if (p->argv[i][0] == '/') {
outputnl("Invalid switch");
return(-1);
}
if (drv != 0) {
outputnl("Too many parameters");
return(-1);
}
if ((p->argv[i][0] == 0) || (p->argv[i][1] != ':') || (p->argv[i][2] != 0)) {
outputnl("Invalid parameter format");
return(-1);
}
drv = p->argv[i][0];
/* convert drive letter to a value 1..x (1=A, 2=B, etc) */
if ((drv >= 'a') && (drv <= 'z')) {
drv -= 'a';
} else {
drv -= 'A';
}
}
 
/* fetch current drive */
_asm {
push ax
mov ah, 0x19 /* query default (current) disk */
int 0x21 /* drive in AL (0=A, 1=B, etc) */
mov [curdrv], al
pop ax
}
 
/* if no drive specified, use the default one */
if (drv == 0) {
drv = curdrv;
} else if (!isdrivevalid(drv)) { /* is specified drive valid? */
outputnl("Invalid drive");
return(-1);
}
 
cmd_vol_internal(drv, p->BUFFER);
 
return(-1);
}
/svarcom/trunk/cmd.c
33,6 → 33,7
#include "cmd/_notimpl.c"
#include "cmd/cd.c"
#include "cmd/del.c"
#include "cmd/vol.c" /* must be included before dir.c due to dependency */
#include "cmd/dir.c"
#include "cmd/exit.c"
#include "cmd/mkdir.c"
40,9 → 41,9
#include "cmd/prompt.c"
#include "cmd/rmdir.c"
#include "cmd/set.c"
#include "cmd/type.c"
#include "cmd/ver.c"
#include "cmd/verify.c"
#include "cmd/type.c"
 
#include "cmd.h"
 
82,7 → 83,7
{"TYPE", cmd_type},
{"VER", cmd_ver},
{"VERIFY", cmd_verify},
{"VOL", cmd_notimpl},
{"VOL", cmd_vol},
{NULL, NULL}
};
 
/svarcom/trunk/helpers.c
145,9 → 145,12
}
 
 
/* converts a path to its canonic representation */
void file_truename(const char *src, char *dst) {
/* converts a path to its canonic representation, returns 0 on success
* or DOS err on failure (invalid drive) */
unsigned short file_truename(const char *src, char *dst) {
unsigned short res = 0;
_asm {
push es
mov ah, 0x60 /* query truename, DS:SI=src, ES:DI=dst */
push ds
pop es
154,7 → 157,12
mov si, src
mov di, dst
int 0x21
jnc DONE
mov [res], ax
DONE:
pop es
}
return(res);
}
 
 
208,3 → 216,32
int 0x21
}
}
 
 
/* validate a drive (A=0, B=1, etc). returns 1 if valid, 0 otherwise */
int isdrivevalid(unsigned char drv) {
_asm {
mov ah, 0x19 /* query default (current) disk */
int 0x21 /* drive in AL (0=A, 1=B, etc) */
mov ch, al /* save current drive to ch */
/* try setting up the drive as current */
mov ah, 0x0E /* select default drive */
mov dl, [drv] /* 0=A, 1=B, etc */
int 0x21
/* this call does not set CF on error, I must check cur drive to look for success */
mov ah, 0x19 /* query default (current) disk */
int 0x21 /* drive in AL (0=A, 1=B, etc) */
mov [drv], 1 /* preset result as success */
cmp al, dl /* is eq? */
je DONE
mov [drv], 0 /* fail */
jmp FAILED
DONE:
/* set current drive back to what it was initially */
mov ah, 0x0E
mov dl, ch
int 0x21
FAILED:
}
return(drv);
}
/svarcom/trunk/helpers.h
51,8 → 51,9
* in string. keys in c MUST BE UPPERCASE! */
unsigned short askchoice(const char *s, const char *c);
 
/* converts a path to its canonic representation */
void file_truename(const char *src, char *dst);
/* converts a path to its canonic representation, returns 0 on success
* or DOS err on failure (invalid drive) */
unsigned short file_truename(const char *src, char *dst);
 
/* returns DOS attributes of file, or -1 on error */
int file_getattr(const char *fname);
66,4 → 67,7
/* displays the "Press any key to continue" msg and waits for a keypress */
void press_any_key(void);
 
/* validate a drive (A=0, B=1, etc). returns 1 if valid, 0 otherwise */
int isdrivevalid(unsigned char drv);
 
#endif