Deleted Added
full compact
newsyslog.c (208649) newsyslog.c (210372)
1/*-
2 * ------+---------+---------+-------- + --------+---------+---------+---------*
3 * This file includes significant modifications done by:
4 * Copyright (c) 2003, 2004 - Garance Alistair Drosehn <gad@FreeBSD.org>.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions

--- 40 unchanged lines hidden (view full) ---

49 */
50
51/*
52 * newsyslog - roll over selected logs at the appropriate time, keeping the a
53 * specified number of backup files around.
54 */
55
56#include <sys/cdefs.h>
1/*-
2 * ------+---------+---------+-------- + --------+---------+---------+---------*
3 * This file includes significant modifications done by:
4 * Copyright (c) 2003, 2004 - Garance Alistair Drosehn <gad@FreeBSD.org>.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions

--- 40 unchanged lines hidden (view full) ---

49 */
50
51/*
52 * newsyslog - roll over selected logs at the appropriate time, keeping the a
53 * specified number of backup files around.
54 */
55
56#include <sys/cdefs.h>
57__FBSDID("$FreeBSD: head/usr.sbin/newsyslog/newsyslog.c 208649 2010-05-29 22:55:59Z gordon $");
57__FBSDID("$FreeBSD: head/usr.sbin/newsyslog/newsyslog.c 210372 2010-07-22 11:23:18Z simon $");
58
59#define OSF
60#ifndef COMPRESS_POSTFIX
61#define COMPRESS_POSTFIX ".gz"
62#endif
63#ifndef BZCOMPRESS_POSTFIX
64#define BZCOMPRESS_POSTFIX ".bz2"
65#endif
66
67#include <sys/param.h>
68#include <sys/queue.h>
69#include <sys/stat.h>
70#include <sys/wait.h>
71
58
59#define OSF
60#ifndef COMPRESS_POSTFIX
61#define COMPRESS_POSTFIX ".gz"
62#endif
63#ifndef BZCOMPRESS_POSTFIX
64#define BZCOMPRESS_POSTFIX ".bz2"
65#endif
66
67#include <sys/param.h>
68#include <sys/queue.h>
69#include <sys/stat.h>
70#include <sys/wait.h>
71
72#include <assert.h>
72#include <ctype.h>
73#include <err.h>
74#include <errno.h>
73#include <ctype.h>
74#include <err.h>
75#include <errno.h>
76#include <dirent.h>
75#include <fcntl.h>
76#include <fnmatch.h>
77#include <glob.h>
78#include <grp.h>
79#include <paths.h>
80#include <pwd.h>
81#include <signal.h>
82#include <stdio.h>
77#include <fcntl.h>
78#include <fnmatch.h>
79#include <glob.h>
80#include <grp.h>
81#include <paths.h>
82#include <pwd.h>
83#include <signal.h>
84#include <stdio.h>
85#include <libgen.h>
83#include <stdlib.h>
84#include <string.h>
85#include <time.h>
86#include <unistd.h>
87
88#include "pathnames.h"
89#include "extern.h"
90

--- 16 unchanged lines hidden (view full) ---

107#define MIN_PID 5 /* Don't touch pids lower than this */
108#define MAX_PID 99999 /* was lower, see /usr/include/sys/proc.h */
109
110#define kbytes(size) (((size) + 1023) >> 10)
111
112#define DEFAULT_MARKER "<default>"
113#define DEBUG_MARKER "<debug>"
114#define INCLUDE_MARKER "<include>"
86#include <stdlib.h>
87#include <string.h>
88#include <time.h>
89#include <unistd.h>
90
91#include "pathnames.h"
92#include "extern.h"
93

--- 16 unchanged lines hidden (view full) ---

