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