Added SILC Thread Queue API
[crypto.git] / apps / irssi / src / lib-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 "common.h"
6
7 #include "popt.h"
8 #include "poptint.h"
9
10 static void configLine(poptContext con, char * line) {
11     int nameLength = strlen(con->appName);
12     char * opt;
13     struct poptAlias alias;
14     char * entryType;
15     char * longName = NULL;
16     char shortName = '\0';
17     
18     if (strncmp(line, con->appName, nameLength)) return;
19     line += nameLength;
20     if (!*line || !i_isspace(*line)) return;
21     while (*line && i_isspace(*line)) line++;
22     entryType = line;
23
24     while (!*line || !i_isspace(*line)) line++;
25     *line++ = '\0';
26     while (*line && i_isspace(*line)) line++;
27     if (!*line) return;
28     opt = line;
29
30     while (!*line || !i_isspace(*line)) line++;
31     *line++ = '\0';
32     while (*line && i_isspace(*line)) line++;
33     if (!*line) return;
34
35     if (opt[0] == '-' && opt[1] == '-')
36         longName = opt + 2;
37     else if (opt[0] == '-' && !opt[2])
38         shortName = opt[1];
39
40     if (!strcmp(entryType, "alias")) {
41         if (poptParseArgvString(line, &alias.argc, &alias.argv)) return;
42         alias.longName = longName, alias.shortName = shortName;
43         poptAddAlias(con, alias, 0);
44     } else if (!strcmp(entryType, "exec")) {
45         con->execs = realloc(con->execs, 
46                                 sizeof(*con->execs) * (con->numExecs + 1));
47         if (longName)
48             con->execs[con->numExecs].longName = g_strdup(longName);
49         else
50             con->execs[con->numExecs].longName = NULL;
51
52         con->execs[con->numExecs].shortName = shortName;
53         con->execs[con->numExecs].script = g_strdup(line);
54         
55         con->numExecs++;
56     }
57 }
58
59 int poptReadConfigFile(poptContext con, char * fn) {
60     char * file, * chptr, * end;
61     char * buf, * dst;
62     int fd, rc;
63     int fileLength;
64
65     fd = open(fn, O_RDONLY);
66     if (fd < 0) {
67         if (errno == ENOENT)
68             return 0;
69         else 
70             return POPT_ERROR_ERRNO;
71     }
72
73     fileLength = lseek(fd, 0, SEEK_END);
74     lseek(fd, 0, 0);
75
76     file = malloc(fileLength + 1);
77     if (read(fd, file, fileLength) != fileLength) {
78         rc = errno;
79         close(fd);
80         errno = rc;
81         free(file);
82         return POPT_ERROR_ERRNO;
83     }
84     close(fd);
85
86     dst = buf = malloc(fileLength + 1);
87
88     chptr = file;
89     end = (file + fileLength);
90     while (chptr < end) {
91         switch (*chptr) {
92           case '\n':
93             *dst = '\0';
94             dst = buf;
95             while (*dst && i_isspace(*dst)) dst++;
96             if (*dst && *dst != '#') {
97                 configLine(con, dst);
98             }
99             chptr++;
100             break;
101           case '\\':
102             *dst++ = *chptr++;
103             if (chptr < end) {
104                 if (*chptr == '\n') 
105                     dst--, chptr++;     
106                     /* \ at the end of a line does not insert a \n */
107                 else
108                     *dst++ = *chptr++;
109             }
110             break;
111           default:
112             *dst++ = *chptr++;
113         }
114     }
115
116     free(buf);
117     free(file);
118     return 0;
119 }
120
121 int poptReadDefaultConfig(poptContext con, 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 #ifndef WIN32
130     if (getuid() != geteuid()) return 0;
131 #endif
132
133     if ((home = getenv("HOME"))) {
134         fn = malloc(strlen(home) + 20);
135         strcpy(fn, home);
136         strcat(fn, "/.popt");
137         rc = poptReadConfigFile(con, fn);
138         free(fn);
139         if (rc) return rc;
140     }
141
142     return 0;
143 }
144