1implement CfgFile; 2 3# 4# Copyright © 1996-1999 Lucent Technologies Inc. All rights reserved. 5# Revisions Copyright © 2000 Vita Nuova Limited. All rights reserved. 6# 7 8include "sys.m"; 9 sys: Sys; 10 Dir: import sys; 11 12include "draw.m"; 13 14include "bufio.m"; 15 bufio: Bufio; 16 Iobuf: import bufio; 17 18include "cfgfile.m"; 19 20# Detect/Copy/Create 21verify(default: string, path: string): ref Sys->FD 22{ 23 if(sys == nil) 24 sys = load Sys Sys->PATH; 25 26 fd := sys->open(path, Sys->ORDWR); 27 if(fd == nil) { 28 fd = sys->create(path, Sys->ORDWR, 8r666); 29 if(fd == nil) 30 return nil; 31 # copy default configuration file (if present) 32 ifd := sys->open(default, Sys->OREAD); 33 if(ifd != nil){ 34 buf := array[Sys->ATOMICIO] of byte; 35 while((n := sys->read(ifd, buf, len buf)) > 0) 36 if(sys->write(fd, buf, n) != n) 37 return nil; 38 ifd = nil; 39 } 40 } 41 return fd; 42} 43 44init(file: string): ref ConfigFile 45{ 46 sys = load Sys Sys->PATH; 47 bufio = load Bufio Bufio->PATH; 48 49 if(sys == nil || bufio == nil) 50 return nil; 51 52 me := ref ConfigFile; 53 me.file = file; 54 me.readonly = 0; 55 f := bufio->open(file, Sys->ORDWR); 56 if(f == nil) { 57 f = bufio->open(file, Sys->OREAD); 58 if (f == nil) 59 return nil; 60 me.readonly = 1; 61 } 62 63 while((l := f.gett("\r\n")) != nil) { 64 if(l[(len l)-1] == '\n') 65 l = l[0:(len l)-1]; 66 me.lines = l :: me.lines; 67 } 68 69 return me; 70} 71 72ConfigFile.flush(me: self ref ConfigFile): string 73{ 74 if(me.readonly) 75 return "file is read only"; 76 if((fd := sys->create(me.file,Sys->OWRITE,0644)) == nil) 77 return sys->sprint("%r"); 78 if((f := bufio->fopen(fd,Sys->OWRITE)) == nil) 79 return sys->sprint("%r"); 80 81 l := me.lines; 82 while(l != nil) { 83 f.puts(hd l+"\n"); 84 l = tl l; 85 } 86 if(f.flush() == -1) 87 return sys->sprint("%r"); 88 89 return nil; 90} 91 92ConfigFile.getcfg(me:self ref ConfigFile, field:string): list of string 93{ 94 l := me.lines; 95 96 while(l != nil) { 97 (n,fields) := sys->tokenize(hd l," \t"); 98 if(n >= 1 && field == hd fields) 99 return tl fields; 100 l = tl l; 101 } 102 return nil; 103} 104 105ConfigFile.setcfg(me:self ref ConfigFile, field:string, val:string) 106{ 107 l := me.lines; 108 newlist: list of string; 109 110 if(me.readonly) 111 return; # should return "file is read only"; 112 113 matched := 0; 114 115 while(l != nil) { 116 (n,fields) := sys->tokenize(hd l," \t"); 117 if(!matched && n >= 1 && field == hd fields) { 118 newlist = field+"\t"+val::newlist; 119 matched = 1; 120 } 121 else 122 newlist = hd l::newlist; 123 l = tl l; 124 } 125 if(!matched) 126 newlist = field+"\t"+val::newlist; 127 128 me.lines = newlist; 129} 130 131ConfigFile.delete(me:self ref ConfigFile, field:string) 132{ 133 l := me.lines; 134 newlist: list of string; 135 136 if(me.readonly) 137 return; # should return "file is read only"; 138 139 matched := 0; 140 141 while(l != nil) { 142 (n,fields) := sys->tokenize(hd l," \t"); 143 if(!matched && n >= 1 && field == hd fields) { 144 matched = 1; 145 } 146 else 147 newlist = hd l::newlist; 148 l = tl l; 149 } 150 151 me.lines = newlist; 152} 153