home *** CD-ROM | disk | FTP | other *** search
- PROGRAM vlabel(Input, Output);
- {display, add or modify volume labels}
-
- CONST
- toklen = 63; {max length of a token}
- maxtok = 10; {max number of tokens on command line}
- TYPE
- token = STRING[toklen];
- argarray = ARRAY[1..maxtok] OF token;
- message = STRING[79];
- VAR
- argc : Integer; {argument count (number of tokens)}
- argv : argarray; {elements are the tokens found on the command line}
- errmess : message; {error message, if any, returned from getcom}
- i : Integer;
- drive : Byte;
- drivelet : STRING[1];
- labl : STRING[11];
- inter, gotlabel : Boolean;
-
- FUNCTION getcom(VAR errstring : message) : Boolean;
- {parse command line passed from DOS to Turbo Pascal}
- {return false if error encountered}
- {errstring will contain a text error message if getcom is false}
- CONST
- delim : SET OF Char = [' ', ^I];
- comm = $80; {offset of command tail in program segment prefix}
- VAR
- bufpos : Byte; {position in command line buffer}
- tokpos : Byte; {position in current token}
- nchars : Byte; {one more than the characters in the command tail}
- c : Char;
- m1, m2 : message;
-
- FUNCTION comchar : Char;
- {return the command character at current buffer position}
- BEGIN
- comchar := Chr(Mem[CSeg : (comm+bufpos)]);
- bufpos := bufpos+1;
- END; {comchar}
-
- BEGIN {getcom}
- getcom := True;
- bufpos := 0;
- nchars := 1+Ord(comchar); {define buffer stopping point}
- argc := 0;
- IF nchars > 1 THEN BEGIN
- c := comchar;
- WHILE (c IN delim) DO c := comchar; {skip leading blanks}
- WHILE bufpos <= nchars DO BEGIN
- IF argc < maxtok THEN BEGIN {get the next argument}
- argc := argc+1;
- tokpos := 0;
- WHILE ((bufpos <= nchars) AND (NOT(c IN delim))) DO BEGIN
- IF tokpos < toklen THEN BEGIN {read the argument}
- tokpos := tokpos+1;
- argv[argc][tokpos] := c;
- c := comchar;
- END ELSE BEGIN {set error and skip the rest}
- getcom := False;
- Str(argc, m1);
- Str(toklen, m2);
- errstring := 'ERROR: argument# '+m1+' truncated to '+m2+' characters';
- WHILE (NOT(c IN delim)) DO c := comchar;
- END;
- END;
- argv[argc][0] := Chr(tokpos); {store the arg length}
- WHILE (c IN delim) DO c := comchar; {skip blanks}
- END ELSE BEGIN
- getcom := False;
- Str(maxtok, m1);
- errstring := 'ERROR: number of arguments truncated to '+m1;
- bufpos := nchars+1;
- END;
- END;
- END;
- END; {getcom}
-
- PROCEDURE volume(drive : Byte);
- {DOS calls to access volume labels}
- TYPE
- regpack = RECORD
- ax, bx, cx, dx, bp, si, di, ds, es, flags : Integer;
- END;
- extendfcb = ARRAY[0..43] OF Char;
- VAR
-
- drivenam : STRING[3];
- i : Integer;
- reg : regpack;
- c : Char;
- haslabel : Boolean;
- dta, xfcb, sfcb : extendfcb;
-
- PROCEDURE initfcb(VAR x : extendfcb; namechar : Char);
- {initialize an extended fcb}
- VAR
- i : Integer;
- BEGIN
- x[0] := Chr(255); {flag for extended FCB}
- FOR i := 1 TO 5 DO x[i] := Chr(0);
- x[6] := Chr(8); {specifies that we want volume label}
- x[7] := Chr(0); {where drive number goes}
- FOR i := 8 TO 18 DO x[i] := namechar;
- FOR i := 19 TO 43 DO x[i] := Chr(0);
- END; {initfcb}
-
- BEGIN
- initfcb(sfcb, '?'); {initialize buffers}
- initfcb(xfcb, ' ');
-
- IF drive = 0 THEN BEGIN {GET DRIVE NUMBER}
- reg.ax := $19 SHL 8;
- MsDos(reg);
- Mem[Seg(drive) : Ofs(drive)] := Lo(reg.ax)+1;
- END;
- sfcb[7] := Chr(drive);
- xfcb[7] := Chr(drive);
- CASE drive OF
- 1 : drivenam := 'A: ';
- 2 : drivenam := 'B: ';
- 3 : drivenam := 'C: ';
- 4 : drivenam := 'D: ';
- 5 : drivenam := 'E: ';
- 6 : drivenam := 'F: ';
- 7 : drivenam := 'G: ';
- 8 : drivenam := 'H: ';
- END;
-
- reg.ax := $1a SHL 8; reg.ds := Seg(dta[0]); reg.dx := Ofs(dta[0]);
- MsDos(reg); {SET UP DISK TRANSFER AREA FOR FILENAMES}
-
-
- reg.dx := Ofs(sfcb[0]); reg.ax := $11 SHL 8;
- MsDos(reg); {search for volume entry}
-
- IF Lo(reg.ax) = $FF THEN BEGIN
- haslabel := False;
- IF NOT(gotlabel) THEN
- WriteLn('volume in drive ', drivenam, ' has no label')
- END ELSE BEGIN
- haslabel := True;
- IF NOT(gotlabel) THEN BEGIN
- Write('volume in drive ', drivenam, ' is ');
- FOR i := 1 TO 11 DO Write(dta[7+i]);
- WriteLn;
- END;
- END;
-
- {go on to change the label}
- IF inter THEN BEGIN
- Write('enter new volume label (<cr> for no change): ');
- ReadLn(labl);
- END;
- IF Length(labl) > 0 THEN BEGIN
- FOR i := 1 TO Length(labl) DO xfcb[7+i] := labl[i]; {insert label into xfcb}
- IF haslabel THEN BEGIN
- FOR i := 1 TO 11 DO dta[23+i] := xfcb[7+i]; {modify dta}
- reg.ds := Seg(dta[0]); reg.dx := Ofs(dta[0]); reg.ax := $17 SHL 8;
- MsDos(reg);
- END ELSE BEGIN
- reg.ds := Seg(xfcb[0]); reg.dx := Ofs(xfcb[0]); reg.ax := $16 SHL 8;
- MsDos(reg);
- END;
- IF Lo(reg.ax) = $FF THEN
- WriteLn('error in modifying label')
- ELSE BEGIN
- Write('new volume label in drive ', drivenam, ' is ');
- FOR i := 1 TO 11 DO BEGIN
- c := xfcb[7+i];
- Write(UpCase(c));
- END;
- WriteLn;
- END;
- END;
- END; {volume}
-
- BEGIN
- writeln;
- IF getcom(errmess) THEN BEGIN
- gotlabel := False;
- drive := 0; labl:='';
- IF argc > 0 THEN BEGIN
- inter:=false;
- i := 1;
- WHILE i <= argc DO BEGIN
- IF (Length(argv[i]) = 2) AND (argv[i][2] = ':') THEN BEGIN
- {a drive letter}
- drivelet := argv[i];
- CASE UpCase(drivelet[1]) OF
- 'A' : drive := 1;
- 'B' : drive := 2;
- 'C' : drive := 3;
- 'D' : drive := 4;
- 'E' : drive := 5;
- 'F' : drive := 6;
- 'G' : drive := 7;
- 'H' : drive := 8;
- ELSE
- WriteLn('unknown drive designator');
- Halt;
- END;
- END ELSE BEGIN
- {a new volume label}
- gotlabel := True;
- labl := argv[i];
- END;
- i := i+1;
- END;
- volume(drive);
- END ELSE BEGIN
- inter:=true;
- WHILE True DO BEGIN
- WriteLn;
- Write('enter drive (<cr> for default, Q to quit): ');
- drivelet := '';
- ReadLn(drivelet);
- IF UpCase(drivelet[1]) = 'Q' THEN Halt;
- IF Length(drivelet) = 0 THEN
- drive := 0
- ELSE BEGIN
- CASE UpCase(drivelet[1]) OF
- 'A' : drive := 1;
- 'B' : drive := 2;
- 'C' : drive := 3;
- 'D' : drive := 4;
- 'E' : drive := 5;
- 'F' : drive := 6;
- 'G' : drive := 7;
- 'H' : drive := 8;
- ELSE
- WriteLn('unknown drive designator');
- Halt;
- END;
- END;
- volume(drive);
- END;
- END;
- END ELSE BEGIN
- WriteLn(errmess);
- END;
- END.
-
-