1 /* $NetBSD: logwriter.c,v 1.3 2025/02/25 19:15:52 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 /* 27 /* int set_logwriter_create_perms( 28 /* const char *mode) 29 /* DESCRIPTION 30 /* This module manages a logfile writer. 31 /* 32 /* logwriter_open_or_die() safely opens the specified file in 33 /* write+append mode. File open/create errors are fatal. 34 /* 35 /* logwriter_write() writes the buffer plus newline to the 36 /* open logfile. The result is zero if successful, VSTREAM_EOF 37 /* if the operation failed. 38 /* 39 /* logwriter_close() closes the logfile and destroys the VSTREAM 40 /* instance. The result is zero if there were no errors writing 41 /* the file, VSTREAM_EOF otherwise. 42 /* 43 /* logwriter_one_shot() combines all the above operations. The 44 /* result is zero if successful, VSTREAM_EOF if any operation 45 /* failed. 46 /* 47 /* set_logwriter_create_perms() sets the file permissions that 48 /* will be used when creating a logfile. Valid inputs are 49 /* "644", "640", and "600". Leading zeros are allowed and 50 /* ignored. 51 /* DIAGNOSTICS 52 /* Fatal error: logfile create error; warning: logfile permission 53 /* change error. set_logwriter_create_perms() returns the file 54 /* create permission if the request is valid, -1 otherwise. 55 /* LICENSE 56 /* .ad 57 /* .fi 58 /* The Secure Mailer license must be distributed with this software. 59 /* AUTHOR(S) 60 /* Wietse Venema 61 /* Google, Inc. 62 /* 111 8th Avenue 63 /* New York, NY 10011, USA 64 /*--*/ 65 66 /* 67 * System library. 68 */ 69 #include <sys_defs.h> 70 #include <unistd.h> 71 #include <string.h> 72 #include <errno.h> 73 74 /* 75 * Utility library. 76 */ 77 #include <iostuff.h> 78 #include <logwriter.h> 79 #include <msg.h> 80 #include <mymalloc.h> 81 #include <safe_open.h> 82 #include <vstream.h> 83 #include <name_code.h> 84 85 /* 86 * Application-specific. 87 */ 88 static int logwriter_perms = 0600; 89 90 /* logwriter_open_or_die - open logfile */ 91 92 VSTREAM *logwriter_open_or_die(const char *path) 93 { 94 VSTREAM *fp; 95 VSTRING *why = vstring_alloc(100); 96 97 #define NO_STATP ((struct stat *) 0) 98 #define NO_CHOWN (-1) 99 #define NO_CHGRP (-1) 100 101 fp = safe_open(path, O_CREAT | O_WRONLY | O_APPEND, logwriter_perms, 102 NO_STATP, NO_CHOWN, NO_CHGRP, why); 103 if (fp == 0) 104 msg_fatal("open logfile '%s': %s", path, vstring_str(why)); 105 close_on_exec(vstream_fileno(fp), CLOSE_ON_EXEC); 106 vstring_free(why); 107 return (fp); 108 } 109 110 /* logwriter_write - append to logfile */ 111 112 int logwriter_write(VSTREAM *fp, const char *buf, ssize_t len) 113 { 114 if (len < 0) 115 msg_panic("logwriter_write: negative length %ld", (long) len); 116 if (vstream_fwrite(fp, buf, len) != len) 117 return (VSTREAM_EOF); 118 VSTREAM_PUTC('\n', fp); 119 return (vstream_fflush(fp)); 120 } 121 122 /* logwriter_close - close logfile */ 123 124 int logwriter_close(VSTREAM *fp) 125 { 126 return (vstream_fclose(fp)); 127 } 128 129 /* logwriter_one_shot - one-shot logwriter */ 130 131 int logwriter_one_shot(const char *path, const char *buf, ssize_t len) 132 { 133 VSTREAM *fp; 134 int err; 135 136 fp = logwriter_open_or_die(path); 137 err = logwriter_write(fp, buf, len); 138 err |= logwriter_close(fp); 139 return (err ? VSTREAM_EOF : 0); 140 } 141 142 /* set_logwriter_create_perms - logfile permission control */ 143 144 int set_logwriter_create_perms(const char *mode_str) 145 { 146 static const NAME_CODE sane_perms[] = { 147 "644", 0644, 148 "640", 0640, 149 "600", 0600, 150 0, -1, 151 }; 152 int perms; 153 154 if ((perms = name_code(sane_perms, NAME_CODE_FLAG_NONE, 155 mode_str + strspn(mode_str, "0"))) != -1) 156 logwriter_perms = perms; 157 return (perms); 158 } 159