summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--syslogd/logfile.c39
-rw-r--r--syslogd/logfile.h4
-rw-r--r--syslogd/main.c11
-rw-r--r--syslogd/proto.c11
4 files changed, 53 insertions, 12 deletions
diff --git a/syslogd/logfile.c b/syslogd/logfile.c
index 5687750..56f8d53 100644
--- a/syslogd/logfile.c
+++ b/syslogd/logfile.c
@@ -15,39 +15,66 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
+#include <sys/types.h>
+#include <sys/stat.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdarg.h>
#include <stdio.h>
#include <fcntl.h>
+#include <errno.h>
#include "logfile.h"
-logfile_t *logfile_create(const char *name, int facility)
+logfile_t *logfile_create(const char *ident, const char *name, int facility)
{
+ int dfd = AT_FDCWD;
logfile_t *file;
+ size_t size;
- file = calloc(1, sizeof(*file) + strlen(name) + 1);
+ size = sizeof(*file) + 1;
+ if (ident != NULL)
+ size += strlen(ident);
+
+ file = calloc(1, size);
if (file == NULL) {
perror("calloc");
return NULL;
}
- strcpy(file->name, name);
+ if (ident != NULL) {
+ strcpy(file->ident, ident);
+ if (mkdir(file->ident, 0750) != 0 && errno != EEXIST) {
+ perror(file->ident);
+ goto fail;
+ }
+
+ dfd = open(file->ident, O_DIRECTORY | O_RDONLY);
+ if (dfd < 0) {
+ perror(file->ident);
+ goto fail;
+ }
+ }
+
file->facility = facility;
- file->fd = open(file->name, O_WRONLY | O_CREAT, 0640);
- if (file->fd < 0)
+ file->fd = openat(dfd, name, O_WRONLY | O_CREAT, 0640);
+ if (file->fd < 0) {
+ perror(name);
goto fail;
+ }
if (lseek(file->fd, 0, SEEK_END))
goto fail;
+ if (dfd != AT_FDCWD)
+ close(dfd);
return file;
fail:
- perror(file->name);
+ if (dfd != AT_FDCWD)
+ close(dfd);
free(file);
return NULL;
}
diff --git a/syslogd/logfile.h b/syslogd/logfile.h
index cf4a7d6..3a596ba 100644
--- a/syslogd/logfile.h
+++ b/syslogd/logfile.h
@@ -23,10 +23,10 @@ typedef struct logfile_t {
int facility;
int fd;
- char name[];
+ char ident[];
} logfile_t;
-logfile_t *logfile_create(const char *name, int facility);
+logfile_t *logfile_create(const char *ident, const char *name, int facility);
void logfile_destroy(logfile_t *file);
diff --git a/syslogd/main.c b/syslogd/main.c
index 79d6325..263c87d 100644
--- a/syslogd/main.c
+++ b/syslogd/main.c
@@ -134,12 +134,16 @@ static int print_to_log(const syslog_msg_t *msg)
return -1;
for (log = logfiles; log != NULL; log = log->next) {
- if (log->facility == msg->facility)
+ if (log->facility != msg->facility)
+ continue;
+ if (msg->ident == NULL && log->ident[0] == '\0')
+ break;
+ if (msg->ident != NULL && strcmp(msg->ident, log->ident) == 0)
break;
}
if (log == NULL) {
- log = logfile_create(fac_name, msg->facility);
+ log = logfile_create(msg->ident, fac_name, msg->facility);
if (log == NULL)
return -1;
log->next = logfiles;
@@ -149,8 +153,7 @@ static int print_to_log(const syslog_msg_t *msg)
gmtime_r(&msg->timestamp, &tm);
strftime(timebuf, sizeof(timebuf), "%FT%T", &tm);
- logfile_write(log, "[%s][%s][%s][%u] %s", timebuf, lvl_str,
- msg->ident ? msg->ident : "", msg->pid,
+ logfile_write(log, "[%s][%s][%u] %s", timebuf, lvl_str, msg->pid,
msg->message);
return 0;
}
diff --git a/syslogd/proto.c b/syslogd/proto.c
index 3487dbd..8a285dd 100644
--- a/syslogd/proto.c
+++ b/syslogd/proto.c
@@ -169,9 +169,20 @@ int syslog_msg_parse(syslog_msg_t *msg, char *str)
ident = NULL;
}
+ if (ident != NULL && ident[0] == '\0')
+ ident = NULL;
+
msg->timestamp = mktime(&tstamp);
msg->pid = pid;
msg->ident = ident;
msg->message = str;
+
+ if (ident != NULL) {
+ for (ptr = ident; *ptr != '\0'; ++ptr) {
+ if (!isalnum(*ptr))
+ *ptr = '_';
+ }
+ }
+
return 0;
}