home *** CD-ROM | disk | FTP | other *** search
- (*
- * chmod.pas - UNIX-like chmod utility in Turbo Pascal v4.0 (MsDos)
- *
- * usage: chmod [-rhsa] [+rhsa] file(s)
- * where
- * - turns OFF, + turns ON
- * r : Read Only
- * h : Hidden
- * s : System
- * a : Archive
- *
- * note: any combination of switches followed by filenames is legal, i.e.
- * chmod -a +rhs -r file1.pas *.c ???h.h
- * chmod -ahs +r *.* /*.bak \tmp\*.spl
- *
- * and either '\' or '/' may be used as a path separator
- *
- * chmod was originally written to test the wildcard handling routines -
- * thanks much to Karl Brendel for pointing out that the original
- * version didn't actually WORK, except in select cases (not
- * coincidentally, the cases i tested).
- *
- * this program is hereby dedicated to the public domain, etc, etc
- *
- * Paul Roub
- * 786 Loggerhead Island Dr.
- * Satellite Beach, FL 32937
- *
- * Compuserve: 71131, 157
- *
- *)
- program ChangeMode;
-
- uses
- dos;
-
- const
- ro = $0001;
- hid = $0002;
- sys = $0004;
- arc = $0020;
- carry = $0001;
-
- type
- string80 = string[80];
- DtaRec = record
- garbage : array[0..20] of byte;
- attr : byte;
- time : word;
- date : word;
- size : LongInt;
- filename : array[1..13] of char;
- end;
-
- var
- dta : DtaRec;
- Archive, (* attribute switches - *)
- Hidden, (* 0 if turning OFF *)
- SysAtt, (* 1 if turning ON *)
- ReadOnly : integer; (* -1 if no change *)
-
-
- (*
- * Name: StripPath
- * Description: gets path part of filespec
- * Parameters: var
- * full, path : string80
- *)
- procedure StripPath(var full, path : string80);
- var
- slpos : integer;
- begin
- for slpos := 1 to length(full) do
- if (full[slpos] = '/') then
- full[slpos] := '\';
-
- slpos := length(full);
-
- while ((slpos > 0) and (full[slpos] <> '\')) do
- slpos := pred(slpos);
-
- if (slpos <> 0) then
- path := copy(full, 1, slpos)
- else
- path := '';
- end;
-
-
- (*
- * Name: chmod
- * Description: changes attributes of specified file
- * Parameters: var
- * name : string80
- * value
- * ReadOnly, Hidden, SysAtt, Archive : BOOLEAN
- *)
- procedure chmod(var name : string80;
- ReadOnly, Hidden, SysAtt, Archive : integer);
- var
- regs : Registers;
- att : word;
- tn : string80;
- begin
- tn := name + #0;
-
- regs.ax := $4300;
- regs.ds := seg(tn);
- regs.dx := ofs(tn[1]);
-
- MsDos(regs);
-
- att := regs.cx;
-
- if (ReadOnly = 1) then
- att := att OR ro;
- if (Hidden = 1) then
- att := att OR hid;
- if (SysAtt = 1) then
- att := att OR sys;
- if (Archive = 1) then
- att := att OR arc;
-
- if (ReadOnly = 0) then
- att := att AND not ro;
- if (Hidden = 0) then
- att := att AND not hid;
- if (SysAtt = 0) then
- att := att AND not sys;
- if (Archive = 0) then
- att := att AND not arc;
-
- regs.ax := $4301;
- regs.cx := att;
- regs.dx := ofs(tn[1]);
- regs.ds := seg(tn);
-
- MsDos(regs);
- end;
-
-
- (*
- * Name: dispatch
- * Description: calls chmod for each file in wildcard expansion of 'mask'
- * Parameters: var
- * mask : string80
- *)
- procedure dispatch(var mask : string80);
- var
- path : string80;
- regs : Registers;
- tm, victim : string80;
- ps : boolean;
- count : integer;
- any : boolean;
- begin
- StripPath(mask, path);
-
- tm := mask + #0;
-
- regs.ax := $4E00;
- regs.cx := $0027;
- regs.ds := seg(tm);
- regs.dx := ofs(tm[1]);
-
- MsDos(regs);
-
- ps := (path <> '') and (path[length(path)] <> '\');
-
- any := false;
-
- while ((regs.flags and carry) = 0) do
- begin
- any := true;
-
- victim := path;
- if (ps) then
- victim := victim + '\';
-
- count := 1;
-
- while (dta.filename[count] <> #0) do
- begin
- victim := victim + dta.filename[count];
- count := succ(count);
- end;
-
- chmod(victim, ReadOnly, Hidden, SysAtt, Archive);
-
- regs.ah := $4F;
- msdos(regs);
- end;
-
- if (not any) then
- writeln('no files found matching ', mask);
- end;
-
-
- (*
- * Name: initialize
- * Description: initialize globals
- * Parameters: none
- *)
- procedure initialize;
- var
- regs : Registers;
- begin
- regs.ah := $1A;
- regs.ds := seg(dta);
- regs.dx := ofs(dta);
- MsDos(regs);
- Archive := -1;
- SysAtt := -1;
- Hidden := -1;
- ReadOnly := -1;
- end;
-
-
- (*
- * Name: usage
- * Description: print syntax message, exit with error code 1
- * Parameters: none
- *)
- procedure usage;
- begin
- writeln('usage: chmod [-rhsa] [+rhsa] file(s)');
- halt(1);
- end;
-
-
- (*
- * Name: ProcessParms
- * Description: processes command-line parameters
- * Parameters: none
- *)
- procedure ProcessParms;
- var
- count : integer;
- files,
- switches : boolean;
- parm : string80;
- val,
- len,
- count2 : integer;
- begin
- files := FALSE;
- switches := FALSE;
-
- parm := ParamStr(1);
- count := 1;
-
- while (((parm[1] = '-') or (parm[1] = '+')) and (count <= ParamCount)) do
- begin
- switches := TRUE;
-
- if (parm[1] = '+') then
- val := 1
- else
- val := 0;
-
- count2 := 2;
- len := length(parm);
-
- while (count2 <= len) do
- begin
- case (parm[count2]) of
- 'a' : Archive := val;
- 'r' : ReadOnly := val;
- 'h' : Hidden := val;
- 's' : SysAtt := val;
- else
- usage;
- end;
-
- count2 := succ(count2);
- end;
-
- count := succ(count);
- parm := ParamStr(count);
- end;
-
- if (not switches) then
- usage;
-
- while (count <= ParamCount) do
- begin
- files := TRUE;
-
- parm := ParamStr(count);
- dispatch(parm);
-
- count := succ(count);
- end;
-
- if (not files) then
- usage;
- end;
-
-
- (*
- * main routine
- *)
- begin
- initialize;
- ProcessParms;
- end.