Import Upstream version 1.8.5
[hcoop/debian/openafs.git] / src / audit / audit-sysvmq.c
1 /*
2 * Copyright 2009, Sine Nomine Associates and others.
3 * All Rights Reserved.
4 *
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
8 */
9
10 #include <afsconfig.h>
11 #include <afs/param.h>
12
13 #include <roken.h>
14
15 /* only build on platforms that have SysV IPC support; i.e., when we
16 * have sys/ipc.h */
17 #ifdef HAVE_SYS_IPC_H
18
19 #include <sys/ipc.h>
20 #include <sys/msg.h>
21
22 #include "audit-api.h"
23
24 /* solaris default is 2048 */
25 #define MAXMSG 2048
26
27 /* message queue size will be increased to this value
28 if not already bigger */
29 #define MSGMNB (2*1024*1024)
30
31 static struct my_msgbuf {
32 long mtype;
33 char mtext[MAXMSG];
34 } msgbuffer;
35
36 static int mqid;
37
38 static struct mqaudit_stats {
39 long all;
40 long truncated;
41 long lost;
42 } myauditstats;
43
44 static int truncated;
45
46 static void
47 send_msg(void)
48 {
49 /* +1 to send the trailing '\0' in the message too so the
50 receiver doesn't need to bother with it */
51 if (msgsnd(mqid, &msgbuffer, strlen(msgbuffer.mtext)+1, IPC_NOWAIT) == -1) {
52 myauditstats.lost++;
53 } else if (truncated) {
54 myauditstats.truncated++;
55 }
56 myauditstats.all++;
57 msgbuffer.mtext[0] = 0;
58 truncated = 0;
59 }
60
61 static void
62 append_msg(const char *format, ...)
63 {
64 va_list vaList;
65 int size, printed;
66
67 size = MAXMSG - strlen(msgbuffer.mtext);
68
69 va_start(vaList, format);
70 printed = vsnprintf(&msgbuffer.mtext[strlen(msgbuffer.mtext)], size, format, vaList);
71 va_end(vaList);
72
73 /* A return value of size or more means that the output was truncated.
74 If an output error is encountered, a negative value is returned. */
75 if (size <= printed || printed == -1) {
76 truncated = 1;
77 }
78 }
79
80 static int
81 open_file(const char *fileName)
82 {
83 int tempfd;
84 struct msqid_ds msqdesc;
85
86 msgbuffer.mtext[0] = 0;
87 msgbuffer.mtype = 1;
88
89 truncated = 0;
90 myauditstats.all = 0;
91 myauditstats.lost = 0;
92 myauditstats.truncated = 0;
93
94 /* try to create file for ftok if it doesn't already exist */
95 tempfd = open(fileName, O_WRONLY | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
96 if(tempfd != -1)
97 close(tempfd);
98
99 mqid = msgget(ftok(fileName, 1), S_IRUSR | S_IWUSR | IPC_CREAT);
100 if (mqid == -1) {
101 printf("Warning: auditlog message queue %s cannot be opened.\n", fileName);
102 return 1;
103 }
104
105 /* increase message queue size */
106 msgctl(mqid, IPC_STAT, &msqdesc);
107 if (msqdesc.msg_qbytes < MSGMNB) {
108 msqdesc.msg_qbytes = MSGMNB;
109 msgctl(mqid, IPC_SET, &msqdesc);
110 }
111
112 return 0;
113 }
114
115 static void
116 print_interface_stats(FILE *out)
117 {
118 fprintf(out, "audit statistics: %ld messages total, %ld truncated, %ld lost\n",
119 myauditstats.all, myauditstats.truncated, myauditstats.lost);
120 }
121
122 const struct osi_audit_ops audit_sysvmq_ops = {
123 &send_msg,
124 &append_msg,
125 &open_file,
126 &print_interface_stats,
127 };
128
129 #endif /* HAVE_SYS_IPC_H */