110#define MIN_PID 5 /* Don't touch pids lower than this */
111#define MAX_PID 99999 /* was lower, see /usr/include/sys/proc.h */
112
113#define kbytes(size) (((size) + 1023) >> 10)
114
115#define DEFAULT_MARKER "<default>"
116#define DEBUG_MARKER "<debug>"
117#define INCLUDE_MARKER "<include>"
118#define DEFAULT_TIMEFNAME_FMT "%Y%m%dT%H%M%S"
115
119
120#define MAX_OLDLOGS 65536 /* Default maximum number of old logfiles */
121
116struct conf_entry {
117 STAILQ_ENTRY(conf_entry) cf_nextp;
118 char *log; /* Name of the log */
119 char *pid_file; /* PID file */
120 char *r_reason; /* The reason this file is being rotated */
121 int firstcreate; /* Creating log for the first time (-C). */
122 int rotate; /* Non-zero if this file should be rotated */
123 int fsize; /* size found for the log file */

--- 26 unchanged lines hidden (view full) ---

150 char zw_fname[1]; /* the file to compress */
151};
152
153struct include_entry {
154 STAILQ_ENTRY(include_entry) inc_nextp;
155 const char *file; /* Name of file to process */
156};
157
122struct conf_entry {
123 STAILQ_ENTRY(conf_entry) cf_nextp;
124 char *log; /* Name of the log */
125 char *pid_file; /* PID file */
126 char *r_reason; /* The reason this file is being rotated */
127 int firstcreate; /* Creating log for the first time (-C). */
128 int rotate; /* Non-zero if this file should be rotated */
129 int fsize; /* size found for the log file */

--- 26 unchanged lines hidden (view full) ---

156 char zw_fname[1]; /* the file to compress */
157};
158
159struct include_entry {
160 STAILQ_ENTRY(include_entry) inc_nextp;
161 const char *file; /* Name of file to process */
162};
163
164struct oldlog_entry {
165 char *fname; /* Filename of the log file */
166 time_t t; /* Parses timestamp of the logfile */
167};
168
158typedef enum {
159 FREE_ENT, KEEP_ENT
160} fk_entry;
161
162STAILQ_HEAD(cflist, conf_entry);
163SLIST_HEAD(swlisthead, sigwork_entry) swhead = SLIST_HEAD_INITIALIZER(swhead);
164SLIST_HEAD(zwlisthead, zipwork_entry) zwhead = SLIST_HEAD_INITIALIZER(zwhead);
165STAILQ_HEAD(ilist, include_entry);

--- 11 unchanged lines hidden (view full) ---

177int nosignal; /* Do not send any signals */
178int enforcepid = 0; /* If PID file does not exist or empty, do nothing */
179int force = 0; /* Force the trim no matter what */
180int rotatereq = 0; /* -R = Always rotate the file(s) as given */
181 /* on the command (this also requires */
182 /* that a list of files *are* given on */
183 /* the run command). */
184char *requestor; /* The name given on a -R request */
169typedef enum {
170 FREE_ENT, KEEP_ENT
171} fk_entry;
172
173STAILQ_HEAD(cflist, conf_entry);
174SLIST_HEAD(swlisthead, sigwork_entry) swhead = SLIST_HEAD_INITIALIZER(swhead);
175SLIST_HEAD(zwlisthead, zipwork_entry) zwhead = SLIST_HEAD_INITIALIZER(zwhead);
176STAILQ_HEAD(ilist, include_entry);

--- 11 unchanged lines hidden (view full) ---

188int nosignal; /* Do not send any signals */
189int enforcepid = 0; /* If PID file does not exist or empty, do nothing */
190int force = 0; /* Force the trim no matter what */
191int rotatereq = 0; /* -R = Always rotate the file(s) as given */
192 /* on the command (this also requires */
193 /* that a list of files *are* given on */
194 /* the run command). */
195char *requestor; /* The name given on a -R request */
196char *timefnamefmt = NULL; /* Use time based filenames instead of .0 etc */
185char *archdirname; /* Directory path to old logfiles archive */
186char *destdir = NULL; /* Directory to treat at root for logs */
187const char *conf; /* Configuration file to use */
188
189struct ptime_data *dbg_timenow; /* A "timenow" value set via -D option */
190struct ptime_data *timenow; /* The time to use for checking at-fields */
191
192#define DAYTIME_LEN 16

--- 387 unchanged lines hidden (view full) ---

580 /* Let's get our hostname */
581 (void)gethostname(hostname, sizeof(hostname));
582
583 /* Truncate domain */
584 if ((p = strchr(hostname, '.')) != NULL)
585 *p = '\0';
586
587 /* Parse command line options. */
197char *archdirname; /* Directory path to old logfiles archive */
198char *destdir = NULL; /* Directory to treat at root for logs */
199const char *conf; /* Configuration file to use */
200
201struct ptime_data *dbg_timenow; /* A "timenow" value set via -D option */
202struct ptime_data *timenow; /* The time to use for checking at-fields */
203
204#define DAYTIME_LEN 16

