219 |
mateuszvis |
1 |
/*
|
238 |
mateuszvis |
2 |
* This file is part of pkginst (SvarDOS).
|
219 |
mateuszvis |
3 |
*
|
238 |
mateuszvis |
4 |
* Loads the list of repositories from a config file.
|
219 |
mateuszvis |
5 |
*
|
238 |
mateuszvis |
6 |
* Copyright (C) 2012-2021 Mateusz Viste
|
219 |
mateuszvis |
7 |
*/
|
|
|
8 |
|
|
|
9 |
#include <stdio.h> /* printf(), fclose(), fopen()... */
|
|
|
10 |
#include <string.h> /* strcasecmp() */
|
|
|
11 |
#include <stdlib.h> /* malloc(), free() */
|
|
|
12 |
|
259 |
mateuszvis |
13 |
#include "pkginst.h" /* PKGINST_SKIPLINKS... */
|
219 |
mateuszvis |
14 |
#include "helpers.h" /* slash2backslash(), removeDoubleBackslashes()... */
|
|
|
15 |
#include "kprintf.h"
|
|
|
16 |
#include "loadconf.h"
|
|
|
17 |
#include "parsecmd.h"
|
|
|
18 |
|
|
|
19 |
|
225 |
mateuszvis |
20 |
void freeconf(struct customdirs **dirlist) {
|
219 |
mateuszvis |
21 |
struct customdirs *curpos;
|
|
|
22 |
/* free the linked list of custom dirs */
|
|
|
23 |
while (*dirlist != NULL) {
|
|
|
24 |
curpos = *dirlist;
|
|
|
25 |
*dirlist = (*dirlist)->next;
|
|
|
26 |
free(curpos);
|
|
|
27 |
}
|
|
|
28 |
}
|
|
|
29 |
|
|
|
30 |
|
238 |
mateuszvis |
31 |
static int checkfordoubledirlist(const struct customdirs *dirlist) {
|
219 |
mateuszvis |
32 |
struct customdirs *curpos;
|
|
|
33 |
for (; dirlist != NULL; dirlist = dirlist->next) {
|
|
|
34 |
for (curpos = dirlist->next; curpos != NULL; curpos = curpos->next) {
|
|
|
35 |
if (strcasecmp(curpos->name, dirlist->name) == 0) {
|
|
|
36 |
kitten_printf(7, 0, "Error: custom dir '%s' is listed twice!", curpos->name);
|
|
|
37 |
puts("");
|
|
|
38 |
return(-1);
|
|
|
39 |
}
|
|
|
40 |
}
|
|
|
41 |
}
|
|
|
42 |
return(0);
|
|
|
43 |
}
|
|
|
44 |
|
|
|
45 |
|
|
|
46 |
/* validates dirlist entries: check that they are absolute paths and are not using restricted names */
|
238 |
mateuszvis |
47 |
static int validatedirlist(const struct customdirs *dirlist) {
|
219 |
mateuszvis |
48 |
for (; dirlist != NULL; dirlist = dirlist->next) {
|
|
|
49 |
/* the location must be at least 3 characters long to be a valid absolute path (like 'c:\')*/
|
|
|
50 |
if (strlen(dirlist->location) < 3) {
|
|
|
51 |
kitten_printf(7, 15, "Error: custom dir '%s' is not a valid absolute path!", dirlist->name);
|
|
|
52 |
puts("");
|
|
|
53 |
return(-1);
|
|
|
54 |
}
|
|
|
55 |
/* is it a valid absolute path? should start with [a..Z]:\ */
|
|
|
56 |
if ((dirlist->location[1] != ':') ||
|
|
|
57 |
((dirlist->location[2] != '/') && (dirlist->location[2] != '\\')) ||
|
|
|
58 |
(((dirlist->location[0] < 'a') || (dirlist->location[0] > 'z')) && ((dirlist->location[0] < 'A') || (dirlist->location[0] > 'Z')))) {
|
|
|
59 |
kitten_printf(7, 15, "Error: custom dir '%s' is not a valid absolute path!", dirlist->name);
|
|
|
60 |
puts("");
|
|
|
61 |
return(-1);
|
|
|
62 |
}
|
|
|
63 |
/* check for forbidden names */
|
|
|
64 |
if ((strcasecmp(dirlist->name, "appinfo") == 0) ||
|
|
|
65 |
(strcasecmp(dirlist->name, "bin") == 0) ||
|
|
|
66 |
(strcasecmp(dirlist->name, "doc") == 0) ||
|
|
|
67 |
(strcasecmp(dirlist->name, "help") == 0) ||
|
|
|
68 |
(strcasecmp(dirlist->name, "nls") == 0) ||
|
|
|
69 |
(strcasecmp(dirlist->name, "packages") == 0)) {
|
|
|
70 |
kitten_printf(7, 16, "Error: custom dir '%s' is a reserved name!", dirlist->name);
|
|
|
71 |
puts("");
|
|
|
72 |
return(-1);
|
|
|
73 |
}
|
|
|
74 |
}
|
|
|
75 |
return(0);
|
|
|
76 |
}
|
|
|
77 |
|
|
|
78 |
|
|
|
79 |
/* add (and allocates) a new custom dir entry to dirlist. Returns 0 on success,
|
|
|
80 |
or non-zero on failure (failures happen on out of memory events). */
|
238 |
mateuszvis |
81 |
static int addnewdir(struct customdirs **dirlist, const char *name, const char *location) {
|
219 |
mateuszvis |
82 |
struct customdirs *newentry;
|
238 |
mateuszvis |
83 |
if (strlen(name) >= sizeof(newentry->name)) return(-2);
|
|
|
84 |
newentry = malloc(sizeof(struct customdirs) + strlen(location) + 1);
|
219 |
mateuszvis |
85 |
if (newentry == NULL) return(-1);
|
|
|
86 |
strcpy(newentry->name, name);
|
|
|
87 |
strcpy(newentry->location, location);
|
|
|
88 |
newentry->next = *dirlist;
|
|
|
89 |
*dirlist = newentry;
|
|
|
90 |
return(0);
|
|
|
91 |
}
|
|
|
92 |
|
|
|
93 |
|
260 |
mateuszvis |
94 |
int loadconf(const char *dosdir, struct customdirs **dirlist) {
|
219 |
mateuszvis |
95 |
FILE *fd;
|
248 |
mateuszvis |
96 |
char *value = NULL;
|
|
|
97 |
char token[512];
|
|
|
98 |
int nline = 0;
|
219 |
mateuszvis |
99 |
|
248 |
mateuszvis |
100 |
snprintf(token, sizeof(token), "%s\\cfg\\pkginst.cfg", dosdir);
|
|
|
101 |
fd = fopen(token, "r");
|
219 |
mateuszvis |
102 |
if (fd == NULL) {
|
248 |
mateuszvis |
103 |
kitten_printf(7, 1, "Error: Could not open config file (%s)!", token);
|
219 |
mateuszvis |
104 |
puts("");
|
|
|
105 |
return(-1);
|
|
|
106 |
}
|
|
|
107 |
|
260 |
mateuszvis |
108 |
*dirlist = NULL;
|
|
|
109 |
|
219 |
mateuszvis |
110 |
/* read the config file line by line */
|
248 |
mateuszvis |
111 |
while (freadtokval(fd, token, sizeof(token), &value, ' ') == 0) {
|
|
|
112 |
nline++;
|
|
|
113 |
|
|
|
114 |
/* skip comments and empty lines */
|
|
|
115 |
if ((token[0] == '#') || (token[0] == 0)) continue;
|
|
|
116 |
|
|
|
117 |
if ((value == NULL) || (value[0] == 0)) {
|
|
|
118 |
kitten_printf(7, 4, "Warning: token with empty value on line #%d", nline);
|
|
|
119 |
puts("");
|
|
|
120 |
continue;
|
|
|
121 |
}
|
|
|
122 |
|
|
|
123 |
/* printf("token='%s' ; value = '%s'\n", token, value); */
|
260 |
mateuszvis |
124 |
if (strcasecmp(token, "DIR") == 0) { /* custom directory entry */
|
248 |
mateuszvis |
125 |
char *argv[2];
|
|
|
126 |
if (parsecmd(value, argv, 2) != 2) {
|
|
|
127 |
kitten_printf(7, 11, "Warning: Invalid 'DIR' directive found at line #%d", nline);
|
|
|
128 |
puts("");
|
|
|
129 |
}
|
|
|
130 |
/* add the entry to the list */
|
|
|
131 |
slash2backslash(argv[1]);
|
|
|
132 |
removeDoubleBackslashes(argv[1]);
|
|
|
133 |
if (argv[1][strlen(argv[1]) - 1] != '\\') strcat(argv[1], "\\"); /* make sure to end dirs with a backslash */
|
|
|
134 |
if (addnewdir(dirlist, argv[0], argv[1]) != 0) {
|
|
|
135 |
kitten_printf(2, 14, "Out of memory! (%s)", "addnewdir");
|
|
|
136 |
puts("");
|
|
|
137 |
freeconf(dirlist);
|
|
|
138 |
fclose(fd);
|
|
|
139 |
return(-1);
|
|
|
140 |
}
|
|
|
141 |
} else { /* unknown token */
|
|
|
142 |
kitten_printf(7, 8, "Warning: Unknown token '%s' at line #%d", token, nline);
|
|
|
143 |
puts("");
|
219 |
mateuszvis |
144 |
}
|
248 |
mateuszvis |
145 |
}
|
219 |
mateuszvis |
146 |
fclose(fd);
|
|
|
147 |
|
225 |
mateuszvis |
148 |
/* perform some validations */
|
248 |
mateuszvis |
149 |
if ((checkfordoubledirlist(*dirlist) != 0) || (validatedirlist(*dirlist) != 0)) {
|
|
|
150 |
freeconf(dirlist);
|
|
|
151 |
return(-1);
|
|
|
152 |
}
|
219 |
mateuszvis |
153 |
|
225 |
mateuszvis |
154 |
return(0);
|
219 |
mateuszvis |
155 |
}
|