00001
00005
00006
00007
00008
00009 #include "system.h"
00010 #include "poptint.h"
00011 #include <sys/stat.h>
00012
00013 #if defined(HAVE_GLOB_H)
00014 #include <glob.h>
00015
00016 #if defined(__LCLINT__)
00017
00018 extern int glob (const char *__pattern, int __flags,
00019 int (*__errfunc) (const char *, int),
00020 glob_t *__pglob)
00021
00022 ;
00023
00024 extern void globfree ( glob_t *__pglob)
00025 ;
00026
00027 #endif
00028 #endif
00029
00030
00031
00032
00033 static void configLine(poptContext con, char * line)
00034
00035 {
00036 size_t nameLength;
00037 const char * entryType;
00038 const char * opt;
00039 struct poptItem_s item_buf;
00040 poptItem item = &item_buf;
00041 int i, j;
00042
00043 if (con == NULL || con->appName == NULL)
00044 return;
00045 nameLength = strlen(con->appName);
00046
00047 memset(item, 0, sizeof(*item));
00048
00049 if (strncmp(line, con->appName, nameLength)) return;
00050
00051 line += nameLength;
00052 if (*line == '\0' || !_isspaceptr(line)) return;
00053
00054 while (*line != '\0' && _isspaceptr(line)) line++;
00055 entryType = line;
00056 while (*line == '\0' || !_isspaceptr(line)) line++;
00057 *line++ = '\0';
00058
00059 while (*line != '\0' && _isspaceptr(line)) line++;
00060 if (*line == '\0') return;
00061 opt = line;
00062 while (*line == '\0' || !_isspaceptr(line)) line++;
00063 *line++ = '\0';
00064
00065 while (*line != '\0' && _isspaceptr(line)) line++;
00066 if (*line == '\0') return;
00067
00068
00069 if (opt[0] == '-' && opt[1] == '-')
00070 item->option.longName = opt + 2;
00071 else if (opt[0] == '-' && opt[2] == '\0')
00072 item->option.shortName = opt[1];
00073
00074
00075 if (poptParseArgvString(line, &item->argc, &item->argv)) return;
00076
00077
00078 item->option.argInfo = POPT_ARGFLAG_DOC_HIDDEN;
00079 for (i = 0, j = 0; i < item->argc; i++, j++) {
00080 const char * f;
00081 if (!strncmp(item->argv[i], "--POPTdesc=", sizeof("--POPTdesc=")-1)) {
00082 f = item->argv[i] + sizeof("--POPTdesc=");
00083 if (f[0] == '$' && f[1] == '"') f++;
00084 item->option.descrip = f;
00085 item->option.argInfo &= ~POPT_ARGFLAG_DOC_HIDDEN;
00086 j--;
00087 } else
00088 if (!strncmp(item->argv[i], "--POPTargs=", sizeof("--POPTargs=")-1)) {
00089 f = item->argv[i] + sizeof("--POPTargs=");
00090 if (f[0] == '$' && f[1] == '"') f++;
00091 item->option.argDescrip = f;
00092 item->option.argInfo &= ~POPT_ARGFLAG_DOC_HIDDEN;
00093 item->option.argInfo |= POPT_ARG_STRING;
00094 j--;
00095 } else
00096 if (j != i)
00097 item->argv[j] = item->argv[i];
00098 }
00099 if (j != i) {
00100 item->argv[j] = NULL;
00101 item->argc = j;
00102 }
00103
00104
00105
00106 if (!strcmp(entryType, "alias"))
00107 (void) poptAddItem(con, item, 0);
00108 else if (!strcmp(entryType, "exec"))
00109 (void) poptAddItem(con, item, 1);
00110
00111 }
00112
00113
00114 int poptReadConfigFile(poptContext con, const char * fn)
00115 {
00116 char * file = NULL, * chptr, * end;
00117 char * buf = NULL;
00118 char * dst;
00119 int fd, rc;
00120 off_t fileLength;
00121
00122 if (con == NULL) return POPT_ERROR_NOCONTEXT;
00123
00124 fd = open(fn, O_RDONLY);
00125 if (fd < 0)
00126 return (errno == ENOENT ? 0 : POPT_ERROR_ERRNO);
00127
00128 fileLength = lseek(fd, 0, SEEK_END);
00129 if (fileLength == (off_t)-1 || lseek(fd, 0, 0) == (off_t)-1) {
00130 rc = errno;
00131 (void) close(fd);
00132 errno = rc;
00133 return POPT_ERROR_ERRNO;
00134 }
00135
00136 if ((file = malloc((size_t)fileLength + 1)) != NULL)
00137 *file = '\0';
00138 if (file == NULL
00139 || read(fd, (char *)file, (size_t)fileLength) != (ssize_t)fileLength)
00140 {
00141 rc = errno;
00142 (void) close(fd);
00143 errno = rc;
00144 if (file)
00145 free(file);
00146 return POPT_ERROR_ERRNO;
00147 }
00148 if (close(fd) == -1) {
00149 free(file);
00150 return POPT_ERROR_ERRNO;
00151 }
00152
00153 dst = buf = malloc((size_t)fileLength + 1);
00154 if (dst == NULL)
00155 return POPT_ERROR_ERRNO;
00156
00157 end = (file + fileLength);
00158 for (chptr = file; chptr < end; chptr++) {
00159 switch (*chptr) {
00160 case '\n':
00161 *dst = '\0';
00162 dst = buf;
00163 while (*dst && _isspaceptr(dst)) dst++;
00164 if (*dst && *dst != '#')
00165 configLine(con, dst);
00166 break;
00167 case '\\':
00168 *dst = *chptr++;
00169
00170 if (chptr < end && *chptr != '\n') {
00171 dst++;
00172 *dst++ = *chptr;
00173 }
00174 break;
00175 default:
00176 *dst++ = *chptr;
00177 break;
00178 }
00179 }
00180
00181 free(file);
00182 free(buf);
00183
00184 return 0;
00185 }
00186
00187 int poptReadDefaultConfig(poptContext con, UNUSED(int useEnv))
00188 {
00189 static const char _popt_sysconfdir[] = POPT_SYSCONFDIR "/popt";
00190 static const char _popt_etc[] = "/etc/popt";
00191 char * fn, * home;
00192 struct stat s;
00193 int rc;
00194
00195 if (con == NULL || con->appName == NULL) return 0;
00196
00197 if (strcmp(_popt_sysconfdir, _popt_etc)) {
00198 rc = poptReadConfigFile(con, _popt_sysconfdir);
00199 if (rc) return rc;
00200 }
00201
00202 rc = poptReadConfigFile(con, _popt_etc);
00203 if (rc) return rc;
00204
00205 #if defined(HAVE_GLOB_H)
00206 if (!stat("/etc/popt.d", &s) && S_ISDIR(s.st_mode)) {
00207 glob_t _g, *pglob = &_g;
00208 if (!glob("/etc/popt.d/*", 0, NULL, pglob)) {
00209 size_t i;
00210 for (i = 0; i < pglob->gl_pathc; i++) {
00211 char * f = pglob->gl_pathv[i];
00212 if (strstr(f, ".rpmnew") || strstr(f, ".rpmsave"))
00213 continue;
00214 if (!stat(f, &s)) {
00215 if (!S_ISREG(s.st_mode) && !S_ISLNK(s.st_mode))
00216 continue;
00217 }
00218 rc = poptReadConfigFile(con, f);
00219 if (rc) return rc;
00220 }
00221 globfree(pglob);
00222 }
00223 }
00224 #endif
00225
00226 if ((home = getenv("HOME"))) {
00227 fn = malloc(strlen(home) + 20);
00228 if (fn != NULL) {
00229 (void) stpcpy(stpcpy(fn, home), "/.popt");
00230 rc = poptReadConfigFile(con, fn);
00231 free(fn);
00232 } else
00233 rc = POPT_ERROR_ERRNO;
00234 if (rc) return rc;
00235 }
00236
00237 return 0;
00238 }