--- 387 unchanged lines hidden (view full) ---

592 /* Let's get our hostname */
593 (void)gethostname(hostname, sizeof(hostname));
594
595 /* Truncate domain */
596 if ((p = strchr(hostname, '.')) != NULL)
597 *p = '\0';
598
599 /* Parse command line options. */
588 while ((ch = getopt(argc, argv, "a:d:f:nrsvCD:FNPR:")) != -1)
600 while ((ch = getopt(argc, argv, "a:d:f:nrst:vCD:FNPR:")) != -1)
589 switch (ch) {
590 case 'a':
591 archtodir++;
592 archdirname = optarg;
593 break;
594 case 'd':
595 destdir = optarg;
596 break;

--- 4 unchanged lines hidden (view full) ---

601 noaction++;
602 break;
603 case 'r':
604 needroot = 0;
605 break;
606 case 's':
607 nosignal = 1;
608 break;
601 switch (ch) {
602 case 'a':
603 archtodir++;
604 archdirname = optarg;
605 break;
606 case 'd':
607 destdir = optarg;
608 break;

--- 4 unchanged lines hidden (view full) ---

613 noaction++;
614 break;
615 case 'r':
616 needroot = 0;
617 break;
618 case 's':
619 nosignal = 1;
620 break;
621 case 't':
622 if (optarg[0] == '\0' ||
623 strcmp(optarg, "DEFAULT") == 0)
624 timefnamefmt = strdup(DEFAULT_TIMEFNAME_FMT);
625 else
626 timefnamefmt = strdup(optarg);
627 break;
609 case 'v':
610 verbose++;
611 break;
612 case 'C':
613 /* Useful for things like rc.diskless... */
614 createlogs++;
615 break;
616 case 'D':

--- 106 unchanged lines hidden (view full) ---

723}
724
725static void
726usage(void)
727{
728
729 fprintf(stderr,
730 "usage: newsyslog [-CFNnrsv] [-a directory] [-d directory] [-f config-file]\n"
628 case 'v':
629 verbose++;
630 break;
631 case 'C':
632 /* Useful for things like rc.diskless... */
633 createlogs++;
634 break;
635 case 'D':

--- 106 unchanged lines hidden (view full) ---

742}
743
744static void
745usage(void)
746{
747
748 fprintf(stderr,
749 "usage: newsyslog [-CFNnrsv] [-a directory] [-d directory] [-f config-file]\n"
731 " [ [-R requestor] filename ... ]\n");
750 " [-t timefmt ] [ [-R requestor] filename ... ]\n");
732 exit(1);
733}
734
735/*
736 * Parse a configuration file and return a linked list of all the logs
737 * which should be processed.
738 */
739static struct cflist *

--- 620 unchanged lines hidden (view full) ---

1360{
1361
1362 if (!p || !*p)
1363 errx(1, "missing field in config file:\n%s", errline);
1364 return (p);
1365}
1366
1367/*
751 exit(1);
752}
753
754/*
755 * Parse a configuration file and return a linked list of all the logs
756 * which should be processed.
757 */
758static struct cflist *

--- 620 unchanged lines hidden (view full) ---

1379{
1380
1381 if (!p || !*p)
1382 errx(1, "missing field in config file:\n%s", errline);
1383 return (p);
1384}
1385
1386/*
1387 * In our sort we return it in the reverse of what qsort normally
1388 * would do, as we want the newest files first. If we have two
1389 * entries with the same time we don't really care about order.
1390 *
1391 * Support function for qsort() in delete_oldest_timelog().
1392 */
1393static int
1394oldlog_entry_compare(const void *a, const void *b)
1395{
1396 const struct oldlog_entry *ola = a, *olb = b;
1397
1398 if (ola->t > olb->t)
1399 return (-1);
1400 else if (ola->t < olb->t)
1401 return (1);
1402 else
1403 return (0);
1404}
1405
1406/*
1407 * Delete the oldest logfiles, when using time based filenames.
1408 */
1409static void
1410delete_oldest_timelog(const struct conf_entry *ent, const char *archive_dir)
1411{
1412 char *logfname, *s, *dir, errbuf[80];
1413 int logcnt, max_logcnt, dirfd, i;
1414 struct oldlog_entry *oldlogs;
1415 size_t logfname_len;
1416 struct dirent *dp;
1417 const char *cdir;
1418 struct tm tm;
1419 DIR *dirp;
1420
1421 oldlogs = malloc(MAX_OLDLOGS * sizeof(struct oldlog_entry));
1422 max_logcnt = MAX_OLDLOGS;
1423 logcnt = 0;
1424
1425 if (archive_dir != NULL && archive_dir[0] != '\0')
1426 cdir = archive_dir;
1427 else
1428 if ((cdir = dirname(ent->log)) == NULL)
1429 err(1, "dirname()");
1430 if ((dir = strdup(cdir)) == NULL)
1431 err(1, "strdup()");
1432
1433 if ((s = basename(ent->log)) == NULL)
1434 err(1, "basename()");
1435 if ((logfname = strdup(s)) == NULL)
1436 err(1, "strdup()");
1437 logfname_len = strlen(logfname);
1438 if (strcmp(logfname, "/") == 0)
1439 errx(1, "Invalid log filename - became '/'");
1440
1441 if (verbose > 2)
1442 printf("Searching for old logs in %s\n", dir);
1443
1444 /* First we create a 'list' of all archived logfiles */
1445 if ((dirp = opendir(dir)) == NULL)
1446 err(1, "Cannot open log directory '%s'", dir);
1447 dirfd = dirfd(dirp);
1448 while ((dp = readdir(dirp)) != NULL) {
1449 if (dp->d_type != DT_REG)
1450 continue;
1451
1452 /* Ignore everything but files with our logfile prefix */
1453 if (strncmp(dp->d_name, logfname, logfname_len) != 0)
1454 continue;
1455 /* Ignore the actual non-rotated logfile */
1456 if (dp->d_namlen == logfname_len)
1457 continue;
1458 /*
1459 * Make sure we created have found a logfile, so the
1460 * postfix is valid, IE format is: '.<time>(.[bg]z)?'.
1461 */
1462 if (dp->d_name[logfname_len] != '.') {
1463 if (verbose)
1464 printf("Ignoring %s which has unexpected "
1465 "extension '%s'\n", dp->d_name,
1466 &dp->d_name[logfname_len]);
1467 continue;
1468 }
1469 if ((s = strptime(&dp->d_name[logfname_len + 1],
1470 timefnamefmt, &tm)) == NULL) {
1471 /*
1472 * We could special case "old" sequentially
1473 * named logfiles here, but we do not as that
1474 * would require special handling to decide
1475 * which one was the oldest compared to "new"
1476 * time based logfiles.
1477 */
1478 if (verbose)
1479 printf("Ignoring %s which does not "
1480 "match time format\n", dp->d_name);
1481 continue;
1482 }
1483 if (*s != '\0' && !(strcmp(s, BZCOMPRESS_POSTFIX) == 0 ||
1484 strcmp(s, COMPRESS_POSTFIX) == 0)) {
1485 if (verbose)
1486 printf("Ignoring %s which has unexpected "
1487 "extension '%s'\n", dp->d_name, s);
1488 continue;
1489 }
1490
1491 /*
1492 * We should now have old an old rotated logfile, so
1493 * add it to the 'list'.
1494 */
1495 if ((oldlogs[logcnt].t = timegm(&tm)) == -1)
1496 err(1, "Could not convert time string to time value");
1497 if ((oldlogs[logcnt].fname = strdup(dp->d_name)) == NULL)
1498 err(1, "strdup()");
1499 logcnt++;
1500
1501 /*
1502 * It is very unlikely we ever run out of space in the
1503 * logfile array from the default size, but lets
1504 * handle it anyway...
1505 */
1506 if (logcnt >= max_logcnt) {
1507 max_logcnt *= 4;
1508 /* Detect integer overflow */
1509 if (max_logcnt < logcnt)
1510 errx(1, "Too many old logfiles found");
1511 oldlogs = realloc(oldlogs,
1512 max_logcnt * sizeof(struct oldlog_entry));
1513 if (oldlogs == NULL)
1514 err(1, "realloc()");
1515 }
1516 }
1517
1518 /* Second, if needed we delete oldest archived logfiles */
1519 if (logcnt > 0 && logcnt >= ent->numlogs && ent->numlogs > 1) {
1520 oldlogs = realloc(oldlogs, logcnt *
1521 sizeof(struct oldlog_entry));
1522 if (oldlogs == NULL)
1523 err(1, "realloc()");
1524
1525 /*
1526 * We now sort the logs in the order of newest to
1527 * oldest. That way we can simply skip over the
1528 * number of records we want to keep.
1529 */
1530 qsort(oldlogs, logcnt, sizeof(struct oldlog_entry),
1531 oldlog_entry_compare);
1532 for (i = ent->numlogs - 1; i < logcnt; i++) {
1533 if (noaction)
1534 printf("\trm -f %s/%s\n", dir,
1535 oldlogs[i].fname);
1536 else if (unlinkat(dirfd, oldlogs[i].fname, 0) != 0) {
1537 snprintf(errbuf, sizeof(errbuf),
1538 "Could not delet old logfile '%s'",
1539 oldlogs[i].fname);
1540 perror(errbuf);
1541 }
1542 }
1543 } else if (verbose > 1)
1544 printf("No old logs to delete for logfile %s\n", ent->log);
1545
1546 /* Third, cleanup */
1547 closedir(dirp);
1548 for (i = 0; i < logcnt; i++) {
1549 assert(oldlogs[i].fname != NULL);
1550 free(oldlogs[i].fname);
1551 }
1552 free(oldlogs);
1553 free(logfname);
1554 free(dir);
1555}
1556
1557/*
1368 * Only add to the queue if the file hasn't already been added. This is
1369 * done to prevent circular include loops.
1370 */
1371static void
1372add_to_queue(const char *fname, struct ilist *inclist)
1373{
1374 struct include_entry *inc;
1375

--- 17 unchanged lines hidden (view full) ---

1393
1394static fk_entry
1395do_rotate(const struct conf_entry *ent)
1396{
1397 char dirpart[MAXPATHLEN], namepart[MAXPATHLEN];
1398 char file1[MAXPATHLEN], file2[MAXPATHLEN];
1399 char zfile1[MAXPATHLEN], zfile2[MAXPATHLEN];
1400 char jfile1[MAXPATHLEN];
1558 * Only add to the queue if the file hasn't already been added. This is
1559 * done to prevent circular include loops.
1560 */
1561static void
1562add_to_queue(const char *fname, struct ilist *inclist)
1563{
1564 struct include_entry *inc;
1565

--- 17 unchanged lines hidden (view full) ---

1583
1584static fk_entry
1585do_rotate(const struct conf_entry *ent)
1586{
1587 char dirpart[MAXPATHLEN], namepart[MAXPATHLEN];
1588 char file1[MAXPATHLEN], file2[MAXPATHLEN];
1589 char zfile1[MAXPATHLEN], zfile2[MAXPATHLEN];
1590 char jfile1[MAXPATHLEN];
1591 char datetimestr[30];
1401 int flags, numlogs_c;
1402 fk_entry free_or_keep;
1403 struct sigwork_entry *swork;
1404 struct stat st;
1592 int flags, numlogs_c;
1593 fk_entry free_or_keep;
1594 struct sigwork_entry *swork;
1595 struct stat st;
1596 struct tm tm;
1597 time_t now;
1405
1406 flags = ent->flags;
1407 free_or_keep = FREE_ENT;
1408
1409 if (archtodir) {
1410 char *p;
1411
1412 /* build complete name of archive directory into dirpart */

--- 17 unchanged lines hidden (view full) ---

1430 if ((p = rindex(ent->log, '/')) == NULL)
1431 strlcpy(namepart, ent->log, sizeof(namepart));
1432 else
1433 strlcpy(namepart, p + 1, sizeof(namepart));
1434
1435 /* name of oldest log */
1436 (void) snprintf(file1, sizeof(file1), "%s/%s.%d", dirpart,
1437 namepart, ent->numlogs);
1598
1599 flags = ent->flags;
1600 free_or_keep = FREE_ENT;
1601
1602 if (archtodir) {
1603 char *p;
1604
1605 /* build complete name of archive directory into dirpart */

--- 17 unchanged lines hidden (view full) ---

1623 if ((p = rindex(ent->log, '/')) == NULL)
1624 strlcpy(namepart, ent->log, sizeof(namepart));
1625 else
1626 strlcpy(namepart, p + 1, sizeof(namepart));
1627
1628 /* name of oldest log */
1629 (void) snprintf(file1, sizeof(file1), "%s/%s.%d", dirpart,
1630 namepart, ent->numlogs);
1438 (void) snprintf(zfile1, sizeof(zfile1), "%s%s", file1,
1439 COMPRESS_POSTFIX);
1440 snprintf(jfile1, sizeof(jfile1), "%s%s", file1,
1441 BZCOMPRESS_POSTFIX);
1442 } else {
1631 } else {
1632 /*
1633 * Tell delete_oldest_timelog() we are not using an
1634 * archive dir.
1635 */
1636 dirpart[0] = '\0';
1637
1443 /* name of oldest log */
1444 (void) snprintf(file1, sizeof(file1), "%s.%d", ent->log,
1445 ent->numlogs);
1638 /* name of oldest log */
1639 (void) snprintf(file1, sizeof(file1), "%s.%d", ent->log,
1640 ent->numlogs);
1641 }
1642
1643 /* Delete old logs */
1644 if (timefnamefmt != NULL)
1645 delete_oldest_timelog(ent, dirpart);
1646 else {
1647 /* name of oldest log */
1446 (void) snprintf(zfile1, sizeof(zfile1), "%s%s", file1,
1447 COMPRESS_POSTFIX);
1448 snprintf(jfile1, sizeof(jfile1), "%s%s", file1,
1449 BZCOMPRESS_POSTFIX);
1648 (void) snprintf(zfile1, sizeof(zfile1), "%s%s", file1,
1649 COMPRESS_POSTFIX);
1650 snprintf(jfile1, sizeof(jfile1), "%s%s", file1,
1651 BZCOMPRESS_POSTFIX);
1450 }
1451
1652
1452 if (noaction) {
1453 printf("\trm -f %s\n", file1);
1454 printf("\trm -f %s\n", zfile1);
1455 printf("\trm -f %s\n", jfile1);
1456 } else {
1457 (void) unlink(file1);
1458 (void) unlink(zfile1);
1459 (void) unlink(jfile1);
1653 if (noaction) {
1654 printf("\trm -f %s\n", file1);
1655 printf("\trm -f %s\n", zfile1);
1656 printf("\trm -f %s\n", jfile1);
1657 } else {
1658 (void) unlink(file1);
1659 (void) unlink(zfile1);
1660 (void) unlink(jfile1);
1661 }
1460 }
1461
1662 }
1663
1664 if (timefnamefmt != NULL) {
1665 /* If time functions fails we can't really do any sensible */
1666 if (time(&now) == (time_t)-1 ||
1667 localtime_r(&now, &tm) == NULL)
1668 bzero(&tm, sizeof(tm));
1669
1670 strftime(datetimestr, sizeof(datetimestr), timefnamefmt, &tm);
1671 if (archtodir)
1672 (void) snprintf(file1, sizeof(file1), "%s/%s.%s",
1673 dirpart, namepart, datetimestr);
1674 else
1675 (void) snprintf(file1, sizeof(file1), "%s.%s",
1676 ent->log, datetimestr);
1677
1678 /* Don't run the code to move down logs */
1679 numlogs_c = 0;
1680 } else
1681 numlogs_c = ent->numlogs; /* copy for countdown */
1682
1462 /* Move down log files */
1683 /* Move down log files */
1463 numlogs_c = ent->numlogs; /* copy for countdown */
1464 while (numlogs_c--) {
1465
1466 (void) strlcpy(file2, file1, sizeof(file2));
1467
1468 if (archtodir)
1469 (void) snprintf(file1, sizeof(file1), "%s/%s.%d",
1470 dirpart, namepart, numlogs_c);
1471 else

--- 766 unchanged lines hidden ---
1684 while (numlogs_c--) {
1685
1686 (void) strlcpy(file2, file1, sizeof(file2));
1687
1688 if (archtodir)
1689 (void) snprintf(file1, sizeof(file1), "%s/%s.%d",
1690 dirpart, namepart, numlogs_c);
1691 else

--- 766 unchanged lines hidden ---