~ubuntu-branches/ubuntu/hoary/apt-spy/hoary

« back to all changes in this revision

Viewing changes to parse.c

  • Committer: Bazaar Package Importer
  • Author(s): Stephen Stafford
  • Date: 2004-12-09 12:45:08 UTC
  • mfrom: (2.1.1 warty)
  • Revision ID: james.westby@ubuntu.com-20041209124508-we5ajs683urbb3jg
Tags: 3.1-13
* Transition to libcurl3 (Closes: #279472)
* fix manpage (Closes: #281897)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* 
 
2
 * apt-spy (c) Steven Holmes, 2003. 
 
3
 * This software is licensed as detailed in the LICENSE file. 
 
4
 */
 
5
 
 
6
/* This file is a bit icky */
 
7
 
 
8
char *str_toupper(char *str);
 
9
 
 
10
#include <stdio.h>
 
11
#include <unistd.h>
 
12
#include <string.h>
 
13
#include <stdlib.h>
 
14
#include <ctype.h>
 
15
 
 
16
#include "include/global.h"
 
17
#include "include/parse.h" 
 
18
#include "include/file.h"
 
19
 
 
20
int build_area_file(FILE *config_p, FILE *infile_p, FILE *mirror_list, char *area)
 
21
{
 
22
        char *line;             /* Where we read the lines into */
 
23
        char *tmp;              /* Temp. pointer */
 
24
        char *inputline;        /* The line that will be written to config_p */
 
25
        char *country_code;     /* where we put the country code */
 
26
 
 
27
        /* Uppercase area */
 
28
        str_toupper(area);
 
29
 
 
30
        /* EWWWWWWW */
 
31
        while((line = next_entry(config_p)) != NULL) {
 
32
                /* Uppercase line */
 
33
                str_toupper(line);
 
34
                
 
35
                /* test for area string */
 
36
                if ((tmp = strstr(line, area)) != NULL) {
 
37
                
 
38
                        if ((strchr(tmp,':')) == NULL) {        /* And for trailing colon.. */
 
39
                                free(line);
 
40
                                continue;                       /* .. it's not there */
 
41
                        }
 
42
                        break;
 
43
                }
 
44
                free(line);
 
45
 
 
46
                if (ferror(config_p) != 0)                      /* Check for File error */
 
47
                        return 1;
 
48
        }
 
49
 
 
50
        /* No match. Return. */
 
51
        if (line == NULL) {
 
52
                fprintf(stderr, "Could not find area named %s\n", area);
 
53
                return 1;
 
54
        }
 
55
        
 
56
        free(line);
 
57
                
 
58
        /* We now have the "label" line. The country list begins on the next line. */
 
59
        while ((line = next_entry(config_p)) != NULL) {
 
60
 
 
61
                if (ferror(config_p) != 0) {    /* Check for file error */
 
62
                        free(line);
 
63
                        return 1;
 
64
                }
 
65
 
 
66
                /* Skip blank lines */
 
67
                country_code = line;
 
68
 
 
69
                /* We check for either a non-space or a '\n'. Has the useful side-effect of */
 
70
                /* fast-forwarding country_code past any preceding whitespace.*/
 
71
                while ((*country_code != '\n') && (isspace(*country_code) != 0))
 
72
                        ++country_code;
 
73
                
 
74
                /* If country_code points to a '\n', there were no other characters. It was a blank line. */
 
75
                /* If it points to a '#', there is a comment. We skip it too. */
 
76
                if ((*country_code == '\n') || (*country_code == '#'))
 
77
                        continue;
 
78
 
 
79
                if ((strchr(line, ':')) != NULL)
 
80
                        return 0;                       /* End of list. Return. */
 
81
 
 
82
                /* We do a little fiddling to get the country code down to 2 letters and a space */
 
83
                *(country_code + 2) = ' ';
 
84
                *(country_code + 3) = '\0';
 
85
 
 
86
                /* Sigh. The country code is in "country_code". We now parse the mirrors file for this */
 
87
                /* and set the file position so that the next read will return the first */
 
88
                /* mirror. */
 
89
                
 
90
                if (find_country(mirror_list, country_code) == 1) {
 
91
                        fprintf(stderr, "Couldn't find country %s. Skipping.\n", country_code);
 
92
                        free(line);
 
93
                        continue;
 
94
                }
 
95
 
 
96
                /* The next read of infile_p will return the first mirror entry. We parse */
 
97
                /* this and build a line to put into the temporary file. */
 
98
 
 
99
                while ((inputline = get_mirrors(mirror_list)) != NULL) {
 
100
 
 
101
                        /* We now write the line to the temporary file */       
 
102
                        fputs(inputline, infile_p);
 
103
                        free(inputline);
 
104
 
 
105
                        if ((ferror(infile_p)) != 0) {  /* Check for file error */
 
106
                                free(line);
 
107
                                return 1;
 
108
                        }
 
109
                }
 
110
 
 
111
                free(line);
 
112
        }
 
113
        return 0;
 
114
}
 
115
 
 
116
int build_country_file(FILE *config_p, FILE *infile_p, FILE *mirror_list, char *country_list)
 
117
{
 
118
        char *country_code;
 
119
        char *p, *q; 
 
120
        char *inputline;
 
121
 
 
122
        int found = 0;
 
123
 
 
124
        /* Upper-case country list */
 
125
        str_toupper(country_list);
 
126
 
 
127
        /* A cheap way to make sure we have enough space */
 
128
        country_code = malloc(strlen(country_code));
 
129
 
 
130
        p = country_list;
 
131
 
 
132
        while (*p != '\0') {
 
133
                /* Reset country code pointer */
 
134
                q = country_code;
 
135
        
 
136
                /* Skip white space */
 
137
                while (isspace(*p))
 
138
                        ++p;
 
139
                        
 
140
                /* Copy up until end or comma */
 
141
                while ((*p != '\0') && (*p != ',') && (isspace(*p) == 0))
 
142
                        *q++ = *p++;
 
143
                        
 
144
                /* Skip more white space. *sigh* */
 
145
                while (isspace(*p))
 
146
                        ++p;
 
147
        
 
148
                /* skip past comma */
 
149
                if (*p != '\0')
 
150
                        ++p;
 
151
                
 
152
                /* String-ify */
 
153
                *q++ = ' ';
 
154
                *q = '\0';
 
155
 
 
156
                /* And find the country/build the file */
 
157
                if (find_country(mirror_list, country_code) == 1) {
 
158
                        fprintf(stderr, "Couldn't find country %s. Skipping.\n", country_code);
 
159
                        continue;
 
160
                }
 
161
 
 
162
                found = 1;
 
163
 
 
164
                while ((inputline = get_mirrors(mirror_list)) != NULL) {
 
165
                        fputs(inputline, infile_p);
 
166
                        free(inputline);
 
167
                        
 
168
                        if (ferror(infile_p)) {
 
169
                                free(country_code);
 
170
                                return 1;
 
171
                        }
 
172
                }
 
173
        }
 
174
        free(country_code);
 
175
        
 
176
        /* Check we have found at least one country */
 
177
        if (found == 0)
 
178
                return 1;
 
179
        else
 
180
                return 0;
 
181
}
 
182
 
 
183
int find_country(FILE *mirror_list, char *country_code)
 
184
{
 
185
        char *line, *cc;
 
186
 
 
187
        /* Make sure we're at beginning of file */
 
188
        rewind(mirror_list);
 
189
 
 
190
        /* This is a hack to allow users to specify "UK" instead of "GB" */
 
191
        if (!strcmp(country_code, "UK "))
 
192
                strncpy(country_code, "GB ", 4);
 
193
 
 
194
        /* Read until we find the country code */
 
195
        while ((line = next_entry(mirror_list)) != NULL) {
 
196
 
 
197
                cc = strstr(line, country_code);
 
198
                if (cc == NULL)
 
199
                        continue;
 
200
                        
 
201
                /* Skip white space */
 
202
                while (isspace(*line))
 
203
                        ++line;
 
204
                
 
205
                /* Country code should be first two characters on line. */
 
206
                if (cc == line)         
 
207
                        break;
 
208
        }
 
209
 
 
210
        if (line == NULL)
 
211
                return 1;
 
212
        
 
213
        next_entry(mirror_list);                /* Skip a line */
 
214
        
 
215
        if (ferror(mirror_list)) {
 
216
                free(line);
 
217
                return 1;
 
218
        }
 
219
        return 0;               /* We're positioned nicely for the next read */
 
220
}
 
221
 
 
222
/* line format is "server:ftp-path:http-path". */
 
223
 
 
224
char *get_mirrors(FILE *mirror_list)
 
225
{
 
226
        char *line, *save_line;
 
227
        char *creation, *save_creation;
 
228
        int counter = 0;
 
229
 
 
230
        /* Allocate space for creation */
 
231
        save_creation = creation = malloc(100);
 
232
 
 
233
        if (creation == NULL) {
 
234
                perror("malloc");
 
235
                exit(1);
 
236
        }
 
237
 
 
238
 
 
239
        /* First, we read in a line from the file */
 
240
        save_line = line = next_entry(mirror_list);
 
241
 
 
242
        /* test for file error */
 
243
        if (ferror(mirror_list)) {
 
244
                perror("fopen");
 
245
                return NULL;
 
246
        }
 
247
        
 
248
        /* If the line begins with a space, we assume it is empty and the list is exhausted. */
 
249
        if (isspace(*line) != 0)
 
250
                return NULL;
 
251
 
 
252
        /* We now read the server name into "creation" */
 
253
        while (isspace(*line) == 0)
 
254
                *creation++ = *line++;
 
255
 
 
256
        /* And add a colon, which is the field seperator */
 
257
        *creation++ = ':';
 
258
        
 
259
        /* We skip over whitespace. If there is a lot of whitespace, we assume there is no FTP entry. */
 
260
        while ((isspace(*line) != 0) && (counter < 30)) {
 
261
                ++line;
 
262
                ++counter;
 
263
        }
 
264
 
 
265
        /* Check if there is an entry or just more space */     
 
266
        while (isspace(*line) == 0) 
 
267
                *creation++ = *line++;
 
268
 
 
269
        *creation++ = ':';
 
270
 
 
271
        /* We now check for an HTTP entry */
 
272
        while (*line != '\n') {
 
273
                if (isspace(*line) == 0)
 
274
                        break;
 
275
                line++;
 
276
        }
 
277
 
 
278
        while (isspace(*line) == 0)
 
279
                *creation++ = *line++;
 
280
 
 
281
        *creation++ = ':';
 
282
        *creation++ = '\n';
 
283
        *creation++ = '\0';
 
284
 
 
285
        free(save_line);
 
286
        
 
287
        return save_creation;
 
288
}
 
289
 
 
290
void tokenise(server_t *current, char *cur_entry)
 
291
{
 
292
        char *temp;     /* We use this for temporary string-pointing :P */
 
293
 
 
294
        /* We initialise the structure to 0 */
 
295
        memset(current, 0, sizeof(*current));
 
296
 
 
297
        /* First, we copy the server name into the struct. */
 
298
        temp = current->hostname;
 
299
        while (*cur_entry != ':')
 
300
                *temp++ = *cur_entry++;
 
301
 
 
302
        *temp++ = '\0';         /* Turn into string */
 
303
 
 
304
        /* We now check for an ftp entry and copy it in */
 
305
        if (*(++cur_entry) != ':') {
 
306
                temp = current->path[FTP];              
 
307
                while (*cur_entry != ':')
 
308
                        *temp++ = *cur_entry++;
 
309
                        
 
310
                *temp++ = '\0';
 
311
        }
 
312
 
 
313
        /* And now check for HTTP entry */
 
314
        if (*(++cur_entry) != ':') {
 
315
                temp = current->path[HTTP];
 
316
                while (*cur_entry != ':')
 
317
                        *temp++ = *cur_entry++;
 
318
                        
 
319
                *temp++ = '\0';
 
320
        }
 
321
 
 
322
        /* We're done for now */
 
323
}
 
324
 
 
325
int write_list(FILE *outfile_p, server_t *best, char *dist)
 
326
{
 
327
        char url[100];
 
328
 
 
329
        /* Make our mark ;) */
 
330
        fprintf(outfile_p, "# sources.list generated by apt-spy %s\n", apt_spy_v);
 
331
 
 
332
        /* Copy URL information */
 
333
        if (best[0].stats.protocol == FTP)
 
334
                strncpy(url, best[0].url[FTP], 100);
 
335
        else
 
336
                strncpy(url, best[0].url[HTTP], 100);
 
337
 
 
338
        /* And write the line */
 
339
        fprintf(outfile_p, "deb %s %s main\n", url, dist);
 
340
 
 
341
        /* We also write a deb-src line */
 
342
        fprintf(outfile_p, "deb-src %s %s main\n", url, dist);
 
343
 
 
344
        /* And if we are using "stable", add a security line. Otherwise comment it out.*/
 
345
        if (strcmp(dist, "stable") == 0)
 
346
                fprintf(outfile_p, "deb http://security.debian.org/ stable/updates main\n");
 
347
        else
 
348
                fprintf(outfile_p, "#deb http://security.debian.org/ stable/updates main\n");
 
349
 
 
350
        if (ferror(outfile_p) != 0) {
 
351
                perror("fprintf");
 
352
                return 1;
 
353
        }
 
354
        return 0;
 
355
}
 
356
 
 
357
int write_top(FILE *infile_p, FILE *outfile_p, server_t *best)
 
358
{
 
359
        int i = 0;
 
360
        char *line;
 
361
        
 
362
        while (i < BESTNUMBER) {
 
363
        
 
364
                /* Make sure we're at the beginning */
 
365
                rewind(infile_p);
 
366
                
 
367
                /* Read in a line... */
 
368
                while ((line = next_entry(infile_p)) != NULL)
 
369
                        if (strstr(line, best[i].hostname) != NULL)     /* Check for hostname */
 
370
                                fputs(line, outfile_p);         /* if it's there, write to file */
 
371
                
 
372
                if ((ferror(infile_p) != 0) || (ferror(outfile_p) != 0))
 
373
                        return 1;
 
374
                ++i;
 
375
        }
 
376
        return 0;
 
377
}
 
378
 
 
379
/* Utility function */
 
380
char *str_toupper(char *str)
 
381
{
 
382
        while (*str != '\0') {
 
383
                *str = toupper(*str);
 
384
                str++;
 
385
        }
 
386
        return str;
 
387
}