Initial import
[samba] / source / popt / poptconfig.c
1 /* (C) 1998 Red Hat Software, Inc. -- Licensing details are in the COPYING
2    file accompanying popt source distributions, available from 
3    ftp://ftp.redhat.com/pub/code/popt */
4
5 #include "system.h"
6 #include "poptint.h"
7
8 static void configLine(poptContext con, char * line) {
9     int nameLength = strlen(con->appName);
10     char * opt;
11     struct poptAlias alias;
12     char * entryType;
13     char * longName = NULL;
14     char shortName = '\0';
15     
16     if (strncmp(line, con->appName, nameLength)) return;
17     line += nameLength;
18     if (!*line || !isspace(*line)) return;
19     while (*line && isspace(*line)) line++;
20     entryType = line;
21
22     while (!*line || !isspace(*line)) line++;
23     *line++ = '\0';
24     while (*line && isspace(*line)) line++;
25     if (!*line) return;
26     opt = line;
27
28     while (!*line || !isspace(*line)) line++;
29     *line++ = '\0';
30     while (*line && isspace(*line)) line++;
31     if (!*line) return;
32
33     if (opt[0] == '-' && opt[1] == '-')
34         longName = opt + 2;
35     else if (opt[0] == '-' && !opt[2])
36         shortName = opt[1];
37
38     if (!strcmp(entryType, "alias")) {
39         if (poptParseArgvString(line, &alias.argc, &alias.argv)) return;
40         alias.longName = longName, alias.shortName = shortName;
41         poptAddAlias(con, alias, 0);
42     } else if (!strcmp(entryType, "exec")) {
43         con->execs = realloc(con->execs,
44                                 sizeof(*con->execs) * (con->numExecs + 1));
45         if (longName)
46             con->execs[con->numExecs].longName = xstrdup(longName);
47         else
48             con->execs[con->numExecs].longName = NULL;
49
50         con->execs[con->numExecs].shortName = shortName;
51         con->execs[con->numExecs].script = xstrdup(line);
52         
53         con->numExecs++;
54     }
55 }
56
57 int poptReadConfigFile(poptContext con, const char * fn) {
58     char * file=NULL, * chptr, * end;
59     char * buf=NULL, * dst;
60     int fd, rc;
61     int fileLength;
62
63     fd = open(fn, O_RDONLY);
64     if (fd < 0) {
65         if (errno == ENOENT)
66             return 0;
67         else 
68             return POPT_ERROR_ERRNO;
69     }
70
71     fileLength = lseek(fd, 0, SEEK_END);
72     (void) lseek(fd, 0, 0);
73
74     file = malloc(fileLength + 1);
75     if (read(fd, file, fileLength) != fileLength) {
76         rc = errno;
77         close(fd);
78         errno = rc;
79         if (file) free(file);
80         return POPT_ERROR_ERRNO;
81     }
82     close(fd);
83
84     dst = buf = malloc(fileLength + 1);
85
86     chptr = file;
87     end = (file + fileLength);
88     while (chptr < end) {
89         switch (*chptr) {
90           case '\n':
91             *dst = '\0';
92             dst = buf;
93             while (*dst && isspace(*dst)) dst++;
94             if (*dst && *dst != '#') {
95                 configLine(con, dst);
96             }
97             chptr++;
98             break;
99           case '\\':
100             *dst++ = *chptr++;
101             if (chptr < end) {
102                 if (*chptr == '\n') 
103                     dst--, chptr++;     
104                     /* \ at the end of a line does not insert a \n */
105                 else
106                     *dst++ = *chptr++;
107             }
108             break;
109           default:
110             *dst++ = *chptr++;
111             break;
112         }
113     }
114
115     free(file);
116     free(buf);
117
118     return 0;
119 }
120
121 int poptReadDefaultConfig(poptContext con, /*@unused@*/ int useEnv) {
122     char * fn, * home;
123     int rc;
124
125     if (!con->appName) return 0;
126
127     rc = poptReadConfigFile(con, "/etc/popt");
128     if (rc) return rc;
129     if (getuid() != geteuid()) return 0;
130
131     if ((home = getenv("HOME"))) {
132         fn = malloc(strlen(home) + 20);
133         strcpy(fn, home);
134         strcat(fn, "/.popt");
135         rc = poptReadConfigFile(con, fn);
136         free(fn);
137         if (rc) return rc;
138     }
139
140     return 0;
141 }
142