00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "system.h"
00010 #include "poptint.h"
00011
00012
00013 static void configLine(poptContext con, char * line)
00014
00015 {
00016
00017 int nameLength = strlen(con->appName);
00018
00019 const char * entryType;
00020 const char * opt;
00021 poptItem item = alloca(sizeof(*item));
00022 int i, j;
00023
00024
00025 memset(item, 0, sizeof(*item));
00026
00027
00028 if (strncmp(line, con->appName, nameLength)) return;
00029
00030
00031 line += nameLength;
00032 if (*line == '\0' || !isspace(*line)) return;
00033
00034 while (*line != '\0' && isspace(*line)) line++;
00035 entryType = line;
00036 while (*line == '\0' || !isspace(*line)) line++;
00037 *line++ = '\0';
00038
00039 while (*line != '\0' && isspace(*line)) line++;
00040 if (*line == '\0') return;
00041 opt = line;
00042 while (*line == '\0' || !isspace(*line)) line++;
00043 *line++ = '\0';
00044
00045 while (*line != '\0' && isspace(*line)) line++;
00046 if (*line == '\0') return;
00047
00048
00049 if (opt[0] == '-' && opt[1] == '-')
00050 item->option.longName = opt + 2;
00051 else if (opt[0] == '-' && opt[2] == '\0')
00052 item->option.shortName = opt[1];
00053
00054
00055 if (poptParseArgvString(line, &item->argc, &item->argv)) return;
00056
00057
00058 item->option.argInfo = POPT_ARGFLAG_DOC_HIDDEN;
00059 for (i = 0, j = 0; i < item->argc; i++, j++) {
00060 const char * f;
00061 if (!strncmp(item->argv[i], "--POPTdesc=", sizeof("--POPTdesc=")-1)) {
00062 f = item->argv[i] + sizeof("--POPTdesc=");
00063 if (f[0] == '$' && f[1] == '"') f++;
00064 item->option.descrip = f;
00065 item->option.argInfo &= ~POPT_ARGFLAG_DOC_HIDDEN;
00066 j--;
00067 } else
00068 if (!strncmp(item->argv[i], "--POPTargs=", sizeof("--POPTargs=")-1)) {
00069 f = item->argv[i] + sizeof("--POPTargs=");
00070 if (f[0] == '$' && f[1] == '"') f++;
00071 item->option.argDescrip = f;
00072 item->option.argInfo &= ~POPT_ARGFLAG_DOC_HIDDEN;
00073 item->option.argInfo |= POPT_ARG_STRING;
00074 j--;
00075 } else
00076 if (j != i)
00077 item->argv[j] = item->argv[i];
00078 }
00079 if (j != i) {
00080 item->argv[j] = NULL;
00081 item->argc = j;
00082 }
00083
00084
00085
00086
00087 if (!strcmp(entryType, "alias"))
00088 (void) poptAddItem(con, item, 0);
00089 else if (!strcmp(entryType, "exec"))
00090 (void) poptAddItem(con, item, 1);
00091
00092 }
00093
00094
00095 int poptReadConfigFile(poptContext con, const char * fn)
00096 {
00097 const char * file, * chptr, * end;
00098 char * buf;
00099 char * dst;
00100 int fd, rc;
00101 off_t fileLength;
00102
00103 fd = open(fn, O_RDONLY);
00104 if (fd < 0)
00105 return (errno == ENOENT ? 0 : POPT_ERROR_ERRNO);
00106
00107 fileLength = lseek(fd, 0, SEEK_END);
00108 if (fileLength == -1 || lseek(fd, 0, 0) == -1) {
00109 rc = errno;
00110 (void) close(fd);
00111
00112 errno = rc;
00113
00114 return POPT_ERROR_ERRNO;
00115 }
00116
00117 file = alloca(fileLength + 1);
00118 if (read(fd, (char *)file, fileLength) != fileLength) {
00119 rc = errno;
00120 (void) close(fd);
00121
00122 errno = rc;
00123
00124 return POPT_ERROR_ERRNO;
00125 }
00126 if (close(fd) == -1)
00127 return POPT_ERROR_ERRNO;
00128
00129
00130 dst = buf = alloca(fileLength + 1);
00131
00132 chptr = file;
00133 end = (file + fileLength);
00134
00135 while (chptr < end) {
00136 switch (*chptr) {
00137 case '\n':
00138 *dst = '\0';
00139 dst = buf;
00140 while (*dst && isspace(*dst)) dst++;
00141 if (*dst && *dst != '#')
00142 configLine(con, dst);
00143 chptr++;
00144 break;
00145 case '\\':
00146 *dst++ = *chptr++;
00147 if (chptr < end) {
00148 if (*chptr == '\n')
00149 dst--, chptr++;
00150
00151 else
00152 *dst++ = *chptr++;
00153 }
00154 break;
00155 default:
00156 *dst++ = *chptr++;
00157 break;
00158 }
00159 }
00160
00161
00162
00163 return 0;
00164 }
00165
00166 int poptReadDefaultConfig(poptContext con, int useEnv)
00167 {
00168 char * fn, * home;
00169 int rc;
00170
00171
00172 if (!con->appName) return 0;
00173
00174
00175 rc = poptReadConfigFile(con, "/etc/popt");
00176 if (rc) return rc;
00177 #if defined(HAVE_GETUID) && defined(HAVE_GETEUID)
00178 if (getuid() != geteuid()) return 0;
00179 #endif
00180
00181 if ((home = getenv("HOME"))) {
00182 fn = alloca(strlen(home) + 20);
00183 strcpy(fn, home);
00184 strcat(fn, "/.popt");
00185 rc = poptReadConfigFile(con, fn);
00186 if (rc) return rc;
00187 }
00188
00189 return 0;
00190 }