diff options
-rw-r--r-- | builtin.go | 12 | ||||
-rw-r--r-- | depmap.go | 12 | ||||
-rw-r--r-- | fileop.go | 6 | ||||
-rw-r--r-- | initd.go | 16 | ||||
-rw-r--r-- | main.go | 104 | ||||
-rw-r--r-- | rcd.go | 36 | ||||
-rw-r--r-- | rcservice.go | 3 | ||||
-rw-r--r-- | runlevel.go | 15 | ||||
-rw-r--r-- | runlevel_test.go | 2 | ||||
-rw-r--r-- | service.go | 11 | ||||
-rw-r--r-- | sysvservice.go | 89 |
11 files changed, 150 insertions, 156 deletions
@@ -3,7 +3,7 @@ package main import ( "os" "path/filepath" -) +) type BuiltinService struct { ServiceBase @@ -38,26 +38,26 @@ var builtinServices = []BuiltinService{ baseName: `$portmap`, provided: []string{`$portmap`, `$rpcbind`}, shortDescr: `SunRPC/ONCRPC portmapping service is available` }, - rcfile: `rc.rpc` }, + rcfile: `rc.rpc` }, // True (unless single-user) BuiltinService{ ServiceBase: ServiceBase{ baseName: `$remote_fs`, provided: []string{`$remote_fs`}, shortDescr: `all remote file systems are available` }, - }, + }, // True if /etc/rc.d/rc.syslog has executable bit on BuiltinService{ ServiceBase: ServiceBase{ baseName: `$syslog`, provided: []string{`$syslog`}, shortDescr: `system logger is operational` }, - rcfile: `rc.syslog` }, + rcfile: `rc.syslog` }, // Always true (or: True if /etc/rc.d/rc.ntpd has executable bit on) BuiltinService{ ServiceBase: ServiceBase{ baseName: `$time`, provided: []string{`$time`}, shortDescr: `the system time is set` }, - rcfile: `rc.ntpd` } } - + rcfile: `rc.ntpd` } } + func (srv *BuiltinService) Enabled() (bool, string) { if srv.rcfile != `` { name := filepath.Join(opts.RCDirectory, srv.rcfile) @@ -3,7 +3,7 @@ package main import ( "errors" "strconv" -) +) // The dependency map structure type Depmap struct { @@ -24,7 +24,7 @@ func NewDepmap(n int) *Depmap { for j := 0; j < n; j++ { v.dist[i][j] = n + 1 // infinity v.next[i][j] = -1 - } + } } return &v } @@ -72,7 +72,7 @@ func (dm *Depmap) TC() { } } } - + // Modified Floyd-Warshall algorithm for k := 0; k < dm.dim; k++ { for i := 0; i < dm.dim; i++ { @@ -94,13 +94,13 @@ func (dm *Depmap) TC() { func (dm *Depmap) Set(i, j int) { dm.dist[i][j] = 1 dm.closed = false -} +} // Set distance between vertices i and j to infinity. func (dm *Depmap) Unset(i int, j int) { dm.dist[i][j] = dm.Inf() dm.closed = false -} +} // Return the (minimal) distance between the two vertices. func (dm *Depmap) Dist(i, j int) int { @@ -207,7 +207,7 @@ func (dm *Depmap) NormalizedCyclePath(i int) (path []int) { if n < minval { minval = n minpos = i - } + } } if minpos != 0 { path = append(path[minpos:], path[0:minpos]...) @@ -72,12 +72,12 @@ func (s Symlink) Commit() error { if err := os.Symlink(s.src, s.dst); err != nil { return err } - + if err := os.Chdir(cwd); err != nil { return err } } - + return nil } // ---------------------------- @@ -94,7 +94,7 @@ func (s Unlink) Commit() error { if ! opts.DryRun { return os.Remove(s.name) } - return nil + return nil } func NewUnlink(name string) *Unlink { @@ -16,14 +16,14 @@ type InitDir struct { } // Ignore files matching this regexp. -var ignoreFileRe = regexp.MustCompile(`^(functions|#.*#|(.*(~|\.bak)))$`) +var ignoreFileRe = regexp.MustCompile(`^(functions|#.*#|(.*(~|\.bak)))$`) // Scan the init.d directory and return a pointer to its internal // representation. func LoadInitDir(dirname string) (*InitDir, error) { files, err := ioutil.ReadDir(dirname) if err != nil { - return nil, err + return nil, err } var dir InitDir @@ -39,8 +39,8 @@ func LoadInitDir(dirname string) (*InitDir, error) { } else { log.Println(path + ": " + err.Error()) } - } - } + } + } return &dir, nil } @@ -72,21 +72,21 @@ func (d *InitDir) WhoProvides(sym string) (result []Service) { // Given service base name, return a copy of the corresponding Service // structure. func (d *InitDir) FindServiceByName(name string) (Service, bool) { - for _, srv := range d.service { + for _, srv := range d.service { if srv.BaseName() == name { return NewRCService(srv), true } } - return nil, false + return nil, false } // Given service file info, return a copy of the corresponding Service // structure. func (d *InitDir) FindServiceByFile(info os.FileInfo) (Service, bool) { - for _, srv := range d.service { + for _, srv := range d.service { if srv.SameFile(info) { return NewRCService(srv), true } } - return nil, false + return nil, false } @@ -15,7 +15,7 @@ var opts struct { Del bool Recursive bool Defaults bool - Level []string + Level []string RCDirectory string DryRun bool Debug bool @@ -54,18 +54,18 @@ func main() { opts.Debug = true } InitDirectory = filepath.Join(opts.RCDirectory, `init.d`) - + if opts.Add { if opts.List || opts.Del { log.Fatal("conflicting options") - } + } Add(NewArgList(args)) os.Exit(0) } if opts.Del { if opts.List || opts.Add { log.Fatal("conflicting options") - } + } Del(NewArgList(args)) os.Exit(0) } @@ -141,7 +141,7 @@ func GetRunlevels() Runlevels { type ListingRow struct { name string // Service base name on [NumLevels]bool // Indicators of whether the service is enabled - // on each runlevel + // on each runlevel } // The listing structure @@ -159,7 +159,7 @@ func LoadListing(initdir *InitDir, sel NameSelector) (*Listing, error) { next := initdir.Iterator(sel) for srv := next(); srv != nil; srv = next() { lst.rows = append(lst.rows, ListingRow{name: srv.BaseName()}) - } + } return &lst, nil } @@ -218,7 +218,7 @@ func List(args *ArgList) { } } } - + // Print the resulting listing. for _, row := range lst.rows { name := row.name @@ -226,7 +226,7 @@ func List(args *ArgList) { if nlen > width { name = name[0:width-5] + `...` + name[nlen-2:] } - + fmt.Printf("%-*s", width, name) next = rs.Iterator() for r := next(); r.IsValid(); r = next() { @@ -250,13 +250,13 @@ func Del(args *ArgList) { if args.Len() == 0 { log.Fatal(`not enough arguments`) } - + // Load the content of the init.d directory. initdir, err := LoadInitDir(InitDirectory) if err != nil { log.Fatal(err) } - + // Get the required runlevels rs := GetRunlevels() @@ -297,7 +297,7 @@ func Del(args *ArgList) { } } // Check and report any unconsumed arguments - args.Report() + args.Report() // Actually remove the collected files (unless in dry-run mode). err = oplist.Commit() @@ -349,7 +349,7 @@ func (d *InitDir) AddDependencies(srvin []Service) (srvout []Service) { // Compute transitive closure and shortest paths. Report eventual // cyclic dependencies. p := dm.FindCycles() - reportCyclicDependencies(p, srvin) + reportCyclicDependencies(p, srvin) // Keep track of already processed services srvind := make([]bool, dm.Dim()) @@ -363,7 +363,7 @@ func (d *InitDir) AddDependencies(srvin []Service) (srvout []Service) { n := path[k] if !srvind[n] { srvout = append(srvout, - srvin[n]) + srvin[n]) srvind[n] = true } } @@ -374,7 +374,7 @@ func (d *InitDir) AddDependencies(srvin []Service) (srvout []Service) { srvind[i] = true } } - + return } @@ -384,7 +384,7 @@ func Add(args *ArgList) { if err != nil { log.Fatal(err) } - + // Get the required runlevels rsmask := GetRunlevels() @@ -398,9 +398,9 @@ func Add(args *ArgList) { nextservice := initdir.Iterator(args.GetNameSelector()) for srv := nextservice(); srv != nil; srv = nextservice() { services = append(services, srv) - } + } // If any unused arguments remain, report them and exit. - args.Report() + args.Report() } else if opts.Defaults { s := make(map[string]bool) nextlevel := GetRunlevels().Iterator() @@ -408,8 +408,8 @@ func Add(args *ArgList) { rcd, err := LoadRCDir(r, initdir) if err != nil { log.Fatal("failed to load rc directory: " + err.Error()) - } - rcdir[r.Index()] = rcd + } + rcdir[r.Index()] = rcd nextserv := rcd.Start.SysVServiceIterator() for srv := nextserv(); srv != nil; srv = nextserv() { @@ -431,7 +431,7 @@ func Add(args *ArgList) { log.Fatal(`not enough arguments`) } - + if opts.Recursive { services = initdir.AddDependencies(services) } @@ -441,11 +441,11 @@ func Add(args *ArgList) { rsStart.Or(srv.DefaultStart()) rsStop.Or(srv.DefaultStop()) } - + // Mask out non requested runlevels rsStart.And(rsmask) rsStop.And(rsmask) - + // Load rc directories var rs Runlevels // A union of start and stop runlevels rs.Or(rsStart) @@ -457,27 +457,27 @@ func Add(args *ArgList) { rcd, err := LoadRCDir(r, initdir) if err != nil { log.Fatal("failed to load rc directory: " + err.Error()) - } - rcdir[r.Index()] = rcd + } + rcdir[r.Index()] = rcd } } // Array of symlinks to be created oplist := new(FileOpList) - + // Incorporate each new service into the corresponding runlevels for _, srv := range services { if opts.Debug { log.Printf("DEBUG: adding %s\n", srv.BaseName()) } - + nextlevel := rsStart.Iterator() for r := nextlevel(); r.IsValid(); r = nextlevel() { if s := rcdir[r.Index()].Start.Inc(srv); s != nil { oplist.Concat(s) } - } - + } + nextlevel = rsStop.Iterator() for r := nextlevel(); r.IsValid(); r = nextlevel() { if s := rcdir[r.Index()].Stop.Inc(srv); s != nil { @@ -562,7 +562,7 @@ func (p *StopPriority) Value() int { func (p *StopPriority) String() string { return fmt.Sprintf("%02d", p.Value()) } - + // Return an iterator over all dependencies of the service n in the // start sequence. func (rseq *RCSeq) StartTraversal(n int) ServiceIterator { @@ -593,7 +593,7 @@ func (rseq *RCSeq) TraverseEquidependentServices(n int) ServiceIterator { } return nil } -} +} func reportCyclicDependencies(p [][]int, srv []Service) { if len(p) > 0 { @@ -607,18 +607,18 @@ func reportCyclicDependencies(p [][]int, srv []Service) { } os.Exit(1) } -} +} // Detect and report possible cyclic dependencies. func (rseq *RCSeq) DetectRecursion() { reportCyclicDependencies(rseq.Deps.Copy().FindCycles(), - rseq.Service) + rseq.Service) } // Incorporate service newsrv into sequence rseq. func (rseq *RCSeq) Inc(newsrv Service) *FileOpList { oplist := new(FileOpList) - + oldsrv := rseq.FindServiceByName(newsrv.BaseName()) if oldsrv != nil { // If link already exists and --defaults is requested, @@ -630,20 +630,20 @@ func (rseq *RCSeq) Inc(newsrv Service) *FileOpList { return nil } } - + /* 1. Register newserv in rsec. Let N be its number. - 2. Compute dependency matrix - 3. Compute priority for the new service: - 3.1. Set prio to initial value (0 for start sequence, 99 for - stop sequence) - 3.2. Traverse the Nth row of the matrix. - For each element (i,j) that is true, set - - prio = update(prio, srv[j].prio) - - where update is max for start sequence and min for stop. - 4. Create symlink name and return new Symlink structure. - */ + 2. Compute dependency matrix + 3. Compute priority for the new service: + 3.1. Set prio to initial value (0 for start sequence, 99 for + stop sequence) + 3.2. Traverse the Nth row of the matrix. + For each element (i,j) that is true, set + + prio = update(prio, srv[j].prio) + + where update is max for start sequence and min for stop. + 4. Create symlink name and return new Symlink structure. + */ srvno := rseq.RegisterService(NewRCService(newsrv)) rseq.BuildDependencies() if rseq.Isstart && rseq.Deps.IsSet(srvno, 0) { @@ -651,22 +651,22 @@ func (rseq *RCSeq) Inc(newsrv Service) *FileOpList { return nil } rseq.DetectRecursion() - + prio := NewPriority(rseq.Isstart) next := rseq.StartTraversal(srvno) for srv := next(); srv != nil; srv = next() { if ok, diag := srv.Enabled(); !ok { log.Printf("%s: %s depends on %s, which is not enabled\n", rseq.dir.runlevel.Letter(), - rseq.Service[srvno].BaseName(), - srv.BaseName()); + rseq.Service[srvno].BaseName(), + srv.BaseName()); log.Printf("%s\n", diag); return nil } prio.Update(srv.Priority()) } prio.Incr() - // Traverse services that have the same dependencies + // Traverse services that have the same dependencies next = rseq.TraverseEquidependentServices(srvno) for srv := next(); srv != nil; srv = next() { prio.Update(srv.Priority()) @@ -680,8 +680,8 @@ func (rseq *RCSeq) Inc(newsrv Service) *FileOpList { initial = `K` } oplist.Append(&Symlink{src: filepath.Join(InitDirectory, - rseq.Service[srvno].BaseName()), - dst: filepath.Join(rseq.dir.dirname, + rseq.Service[srvno].BaseName()), + dst: filepath.Join(rseq.dir.dirname, initial + prio.String() + rseq.Service[srvno].BaseName())}) return oplist } @@ -15,9 +15,9 @@ type RCSeq struct { Service []Service // Array of services in the sequence Deps *Depmap // A matrix of dependencies between services Symbols map[string]int // A map of symbols provided by each service. - // The value of Symbols[name] is the index - // of the corresponding service entry in the - // Service array. + // The value of Symbols[name] is the index + // of the corresponding service entry in the + // Service array. Isstart bool // True if this is a start-up sequence. dir *RCDir // Back pointer to the directory structure. } @@ -43,7 +43,7 @@ func (seq *RCSeq) RegisterService(srv Service) (n int) { if _, found := seq.Symbols[s]; !found { seq.Symbols[s] = n } - } + } seq.Service = append(seq.Service, srv) return } @@ -133,7 +133,7 @@ func (seq *RCSeq) FindServiceByName(name string) Service { return NewRCService(srv) } } - return nil + return nil } // Create a RC sequence corresponding to the directory rcd. @@ -144,22 +144,22 @@ func (rseq *RCSeq) InitRCSeq(rcd *RCDir) { rseq.dir = rcd srv := ServiceBase{baseName: `$undefined`, - shortDescr: `Undefined service`} + shortDescr: `Undefined service`} rseq.Service = append(rseq.Service, NewRCService(&srv)) - + rseq.RegisterBuiltinServices() } -var scriptName = regexp.MustCompile(`^([KS])([0-9][0-9])(.*)`) +var scriptName = regexp.MustCompile(`^([KS])([0-9][0-9])(.*)`) // S being a file name, follow all symbolic links and return the // corresponding absolute file name. func realpath(s string) (string, error) { - path, err := filepath.EvalSymlinks(s) - if err != nil { - return s, err; + path, err := filepath.EvalSymlinks(s) + if err != nil { + return s, err; } - return filepath.Abs(path); + return filepath.Abs(path); } // Scan the rc-directory for the runlevel 'level'. 'idir' provides the @@ -169,13 +169,13 @@ func LoadRCDir(level Runlevel, idir *InitDir) (*RCDir, error) { files, err := ioutil.ReadDir(dirname) if err != nil { - return nil, err + return nil, err } rl := RCDir{dirname: dirname, runlevel: level} rl.Start.InitRCSeq(&rl) rl.Stop.InitRCSeq(&rl) - + for _, file := range files { match := scriptName.FindStringSubmatch(file.Name()) if match == nil || @@ -183,26 +183,26 @@ func LoadRCDir(level Runlevel, idir *InitDir) (*RCDir, error) { (file.Mode() & os.ModeSymlink) != 0) { continue } - + path, err := realpath(filepath.Join(dirname, file.Name())) if err != nil { log.Println(path + ": " + err.Error()) continue - } + } st, err := os.Stat(path) if err != nil { log.Printf("%s: can't stat: %s\n", path, err.Error()) continue } - + srv, found := idir.FindServiceByFile(st) if !found { log.Printf("%s: ignoring; %s target not found in %s\n", path, file.Name(), InitDirectory) continue } srv.SetFileName(filepath.Join(dirname, file.Name())) - prio, _ := strconv.Atoi(match[2]) + prio, _ := strconv.Atoi(match[2]) srv.SetPriority(prio) if match[1] == `S` { rl.Start.RegisterService(srv) diff --git a/rcservice.go b/rcservice.go index fbccf4f..ed70ccb 100644 --- a/rcservice.go +++ b/rcservice.go @@ -4,7 +4,7 @@ package main // rcN.d directory. type RCService struct { SysVService // The service itself. - priority int // Relative priority number. + priority int // Relative priority number. } func (srv *RCService) Copy(s Service) { @@ -25,4 +25,3 @@ func NewRCService(src Service) Service { dst.priority = -1 return &dst } - diff --git a/runlevel.go b/runlevel.go index 750ab4a..12e3251 100644 --- a/runlevel.go +++ b/runlevel.go @@ -4,7 +4,7 @@ import ( "errors" "strings" "encoding/json" -) +) var runlevelLetter = [...]string{`?`, `0`, `1`, `2`, `3`, `4`, `5`, `6`, `S`} const NumLevels = len(runlevelLetter) @@ -20,12 +20,12 @@ func NewRunlevel(s string) Runlevel { } } return Runlevel(0) -} +} // Index returns internal representation of the runlevel func (r Runlevel) Index() int { return int(r) -} +} // Letter returns runlevel letter (external representation) func (r Runlevel) Letter() string { @@ -35,7 +35,7 @@ func (r Runlevel) Letter() string { // IsValid returns true if the runlevel is valid func (r Runlevel) IsValid() bool { return r > 0 && int(r) < NumLevels -} +} // String returns a string representation of the runlevel (its letter, // actually) @@ -83,7 +83,7 @@ func (rs Runlevels) Count() int { } } return count -} +} // Logical OR between two runlevel sets func (rs *Runlevels) Or(other Runlevels) { @@ -116,7 +116,7 @@ func (rs Runlevels) Iterator() RunlevelIterator { } return Runlevel(i) } -} +} // String returns a string representation of the runlevel set func (rs Runlevels) String() string { @@ -147,6 +147,3 @@ func (rsret *Runlevels) UnmarshalJSON(b []byte) error { func (rs Runlevels) MarshalJSON() ([]byte, error) { return json.Marshal(rs.String()) } - - - diff --git a/runlevel_test.go b/runlevel_test.go index e81c616..4feb425 100644 --- a/runlevel_test.go +++ b/runlevel_test.go @@ -3,7 +3,7 @@ package main import ( "testing" "encoding/json" -) +) func TestIndex (t *testing.T) { r := NewRunlevel(`2`) @@ -16,13 +16,13 @@ type Service interface { Priority() int Provided() []string Provides(string) bool - RequiredStart() []string + RequiredStart() []string RequiredStop() []string ShouldStart() []string ShouldStop() []string - DefaultStart() Runlevels - DefaultStop() Runlevels - ShortDescr() string + DefaultStart() Runlevels + DefaultStop() Runlevels + ShortDescr() string Descr() string Enabled() (bool, string) } @@ -137,5 +137,4 @@ func (srv *ServiceBase) DefaultStop() Runlevels { } func (srv *ServiceBase) Enabled() (bool, string) { return true, "on" -} - +} diff --git a/sysvservice.go b/sysvservice.go index 1c23a98..aa0bc63 100644 --- a/sysvservice.go +++ b/sysvservice.go @@ -21,12 +21,12 @@ var ( // SysVService type SysVService struct { ServiceBase - requiredStart []string + requiredStart []string requiredStop []string shouldStart []string shouldStop []string - defaultStart Runlevels - defaultStop Runlevels + defaultStart Runlevels + defaultStop Runlevels } func (srv *SysVService) Copy(src Service) { @@ -34,8 +34,8 @@ func (srv *SysVService) Copy(src Service) { srv.provided = src.Provided(); srv.requiredStart = src.RequiredStart(); srv.requiredStop = src.RequiredStop(); - srv.shouldStart = src.ShouldStart(); - srv.shouldStop = src.ShouldStop(); + srv.shouldStart = src.ShouldStart(); + srv.shouldStop = src.ShouldStop(); srv.defaultStart = src.DefaultStart(); srv.defaultStop = src.DefaultStop(); srv.shortDescr = src.ShortDescr(); @@ -44,10 +44,10 @@ func (srv *SysVService) Copy(src Service) { func (srv *SysVService) RequiredStart() []string { return srv.requiredStart[:] -} +} func (srv *SysVService) RequiredStop() []string { return srv.requiredStop[:] -} +} func (srv *SysVService) ShouldStart() []string { return srv.shouldStart[:] } @@ -75,14 +75,14 @@ func ToRunlevels(kw string, val string) (Runlevels, error) { } if err := rl.Set(string(c)); err != nil { return rl, &ServiceVariableError{name: kw, - msg: err.Error(), - fatal: true} + msg: err.Error(), + fatal: true} } } return rl, nil } -// A service variable error +// A service variable error type ServiceVariableError struct { name string // Keyword that caused the error. msg string // Error message. @@ -122,22 +122,22 @@ func (s *SysVService) Assign (kw string, val string, cont bool) error { } if cont && kw != `Description` { return &ServiceVariableError{name: kw, - msg: "variable doesn't allow continuation", - fatal: true} - } + msg: "variable doesn't allow continuation", + fatal: true} + } switch kw { case `Provides`: if len(s.provided) != 0 { return &ServiceVariableError{name: kw, - msg: "variable redefined", - fatal: true} + msg: "variable redefined", + fatal: true} } s.provided = splitLine(val) case `Require-Start`,`Required-Start`: if len(s.requiredStart) != 0 { return &ServiceVariableError{name: kw, - msg: "variable redefined", - fatal: true} + msg: "variable redefined", + fatal: true} } if val != `` { s.requiredStart = splitLine(val) @@ -145,8 +145,8 @@ func (s *SysVService) Assign (kw string, val string, cont bool) error { case `Require-Stop`,`Required-Stop`: if len(s.requiredStop) != 0 { return &ServiceVariableError{name: kw, - msg: "variable redefined", - fatal: true} + msg: "variable redefined", + fatal: true} } if val != `` { s.requiredStop = splitLine(val) @@ -154,8 +154,8 @@ func (s *SysVService) Assign (kw string, val string, cont bool) error { case `Should-Start`: if len(s.shouldStart) != 0 { return &ServiceVariableError{name: kw, - msg: "variable redefined", - fatal: true} + msg: "variable redefined", + fatal: true} } if val != `` { s.shouldStart = splitLine(val) @@ -163,8 +163,8 @@ func (s *SysVService) Assign (kw string, val string, cont bool) error { case `Should-Stop`: if len(s.shouldStop) != 0 { return &ServiceVariableError{name: kw, - msg: "variable redefined", - fatal: true} + msg: "variable redefined", + fatal: true} } if val != `` { s.shouldStop = splitLine(val) @@ -172,9 +172,9 @@ func (s *SysVService) Assign (kw string, val string, cont bool) error { case `Default-Start`: // FIXME // if s.DefaultStart != nil { - // return &ServiceVariableError{name: kw, - // msg: "variable redefined", - // fatal: true} + // return &ServiceVariableError{name: kw, + // msg: "variable redefined", + // fatal: true} // } if val != `` { s.defaultStart, err = ToRunlevels(kw, val); @@ -182,9 +182,9 @@ func (s *SysVService) Assign (kw string, val string, cont bool) error { case `Default-Stop`: // FIXME // if s.DefaultStop != nil { - // return &ServiceVariableError{name: kw, - // msg: "variable redefined", - // fatal: true} + // return &ServiceVariableError{name: kw, + // msg: "variable redefined", + // fatal: true} // } if val != `` { s.defaultStop, err = ToRunlevels(kw, val) @@ -192,8 +192,8 @@ func (s *SysVService) Assign (kw string, val string, cont bool) error { case `Short-Description`: if s.shortDescr != `` { return &ServiceVariableError{name: kw, - msg: "variable redefined", - fatal: true} + msg: "variable redefined", + fatal: true} } if val != `` { s.shortDescr = val @@ -203,23 +203,23 @@ func (s *SysVService) Assign (kw string, val string, cont bool) error { s.descr += "\n" + val } else if s.descr != `` { return &ServiceVariableError{name: kw, - msg: "variable redefined", - fatal: true} + msg: "variable redefined", + fatal: true} } else { s.descr = val } default: err = &ServiceVariableError{name: kw, - msg: "unrecognized variable", - fatal: false} - } + msg: "unrecognized variable", + fatal: false} + } return err -} +} // Report error ERR in file F, line L. func FileErrorLog(f string, l int, err error) { log.Println(f + ":" + strconv.Itoa(l) + ": " + err.Error()) -} +} // Same as above, but for warnings. func FileWarningLog(f string, l int, err error) { @@ -265,8 +265,8 @@ func ReadServiceFile(f string) (Service, error) { last_keyword = res[1] } else if ve, ok := err.(*ServiceVariableError); ok && ve.IsFatal() { FileErrorLog(f, line, err) - state = stateErr - } else { + state = stateErr + } else { FileWarningLog(f, line, err) // FIXME break @@ -276,23 +276,22 @@ func ReadServiceFile(f string) (Service, error) { FileErrorLog(f, line, err) state = stateErr } - } else { + } else { state = stateStop break } } } - switch state { + switch state { case stateInit: return nil, errors.New(f + ": no init info section") case stateErr: return nil, errors.New(f + ": errors in init info section") default: // if len(service.provided) == 0 || (len(service.DefaultStart) == 0 && len(service.DefaultStop) == 0) { - // return nil, errors.New(f + ": incomplete init info section") - // } + // return nil, errors.New(f + ": incomplete init info section") + // } } return &service, nil } - |