1 // Main file for nsscash
3 // Copyright (C) 2019 Simon Ruderich
5 // This program is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU Affero General Public License as published by
7 // the Free Software Foundation, either version 3 of the License, or
8 // (at your option) any later version.
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU Affero General Public License for more details.
15 // You should have received a copy of the GNU Affero General Public License
16 // along with this program. If not, see <https://www.gnu.org/licenses/>.
32 fmt.Fprintf(os.Stderr,
33 "usage: %[1]s [options] fetch <config>\n"+
34 "usage: %[1]s [options] convert <type> <src> <dst>\n"+
53 err := mainFetch(args[1])
64 err := mainConvert(args[1], args[2], args[3])
75 func mainFetch(cfgPath string) error {
76 cfg, err := LoadConfig(cfgPath)
80 state, err := LoadState(cfg.StatePath)
84 err = handleFiles(cfg, state)
88 // NOTE: Make sure to call WriteState() only if there were no
89 // errors (see WriteState() and README)
90 err = WriteState(cfg.StatePath, state)
97 func mainConvert(typ, srcPath, dstPath string) error {
99 err := t.UnmarshalText([]byte(typ))
104 src, err := ioutil.ReadFile(srcPath)
109 if t == FileTypePlain {
111 } else if t == FileTypePasswd {
112 pws, err := ParsePasswds(bytes.NewReader(src))
116 err = SerializePasswds(&x, pws)
120 } else if t == FileTypeGroup {
121 grs, err := ParseGroups(bytes.NewReader(src))
125 err = SerializeGroups(&x, grs)
130 return fmt.Errorf("unsupported file type %v", t)
133 dstDir := filepath.Dir(dstPath)
134 dstName := filepath.Base(dstPath)
136 // We must create the file first or deployFile() will abort; this is
137 // ugly because deployFile() already performs an atomic replacement
138 // but the simplest solution with the least duplicate code
139 f, err := ioutil.TempFile(dstDir, "tmp-"+dstName+"-")
144 defer os.Remove(tmpPath)
147 err = deployFile(&File{
157 return os.Rename(tmpPath, dstPath)