ref: babf901b4a508c3ec5d1f89655f10377bbdf9637
dir: /appl/lib/cfgfile.b/
implement CfgFile;
#
# Copyright © 1996-1999 Lucent Technologies Inc. All rights reserved.
# Revisions Copyright © 2000 Vita Nuova Limited. All rights reserved.
#
include "sys.m";
sys: Sys;
Dir: import sys;
include "draw.m";
include "bufio.m";
bufio: Bufio;
Iobuf: import bufio;
include "cfgfile.m";
# Detect/Copy/Create
verify(default: string, path: string): ref Sys->FD
{
if(sys == nil)
sys = load Sys Sys->PATH;
fd := sys->open(path, Sys->ORDWR);
if(fd == nil) {
fd = sys->create(path, Sys->ORDWR, 8r666);
if(fd == nil)
return nil;
# copy default configuration file (if present)
ifd := sys->open(default, Sys->OREAD);
if(ifd != nil){
buf := array[Sys->ATOMICIO] of byte;
while((n := sys->read(ifd, buf, len buf)) > 0)
if(sys->write(fd, buf, n) != n)
return nil;
ifd = nil;
}
}
return fd;
}
init(file: string): ref ConfigFile
{
sys = load Sys Sys->PATH;
bufio = load Bufio Bufio->PATH;
if(sys == nil || bufio == nil)
return nil;
me := ref ConfigFile;
me.file = file;
me.readonly = 0;
f := bufio->open(file, Sys->ORDWR);
if(f == nil) {
f = bufio->open(file, Sys->OREAD);
if (f == nil)
return nil;
me.readonly = 1;
}
while((l := f.gett("\r\n")) != nil) {
if(l[(len l)-1] == '\n')
l = l[0:(len l)-1];
me.lines = l :: me.lines;
}
return me;
}
ConfigFile.flush(me: self ref ConfigFile): string
{
if(me.readonly)
return "file is read only";
if((fd := sys->create(me.file,Sys->OWRITE,0644)) == nil)
return sys->sprint("%r");
if((f := bufio->fopen(fd,Sys->OWRITE)) == nil)
return sys->sprint("%r");
l := me.lines;
while(l != nil) {
f.puts(hd l+"\n");
l = tl l;
}
if(f.flush() == -1)
return sys->sprint("%r");
return nil;
}
ConfigFile.getcfg(me:self ref ConfigFile, field:string): list of string
{
l := me.lines;
while(l != nil) {
(n,fields) := sys->tokenize(hd l," \t");
if(n >= 1 && field == hd fields)
return tl fields;
l = tl l;
}
return nil;
}
ConfigFile.setcfg(me:self ref ConfigFile, field:string, val:string)
{
l := me.lines;
newlist: list of string;
if(me.readonly)
return; # should return "file is read only";
matched := 0;
while(l != nil) {
(n,fields) := sys->tokenize(hd l," \t");
if(!matched && n >= 1 && field == hd fields) {
newlist = field+"\t"+val::newlist;
matched = 1;
}
else
newlist = hd l::newlist;
l = tl l;
}
if(!matched)
newlist = field+"\t"+val::newlist;
me.lines = newlist;
}
ConfigFile.delete(me:self ref ConfigFile, field:string)
{
l := me.lines;
newlist: list of string;
if(me.readonly)
return; # should return "file is read only";
matched := 0;
while(l != nil) {
(n,fields) := sys->tokenize(hd l," \t");
if(!matched && n >= 1 && field == hd fields) {
matched = 1;
}
else
newlist = hd l::newlist;
l = tl l;
}
me.lines = newlist;
}