22
23
#define GLOB_ABORTED GLOB_ABEND
26
#define REALLOC_STEP 10
28
#if defined(SunOS) && !defined(isblank)
29
#define isblank(c) ( (c) == ' ' || (c) == '\t' ) ? 1 : 0
25
32
static char * defTabooExts[] = { ".rpmsave", ".rpmorig", "~", ",v",
26
".disabled", ".dpkg-old", ".dpkg-dist",
28
33
".rpmnew", ".swp" };
29
34
static int defTabooCount = sizeof(defTabooExts) / sizeof(char *);
35
40
static int readConfigFile(const char * configFile, logInfo * defConfig,
36
41
logInfo ** logsPtr, int * numLogsPtr);
37
42
static int globerr(const char * pathname, int theerr);
43
static struct rotatePatternElement * parsePattern(const char * pattern,
44
const char * configFile, int lineNum);
39
46
static int isolateValue(const char * fileName, int lineNum, char * key,
40
47
char ** startPtr, char ** endPtr) {
137
static int checkFile(const char * fname) {
140
/* Check if fname is '.' or '..'; if so, return false */
141
if (fname[0] == '.' &&
142
(!fname[1] || (fname[1] == '.' && !fname[2])))
145
/* Check if fname is ending in a taboo-extension; if so, return
147
for (i = 0; i < tabooCount; i++) {
148
if (!strcmp(fname + strlen(fname) - strlen(tabooExts[i]),
150
message(MESS_ERROR, "Ignoring %s, because of %s "
151
"ending\n", fname, tabooExts[i]);
157
/* All checks have been passed; return true */
161
/* Used by qsort to sort filelist */
162
static int compar(const void *p, const void *q) {
163
return strcoll(*((char **)p), *((char **)q));
166
/* Free memory blocks pointed to by pointers in namelist and namelist itself */
167
static void free_namelist (char **namelist, int files_count)
170
for (i=0; i<files_count; ++i)
175
static struct rotatePatternElement * parsePattern(const char * pattern,
176
const char * configFile, int lineNum) {
177
struct rotatePatternElement * head, * item;
178
struct rotatePatternElement new;
182
/* dummy head node; we build off of it */
183
head = alloca(sizeof(*head));
186
start = field = pattern;
187
memset(&new, 0, sizeof(new));
198
new.type = RP_FILENAME;
204
message(MESS_ERROR, "%s:%d unknown element %c in pattern %s",
205
configFile, lineNum, *field, pattern);
209
if (new.type != RP_NONE) {
210
if (start != field) {
212
item->next = malloc(sizeof(*item->next));
213
item->type = RP_STRING;
214
item->arg = malloc(field - start + 1);
215
strncpy(item->arg, start, field - start);
216
item->arg[field-start] = '\0';
220
item->next = malloc(sizeof(*item->next));
224
memset(&new, 0, sizeof(new));
230
if (start != field) {
232
item->next = malloc(sizeof(*item->next));
233
item->type = RP_STRING;
234
item->arg = malloc(field - start + 1);
235
strncpy(item->arg, start, field-start);
236
item->arg[field-start] = '\0';
130
243
int readConfigPath(const char * path, logInfo * defConfig,
131
244
logInfo ** logsPtr, int * numLogsPtr) {
138
248
if (!tabooExts) {
139
249
tabooExts = malloc(sizeof(*tabooExts) * defTabooCount);
149
259
if (S_ISDIR(sb.st_mode)) {
152
message(MESS_ERROR, "failed to open directory %s: %s\n", path,
260
char **namelist, **p;
157
265
here = open(".", O_RDONLY);
159
267
message(MESS_ERROR, "cannot open current directory: %s\n",
160
268
strerror(errno));
272
if ( (dirp = opendir(path)) == NULL) {
273
message(MESS_ERROR, "cannot open directory %s: %s\n", path,
279
while ((dp = readdir(dirp)) != NULL) {
280
if (checkFile(dp->d_name)) {
281
/* Realloc memory for namelist array if necessary */
282
if (files_count % REALLOC_STEP == 0) {
283
p = (char **) realloc(namelist, (files_count + REALLOC_STEP) * sizeof(char *));
286
memset(namelist + files_count, '\0', REALLOC_STEP * sizeof(char *));
288
free_namelist(namelist, files_count);
289
message(MESS_ERROR, "cannot realloc: %s\n", strerror(errno));
293
/* Alloc memory for file name */
294
if ( (namelist[files_count] = (char *) malloc( strlen(dp->d_name) + 1)) ) {
295
strcpy(namelist[files_count], dp->d_name);
298
free_namelist(namelist, files_count);
299
message(MESS_ERROR, "cannot realloc: %s\n", strerror(errno));
306
if (files_count > 0) {
307
qsort(namelist, files_count, sizeof(char *), compar);
165
312
if (chdir(path)) {
166
313
message(MESS_ERROR, "error in chdir(\"%s\"): %s\n", path,
167
314
strerror(errno));
316
free_namelist(namelist, files_count);
177
message(MESS_ERROR, "readdir() from %s failed: %s\n", path,
183
} else if (ent && ent->d_name[0] == '.' && (!ent->d_name[1] ||
184
(ent->d_name[1] == '.' && !ent->d_name[2]))) {
187
for (i = 0; i < tabooCount; i++) {
188
if (!strcmp(ent->d_name + strlen(ent->d_name) -
189
strlen(tabooExts[i]), tabooExts[i])) {
190
message(MESS_DEBUG, "Ignoring %s, because of %s "
191
"ending\n", ent->d_name, tabooExts[i]);
196
if (i == tabooCount) {
197
if (readConfigFile(ent->d_name, defConfig, logsPtr,
320
for (i=0; i<files_count; ++i) {
321
assert(namelist[i] != NULL);
323
if (readConfigFile(namelist[i], defConfig, logsPtr,
327
free_namelist(namelist, files_count);
334
free_namelist(namelist, files_count);
212
336
return readConfigFile(path, defConfig, logsPtr, numLogsPtr);
371
495
newlog->flags &= ~LOG_FLAG_COPYTRUNCATE;
373
497
*endtag = oldchar, start = endtag;
498
} else if (!strcmp(start, "copy")) {
499
newlog->flags |= LOG_FLAG_COPY;
501
*endtag = oldchar, start = endtag;
502
} else if (!strcmp(start, "nocopy")) {
503
newlog->flags &= ~LOG_FLAG_COPY;
505
*endtag = oldchar, start = endtag;
374
506
} else if (!strcmp(start, "ifempty")) {
375
507
newlog->flags |= LOG_FLAG_IFEMPTY;
453
585
} else if (start[length] == 'M') {
454
586
start[length] = '\0';
455
587
multiplier = 1024 * 1024;
588
} else if (start[length] == 'G') {
589
start[length] = '\0';
590
multiplier = 1024 * 1024 * 1024;
456
591
} else if (!isdigit(start[length])) {
457
592
message(MESS_ERROR, "%s:%d unknown unit '%c'\n",
458
593
configFile, lineNum, start[length]);
521
656
*endtag = oldchar, start = endtag;
658
} else if (!strcmp(start, "start")) {
659
*endtag = oldchar, start = endtag;
661
if (!isolateValue(configFile, lineNum, "start count", &start,
663
oldchar = *endtag, *endtag = '\0';
665
newlog->logStart = strtoul(start, &chptr, 0);
666
if (*chptr || newlog->logStart < 0) {
667
message(MESS_ERROR, "%s:%d bad start count '%s'\n",
668
configFile, lineNum, start);
671
*endtag = oldchar, start = endtag;
523
673
} else if (!strcmp(start, "errors")) {
524
674
message(MESS_DEBUG, "%s: %d: the errors directive is deprecated and no longer used.\n",
525
675
configFile, lineNum);
526
676
} else if (!strcmp(start, "mail")) {
527
677
*endtag = oldchar, start = endtag;
528
678
if (!(newlog->logAddress = readAddress(configFile, lineNum,
532
682
} else if (!strcmp(start, "nomail")) {
549
699
scriptDest = &newlog->pre;
551
701
while (*start != '\n') start++;
702
} else if (!strcmp(start, "firstaction")) {
703
*endtag = oldchar, start = endtag;
706
scriptDest = &newlog->first;
708
while (*start != '\n') start++;
552
709
} else if (!strcmp(start, "postrotate")) {
553
710
*endtag = oldchar, start = endtag;
556
713
scriptDest = &newlog->post;
558
715
while (*start != '\n') start++;
716
} else if (!strcmp(start, "lastaction")) {
717
*endtag = oldchar, start = endtag;
720
scriptDest = &newlog->last;
722
while (*start != '\n') start++;
559
723
} else if (!strcmp(start, "tabooext")) {
560
724
if (newlog != defConfig) {
561
725
message(MESS_ERROR, "%s:%d tabooext may not appear inside "
566
730
*endtag = oldchar, start = endtag;
567
if (!isolateValue(configFile, lineNum, "size", &start,
731
if (!isolateValue(configFile, lineNum, "tabooext", &start,
569
733
oldchar = *endtag, *endtag = '\0';
607
771
*endtag = oldchar, start = endtag;
608
if (!isolateValue(configFile, lineNum, "size", &start,
772
if (!isolateValue(configFile, lineNum, "include", &start,
610
774
oldchar = *endtag, *endtag = '\0';
618
782
*endtag = oldchar, start = endtag;
784
} else if (!strcmp(start, "pattern")) {
785
char * patternString;
787
*endtag = oldchar, start = endtag;
788
if (!(patternString = readPath(configFile, lineNum,
789
"pattern", &start))) {
793
newlog->rotatePattern = parsePattern(patternString,
794
configFile, lineNum);
795
if (!newlog->rotatePattern) return 1;
797
message(MESS_DEBUG, "pattern is now %s\n", patternString);
620
798
} else if (!strcmp(start, "olddir")) {
621
799
*endtag = oldchar, start = endtag;
622
800
if (!(newlog->oldDir = readPath(configFile, lineNum,
682
862
message(MESS_DEBUG, "uncompress_prog is now %s\n", newlog->uncompress_prog);
684
864
} else if (!strcmp(start, "compressoptions")) {
685
867
*endtag = oldchar, start = endtag;
686
if (!(newlog->compress_options = readPath(configFile, lineNum, "compressoptions", &start))) {
690
message(MESS_DEBUG, "compress_options is now %s\n", newlog->compress_options);
868
if (!(options = readPath(configFile, lineNum, "compressoptions", &start))) {
872
if (poptParseArgvString(options,
873
&newlog->compress_options_count,
874
&newlog->compress_options_list)) {
875
message(MESS_ERROR, "%s:%d invalid compression options\n",
876
configFile, lineNum);
880
message(MESS_DEBUG, "compress_options is now %s\n", options);
692
881
} else if (!strcmp(start, "compressext")) {
693
882
*endtag = oldchar, start = endtag;
694
883
if (!(newlog->compress_ext = readPath(configFile, lineNum, "compress-ext", &start))) {
749
938
for (argNum = 0; argNum < argc; argNum++) {
750
939
rc = glob(argv[argNum], GLOB_NOCHECK, globerr, &globResult);
751
940
if (rc == GLOB_ABORTED) {
941
if(newlog->flags & LOG_FLAG_MISSINGOK)
752
944
message(MESS_ERROR, "%s:%d glob failed for %s\n",
753
945
configFile, lineNum, argv[argNum]);
798
990
if (newlog->oldDir) {
799
if (stat(newlog->oldDir, &sb)) {
800
message(MESS_ERROR, "%s:%d error verifying olddir "
801
"path %s: %s\n", configFile, lineNum,
802
newlog->oldDir, strerror(errno));
806
991
for (i = 0; i < newlog->numFiles; i++) {
807
993
dirName = ourDirName(newlog->files[i]);
808
994
if (stat(dirName, &sb2)) {
809
995
message(MESS_ERROR, "%s:%d error verifying log file "
1001
ld = alloca(strlen(dirName) + strlen(newlog->oldDir) + 2);
1002
sprintf(ld, "%s/%s", dirName, newlog->oldDir);
1005
if(newlog->oldDir[0] != '/') dirName = ld;
1006
else dirName = newlog->oldDir;
1007
if(stat(dirName, &sb)) {
1008
message(MESS_ERROR, "%s:%d error verifying olddir "
1009
"path %s: %s\n", configFile, lineNum,
1010
dirName, strerror(errno));
818
1014
if (sb.st_dev != sb2.st_dev) {
819
1015
message(MESS_ERROR, "%s:%d olddir %s and log file %s "
820
1016
"are on different devices\n", configFile,