1 /* $NetBSD: logwriter.c,v 1.2 2020/03/18 19:05:21 christos Exp $ */
2
3 /*++
4 /* NAME
5 /* logwriter 3
6 /* SUMMARY
7 /* logfile writer
8 /* SYNOPSIS
9 /* #include <logwriter.h>
10 /*
11 /* VSTREAM *logwriter_open_or_die(
12 /* const char *path)
13 /*
14 /* int logwriter_write(
15 /* VSTREAM *file,
16 /* const char *buffer.
17 /* ssize_t buflen)
18 /*
19 /* int logwriter_close(
20 /* VSTREAM *file)
21 /*
22 /* int logwriter_one_shot(
23 /* const char *path,
24 /* const char *buffer,
25 /* ssize_t buflen)
26 /* DESCRIPTION
27 /* This module manages a logfile writer.
28 /*
29 /* logwriter_open_or_die() safely opens the specified file in
30 /* write+append mode. File open/create errors are fatal.
31 /*
32 /* logwriter_write() writes the buffer plus newline to the
33 /* open logfile. The result is zero if successful, VSTREAM_EOF
34 /* if the operation failed.
35 /*
36 /* logwriter_close() closes the logfile and destroys the VSTREAM
37 /* instance. The result is zero if there were no errors writing
38 /* the file, VSTREAM_EOF otherwise.
39 /*
40 /* logwriter_one_shot() combines all the above operations. The
41 /* result is zero if successful, VSTREAM_EOF if any operation
42 /* failed.
43 /* LICENSE
44 /* .ad
45 /* .fi
46 /* The Secure Mailer license must be distributed with this software.
47 /* AUTHOR(S)
48 /* Wietse Venema
49 /* Google, Inc.
50 /* 111 8th Avenue
51 /* New York, NY 10011, USA
52 /*--*/
53
54 /*
55 * System library.
56 */
57 #include <sys_defs.h>
58 #include <unistd.h>
59 #include <string.h>
60 #include <errno.h>
61
62 /*
63 * Utility library.
64 */
65 #include <iostuff.h>
66 #include <logwriter.h>
67 #include <msg.h>
68 #include <mymalloc.h>
69 #include <safe_open.h>
70 #include <vstream.h>
71
72 /*
73 * Application-specific.
74 */
75
76 /* logwriter_open_or_die - open logfile */
77
logwriter_open_or_die(const char * path)78 VSTREAM *logwriter_open_or_die(const char *path)
79 {
80 VSTREAM *fp;
81 VSTRING *why = vstring_alloc(100);
82
83 #define NO_STATP ((struct stat *) 0)
84 #define NO_CHOWN (-1)
85 #define NO_CHGRP (-1)
86
87 fp = safe_open(path, O_CREAT | O_WRONLY | O_APPEND, 0644,
88 NO_STATP, NO_CHOWN, NO_CHGRP, why);
89 if (fp == 0)
90 msg_fatal("open logfile '%s': %s", path, vstring_str(why));
91 close_on_exec(vstream_fileno(fp), CLOSE_ON_EXEC);
92 vstring_free(why);
93 return (fp);
94 }
95
96 /* logwriter_write - append to logfile */
97
logwriter_write(VSTREAM * fp,const char * buf,ssize_t len)98 int logwriter_write(VSTREAM *fp, const char *buf, ssize_t len)
99 {
100 if (len < 0)
101 msg_panic("logwriter_write: negative length %ld", (long) len);
102 if (vstream_fwrite(fp, buf, len) != len)
103 return (VSTREAM_EOF);
104 VSTREAM_PUTC('\n', fp);
105 return (vstream_fflush(fp));
106 }
107
108 /* logwriter_close - close logfile */
109
logwriter_close(VSTREAM * fp)110 int logwriter_close(VSTREAM *fp)
111 {
112 return (vstream_fclose(fp));
113 }
114
115 /* logwriter_one_shot - one-shot logwriter */
116
logwriter_one_shot(const char * path,const char * buf,ssize_t len)117 int logwriter_one_shot(const char *path, const char *buf, ssize_t len)
118 {
119 VSTREAM *fp;
120 int err;
121
122 fp = logwriter_open_or_die(path);
123 err = logwriter_write(fp, buf, len);
124 err |= logwriter_close(fp);
125 return (err ? VSTREAM_EOF : 0);
126 }
127