Commit | Line | Data |
---|---|---|
805e021f CE |
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 */ |