1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 /*
27 * nfs log - read buffer file and print structs in user-readable form
28 */
29
30 #define _REENTRANT
31
32 #include <ctype.h>
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <stddef.h>
36 #include <string.h>
37 #include <strings.h>
38 #include <time.h>
39 #include <fcntl.h>
40 #include <unistd.h>
41 #include <signal.h>
42 #include <sys/types.h>
43 #include <sys/stat.h>
44 #include <sys/param.h>
45 #include <sys/utsname.h>
46 #include <errno.h>
47 #include <time.h>
48 #include <limits.h>
49 #include <libintl.h>
50 #include <pwd.h>
51 #include <netdb.h>
52 #include <syslog.h>
53 #include <rpc/rpc.h>
54 #include <netconfig.h>
55 #include <netdir.h>
56 #include <nfs/nfs_sec.h>
57 #include <nfs/export.h>
58 #include <rpc/auth.h>
59 #include <rpc/svc.h>
60 #include <rpc/xdr.h>
61 #include <rpc/clnt.h>
62 #include <nfs/nfs.h>
63 #include <nfs/nfs_log.h>
64 #include "fhtab.h"
65 #include "nfslogd.h"
66
67 static char empty_name[4] = "-";
68
69 static char ftype3_names[NF3FIFO + 1][20] = {
70 "\"none\"", "\"file\"", "\"dir\"", "\"blk device\"",
71 "\"chr device\"", "\"link\"", "\"socket\"", "\"fifo\""
72 };
73
74 #define NFSL_FTYPE3(ftype) \
75 ((((ftype) >= 0) && ((ftype) <= NF3FIFO)) ? \
76 ftype3_names[ftype] : empty_name)
77
78 static char createmode3_names[EXCLUSIVE + 1][20] = {
79 "\"unchecked", "\"guarded\"", "\"exclusive\""
80 };
81
82 #define NFSL_CREATEMODE3(createmode) \
83 ((((createmode) >= 0) && ((createmode) <= EXCLUSIVE)) ? \
84 createmode3_names[createmode] : empty_name)
85
86 static char auth_flavor_name[RPCSEC_GSS + 1][20] = {
87 "\"auth_null\"", "\"auth_unix\"", "\"auth_short\"", "\"auth_des\"",
88 "\"auth_kerb\"", "\"none\"", "\"rpcsec_gss\""
89 };
90
91 #define NFSL_AUTH_FLAVOR_PRINT(auth_flavor) \
92 (((auth_flavor) <= RPCSEC_GSS) ? \
93 auth_flavor_name[auth_flavor] : empty_name)
94
95 #define NFSL_ERR_CNT 31 /* Actual err numbers */
96
97 /*
98 * Two arrays - one short ints containing err codes, the other the strings
99 * (merged codes for both v2 and v3
100 */
101 static char nfsl_status_name[NFSL_ERR_CNT][30] = {
102 "\"ok\"", "\"perm\"", "\"noent\"", "\"io\"",
103 "\"nxio\"", "\"access\"", "\"exist\"", "\"xdev\"",
104 "\"nodev\"", "\"notdir\"", "\"isdir\"", "\"inval\"",
105 "\"fbig\"", "\"nospc\"", "\"rofs\"", "\"mlink\"",
106 "\"notsupp\"", "\"nametoolong\"", "\"notempty\"", "\"dquot\"",
107 "\"stale\"", "\"remote\"", "\"wflush\"", "\"badhandle\"",
108 "\"not_sync\"", "\"bad_cookie\"", "\"notsupp\"", "\"toosmall\"",
109 "\"serverfault\"", "\"badtype\"", "\"jukebox\"",
110 };
111
112 static short nfsl_status[NFSL_ERR_CNT] = {
113 0, 1, 2, 5, 6, 13, 17, 18,
114 19, 20, 21, 22, 27, 28, 30, 31,
115 45, 63, 66, 69, 70, 71, 99, 10001,
116 10002, 10003, 10004, 10005, 10006, 10007, 10008
117 };
118
119 /* list of open elf files */
120 static struct nfsl_log_file *elf_file_list = NULL;
121
122 /* Imported functions */
123 extern void bcopy(const void *s1, void *s2, size_t n);
124
125 /* Static functions */
126 static void nfsl_log_file_free(struct nfsl_log_file *elfrec);
127 static void nfsl_log_file_add(struct nfsl_log_file *elfrec,
128 struct nfsl_log_file **elf_listp);
129 static struct nfsl_log_file *nfsl_log_file_find(struct nfsl_log_file *elfrec,
130 struct nfsl_log_file *elf_list);
131 static struct nfsl_log_file *nfsl_log_file_del(struct nfsl_log_file *elfrec,
132 struct nfsl_log_file **elf_listp);
133
134 static char *nfsl_get_time(time_t tt);
135 static char *nfsl_get_date(time_t tt);
136 static char *nfsl_get_date_nq(time_t tt);
137 static int nfsl_write_elfbuf(struct nfsl_log_file *elfrec);
138 static void nfsl_ipaddr_print(struct nfsl_log_file *, struct netbuf *);
139 static void nfsl_elf_record_header_print(struct nfsl_log_file *,
140 nfslog_record_header *, char *, char *,
141 struct nfsl_proc_disp *, char *);
142 static void nfsl_elf_buffer_header_print(struct nfsl_log_file *,
143 nfslog_buffer_header *);
144 static struct nfsl_proc_disp *nfsl_find_elf_dispatch(
145 nfslog_request_record *, char **);
146 static void nfsl_elf_rpc_print(struct nfsl_log_file *,
147 nfslog_request_record *, struct nfsl_proc_disp *,
148 char *, char *, char *);
149 static void nfslog_size3_print(struct nfsl_log_file *, set_size3 *);
150
151 static void nfslog_null_args(struct nfsl_log_file *, caddr_t *);
152 static void nfslog_null_res(struct nfsl_log_file *, caddr_t *);
153
154
155 /*
156 * NFS VERSION 2
157 */
158
159 /* Functions for elf print of the arguments */
160 static void nfslog_fhandle_print(struct nfsl_log_file *, fhandle_t *);
161 static void nfslog_diropargs_print(struct nfsl_log_file *, nfslog_diropargs *);
162 static void nfslog_setattrargs_print(struct nfsl_log_file *,
163 nfslog_setattrargs *);
164 static void nfslog_sattr_print(struct nfsl_log_file *,
165 nfslog_sattr *);
166 static void nfslog_nfsreadargs_print(struct nfsl_log_file *,
167 nfslog_nfsreadargs *);
168 static void nfslog_writeargs_print(struct nfsl_log_file *,
169 nfslog_writeargs *);
170 static void nfslog_writeresult_print(struct nfsl_log_file *,
171 nfslog_writeresult *, bool_t);
172 static void nfslog_creatargs_print(struct nfsl_log_file *,
173 nfslog_createargs *);
174 static void nfslog_rddirargs_print(struct nfsl_log_file *, nfslog_rddirargs *);
175 static void nfslog_linkargs_print(struct nfsl_log_file *, nfslog_linkargs *);
176 static void nfslog_rnmargs_print(struct nfsl_log_file *, nfslog_rnmargs *);
177 static void nfslog_symlinkargs_print(struct nfsl_log_file *,
178 nfslog_symlinkargs *);
179
180 static void nfslog_sharefsargs_print(struct nfsl_log_file *,
181 nfslog_sharefsargs *);
182 static void nfslog_getfhargs_print(struct nfsl_log_file *,
183 nfslog_getfhargs *);
184
185 /* Functions for elf print of the response */
186 static void nfslog_nfsstat_print(struct nfsl_log_file *, enum nfsstat *,
187 bool_t);
188 static void nfslog_diropres_print(struct nfsl_log_file *, nfslog_diropres *,
189 bool_t);
190 static void nfslog_rdlnres_print(struct nfsl_log_file *, nfslog_rdlnres *,
191 bool_t);
192 static void nfslog_rdresult_print(struct nfsl_log_file *,
193 nfslog_rdresult *, bool_t);
194 static void nfslog_rddirres_print(struct nfsl_log_file *, nfslog_rddirres *,
195 bool_t);
196
197 /*
198 * NFS VERSION 3
199 */
200
201 /* Functions for elf print of the arguments */
202 static void nfslog_fh3_print(struct nfsl_log_file *, nfs_fh3 *);
203 static void nfslog_diropargs3_print(struct nfsl_log_file *,
204 nfslog_diropargs3 *);
205 static void nfslog_SETATTR3args_print(struct nfsl_log_file *,
206 nfslog_SETATTR3args *);
207 static void nfslog_READ3args_print(struct nfsl_log_file *, nfslog_READ3args *);
208 static void nfslog_WRITE3args_print(struct nfsl_log_file *,
209 nfslog_WRITE3args *);
210 static void nfslog_CREATE3args_print(struct nfsl_log_file *,
211 nfslog_CREATE3args *);
212 static void nfslog_MKDIR3args_print(struct nfsl_log_file *,
213 nfslog_MKDIR3args *);
214 static void nfslog_SYMLINK3args_print(struct nfsl_log_file *,
215 nfslog_SYMLINK3args *);
216 static void nfslog_MKNOD3args_print(struct nfsl_log_file *,
217 nfslog_MKNOD3args *);
218 static void nfslog_REMOVE3args_print(struct nfsl_log_file *,
219 nfslog_REMOVE3args *);
220 static void nfslog_RMDIR3args_print(struct nfsl_log_file *,
221 nfslog_RMDIR3args *);
222 static void nfslog_RENAME3args_print(struct nfsl_log_file *,
223 nfslog_RENAME3args *);
224 static void nfslog_LINK3args_print(struct nfsl_log_file *,
225 nfslog_LINK3args *);
226 static void nfslog_COMMIT3args_print(struct nfsl_log_file *,
227 nfslog_COMMIT3args *);
228 static void nfslog_READDIRPLUS3args_print(struct nfsl_log_file *,
229 nfslog_READDIRPLUS3args *);
230
231 /* Functions for elf print of the response */
232 static void nfslog_nfsstat3_print(struct nfsl_log_file *,
233 nfsstat3 *, bool_t);
234 static void nfslog_LOOKUP3res_print(struct nfsl_log_file *,
235 nfslog_LOOKUP3res *, bool_t);
236 static void nfslog_READLINK3res_print(struct nfsl_log_file *,
237 nfslog_READLINK3res *, bool_t);
238 static void nfslog_READ3res_print(struct nfsl_log_file *,
239 nfslog_READ3res *, bool_t);
240 static void nfslog_WRITE3res_print(struct nfsl_log_file *,
241 nfslog_WRITE3res *, bool_t);
242 static void nfslog_CREATE3res_print(struct nfsl_log_file *,
243 nfslog_CREATE3res *, bool_t);
244 static void nfslog_MKDIR3res_print(struct nfsl_log_file *,
245 nfslog_MKDIR3res *, bool_t);
246 static void nfslog_SYMLINK3res_print(struct nfsl_log_file *,
247 nfslog_SYMLINK3res *, bool_t);
248 static void nfslog_MKNOD3res_print(struct nfsl_log_file *,
249 nfslog_MKNOD3res *, bool_t);
250 static void nfslog_READDIRPLUS3res_print(struct nfsl_log_file *,
251 nfslog_READDIRPLUS3res *, bool_t);
252
253 extern int debug;
254 static bool_t nfsl_print_fh = FALSE; /* print file handles? */
255
256 #define DFLT_BUFFERSIZE 8192
257 #define DFLT_OVFSIZE 3072 /* Maximum logged or buffered size */
258
259 static char hostname[MAXHOSTNAMELEN]; /* name of host */
260
261
262 /*
263 * Define the actions taken per prog/vers/proc:
264 *
265 * In some cases, the nl types are the same as the nfs types and a simple
266 * bcopy should suffice. Rather that define tens of identical procedures,
267 * simply define these to bcopy. Similarly this takes care of different
268 * procs that use same parameter struct.
269 */
270
271 static struct nfsl_proc_disp nfsl_elf_proc_v2[] = {
272 /*
273 * NFS VERSION 2
274 */
275
276 /* RFS_NULL = 0 */
277 {nfslog_null_args, nfslog_null_res, "\"null\""},
278
279 /* RFS_GETATTR = 1 */
280 {nfslog_fhandle_print, nfslog_nfsstat_print, "\"getattr\""},
281
282 /* RFS_SETATTR = 2 */
283 {nfslog_setattrargs_print, nfslog_nfsstat_print, "\"setattr\""},
284
285 /* RFS_ROOT = 3 *** NO LONGER SUPPORTED *** */
286 {nfslog_null_args, nfslog_null_res, "\"root\""},
287
288 /* RFS_LOOKUP = 4 */
289 {nfslog_diropargs_print, nfslog_diropres_print, "\"lookup\""},
290
291 /* RFS_READLINK = 5 */
292 {nfslog_fhandle_print, nfslog_rdlnres_print, "\"readlink\""},
293
294 /* RFS_READ = 6 */
295 {nfslog_nfsreadargs_print, nfslog_rdresult_print, "\"read\""},
296
297 /* RFS_WRITECACHE = 7 *** NO LONGER SUPPORTED *** */
298 {nfslog_null_args, nfslog_null_res, "\"writecache\""},
299
300 /* RFS_WRITE = 8 */
301 {nfslog_writeargs_print, nfslog_writeresult_print, "\"write\""},
302
303 /* RFS_CREATE = 9 */
304 {nfslog_creatargs_print, nfslog_diropres_print, "\"create\""},
305
306 /* RFS_REMOVE = 10 */
307 {nfslog_diropargs_print, nfslog_nfsstat_print, "\"remove\""},
308
309 /* RFS_RENAME = 11 */
310 {nfslog_rnmargs_print, nfslog_nfsstat_print, "\"rename\""},
311
312 /* RFS_LINK = 12 */
313 {nfslog_linkargs_print, nfslog_nfsstat_print, "\"link\""},
314
315 /* RFS_SYMLINK = 13 */
316 {nfslog_symlinkargs_print, nfslog_nfsstat_print, "\"symlink\""},
317
318 /* RFS_MKDIR = 14 */
319 {nfslog_creatargs_print, nfslog_diropres_print, "\"mkdir\""},
320
321 /* RFS_RMDIR = 15 */
322 {nfslog_diropargs_print, nfslog_nfsstat_print, "\"rmdir\""},
323
324 /* RFS_READDIR = 16 */
325 {nfslog_rddirargs_print, nfslog_rddirres_print, "\"readdir\""},
326
327 /* RFS_STATFS = 17 */
328 {nfslog_fhandle_print, nfslog_nfsstat_print, "\"statfs\""},
329 };
330
331
332 /*
333 * NFS VERSION 3
334 */
335
336 static struct nfsl_proc_disp nfsl_elf_proc_v3[] = {
337
338 /* NFSPROC3_NULL = 0 */
339 {nfslog_null_args, nfslog_null_res, "\"null\""},
340
341 /* NFSPROC3_GETATTR = 1 */
342 {nfslog_fh3_print, nfslog_nfsstat3_print, "\"getattr\""},
343
344 /* NFSPROC3_SETATTR = 2 */
345 {nfslog_SETATTR3args_print, nfslog_nfsstat3_print, "\"setattr\""},
346
347 /* NFSPROC3_LOOKUP = 3 */
348 {nfslog_diropargs3_print, nfslog_LOOKUP3res_print, "\"lookup\""},
349
350 /* NFSPROC3_ACCESS = 4 */
351 {nfslog_fh3_print, nfslog_nfsstat3_print, "\"access\""},
352
353 /* NFSPROC3_READLINK = 5 */
354 {nfslog_fh3_print, nfslog_READLINK3res_print, "\"readlink\""},
355
356 /* NFSPROC3_READ = 6 */
357 {nfslog_READ3args_print, nfslog_READ3res_print, "\"read\""},
358
359 /* NFSPROC3_WRITE = 7 */
360 {nfslog_WRITE3args_print, nfslog_WRITE3res_print, "\"write\""},
361
362 /* NFSPROC3_CREATE = 8 */
363 {nfslog_CREATE3args_print, nfslog_CREATE3res_print, "\"create\""},
364
365 /* NFSPROC3_MKDIR = 9 */
366 {nfslog_MKDIR3args_print, nfslog_MKDIR3res_print, "\"mkdir\""},
367
368 /* NFSPROC3_SYMLINK = 10 */
369 {nfslog_SYMLINK3args_print, nfslog_SYMLINK3res_print, "\"symlink\""},
370
371 /* NFSPROC3_MKNOD = 11 */
372 {nfslog_MKNOD3args_print, nfslog_MKNOD3res_print, "\"mknod\""},
373
374 /* NFSPROC3_REMOVE = 12 */
375 {nfslog_REMOVE3args_print, nfslog_nfsstat3_print, "\"remove\""},
376
377 /* NFSPROC3_RMDIR = 13 */
378 {nfslog_RMDIR3args_print, nfslog_nfsstat3_print, "\"rmdir\""},
379
380 /* NFSPROC3_RENAME = 14 */
381 {nfslog_RENAME3args_print, nfslog_nfsstat3_print, "\"rename\""},
382
383 /* NFSPROC3_LINK = 15 */
384 {nfslog_LINK3args_print, nfslog_nfsstat3_print, "\"link\""},
385
386 /* NFSPROC3_READDIR = 16 */
387 {nfslog_fh3_print, nfslog_nfsstat3_print, "\"readdir\""},
388
389 /* NFSPROC3_READDIRPLUS = 17 */
390 {nfslog_READDIRPLUS3args_print, nfslog_READDIRPLUS3res_print,
391 "\"readdirplus\""},
392
393 /* NFSPROC3_FSSTAT = 18 */
394 {nfslog_fh3_print, nfslog_nfsstat3_print, "\"fsstat\""},
395
396 /* NFSPROC3_FSINFO = 19 */
397 {nfslog_fh3_print, nfslog_nfsstat3_print, "\"fsinfo\""},
398
399 /* NFSPROC3_PATHCONF = 20 */
400 {nfslog_fh3_print, nfslog_nfsstat3_print, "\"pathconf\""},
401
402 /* NFSPROC3_COMMIT = 21 */
403 {nfslog_COMMIT3args_print, nfslog_nfsstat3_print, "\"commit\""},
404 };
405
406 /*
407 * NFSLOG VERSION 1
408 */
409
410 static struct nfsl_proc_disp nfsl_log_elf_proc_v1[] = {
411
412 /* NFSLOG_NULL = 0 */
413 {nfslog_null_args, nfslog_null_res, "\"null\""},
414
415 /* NFSLOG_SHARE = 1 */
416 {nfslog_sharefsargs_print, nfslog_nfsstat_print, "\"log_share\""},
417
418 /* NFSLOG_UNSHARE = 2 */
419 {nfslog_sharefsargs_print, nfslog_nfsstat_print, "\"log_unshare\""},
420
421 /* NFSLOG_LOOKUP = 3 */
422 {nfslog_diropargs3_print, nfslog_LOOKUP3res_print, "\"lookup\""},
423
424 /* NFSLOG_GETFH = 4 */
425 {nfslog_getfhargs_print, nfslog_nfsstat_print, "\"log_getfh\""},
426 };
427
428 static struct nfsl_vers_disp nfsl_elf_vers_disptable[] = {
429 {sizeof (nfsl_elf_proc_v2) / sizeof (nfsl_elf_proc_v2[0]),
430 nfsl_elf_proc_v2},
431 {sizeof (nfsl_elf_proc_v3) / sizeof (nfsl_elf_proc_v3[0]),
432 nfsl_elf_proc_v3},
433 };
434
435 static struct nfsl_vers_disp nfsl_log_elf_vers_disptable[] = {
436 {sizeof (nfsl_log_elf_proc_v1) / sizeof (nfsl_log_elf_proc_v1[0]),
437 nfsl_log_elf_proc_v1},
438 };
439
440 static struct nfsl_prog_disp nfsl_elf_dispatch_table[] = {
441 {NFS_PROGRAM,
442 NFS_VERSMIN,
443 sizeof (nfsl_elf_vers_disptable) /
444 sizeof (nfsl_elf_vers_disptable[0]),
445 nfsl_elf_vers_disptable, "nfs"},
446 {NFSLOG_PROGRAM,
447 NFSLOG_VERSMIN,
448 sizeof (nfsl_log_elf_vers_disptable) /
449 sizeof (nfsl_log_elf_vers_disptable[0]),
450 nfsl_log_elf_vers_disptable, "nfslog"},
451 };
452
453 static int nfsl_elf_dispatch_table_arglen =
454 sizeof (nfsl_elf_dispatch_table) /
455 sizeof (nfsl_elf_dispatch_table[0]);
456
457 static char *
nfslog_get_status(short status)458 nfslog_get_status(short status)
459 {
460 int low, mid, high;
461 short errstat;
462
463 /* Usually status is 0... */
464 if (status == 0)
465 return (nfsl_status_name[0]);
466
467 low = 0;
468 high = NFSL_ERR_CNT;
469 mid = NFSL_ERR_CNT / 2;
470 /* binary search for status string */
471 while (((errstat = nfsl_status[mid]) != status) && (low < mid) &&
472 (mid < high)) {
473 if (errstat > status) { /* search bottom half */
474 high = mid;
475 } else { /* search upper half */
476 low = mid;
477 }
478 mid = low + ((high - low) / 2);
479 }
480 if (errstat == status) { /* found it */
481 return (nfsl_status_name[mid]);
482 }
483 return (NULL);
484 }
485
486 /* nfsl_get_time - return string with time formatted as hh:mm:ss */
487 static char *
nfsl_get_time(time_t tt)488 nfsl_get_time(time_t tt)
489 {
490 static char timestr[20];
491 static time_t lasttime;
492 struct tm tmst;
493
494 if (tt == lasttime)
495 return (timestr);
496 if (localtime_r(&tt, &tmst) == NULL) {
497 return (empty_name);
498 }
499 (void) sprintf(timestr, "%02d:%02d:%02d",
500 tmst.tm_hour, tmst.tm_min, tmst.tm_sec);
501 lasttime = tt;
502 return (timestr);
503 }
504
505 /* nfsl_get_date - return date string formatted as "yyyy-mm-dd hh:mm:ss" */
506 static char *
nfsl_get_date(time_t tt)507 nfsl_get_date(time_t tt)
508 {
509 static char timestr[30];
510 static time_t lasttime;
511 struct tm tmst;
512
513 if (tt == lasttime)
514 return (timestr);
515 if (localtime_r(&tt, &tmst) == NULL) {
516 return (empty_name);
517 }
518 (void) sprintf(timestr, "\"%04d-%02d-%02d %02d:%02d:%02d\"",
519 tmst.tm_year + 1900, tmst.tm_mon + 1, tmst.tm_mday,
520 tmst.tm_hour, tmst.tm_min, tmst.tm_sec);
521 lasttime = tt;
522 return (timestr);
523 }
524
525 /*
526 * nfsl_get_date_nq - return date string formatted as yyyy-mm-dd hh:mm:ss
527 * (no quotes)
528 */
529 static char *
nfsl_get_date_nq(time_t tt)530 nfsl_get_date_nq(time_t tt)
531 {
532 static char timestr[30];
533 static time_t lasttime;
534 struct tm tmst;
535
536 if (tt == lasttime)
537 return (timestr);
538 if (localtime_r(&tt, &tmst) == NULL) {
539 return (empty_name);
540 }
541 (void) sprintf(timestr, "%04d-%02d-%02d %02d:%02d:%02d",
542 tmst.tm_year + 1900, tmst.tm_mon + 1, tmst.tm_mday,
543 tmst.tm_hour, tmst.tm_min, tmst.tm_sec);
544 return (timestr);
545 }
546
547 /* write log buffer out to file */
548 static int
nfsl_write_elfbuf(struct nfsl_log_file * elfrec)549 nfsl_write_elfbuf(struct nfsl_log_file *elfrec)
550 {
551 int rc;
552 char *elfbuf = elfrec->buf;
553 int elfbufoffset = elfrec->bufoffset;
554
555 if (debug > 1)
556 (void) printf("nfsl_write_elfbuf: bufoffset %d\n",
557 elfbufoffset);
558 if (elfbufoffset <= 0)
559 return (0);
560 elfbuf[elfbufoffset] = '\0';
561 if ((rc = fputs(elfbuf, elfrec->fp)) < 0) {
562 syslog(LOG_ERR, gettext("Write to %s failed: %s\n"),
563 elfrec->path, strerror(errno));
564 return (-1);
565 }
566 if (rc != elfbufoffset) {
567 syslog(LOG_ERR, gettext("Write %d bytes to %s returned %d\n"),
568 elfbufoffset, elfrec->path, rc);
569 return (-1);
570 }
571 elfrec->bufoffset = 0;
572 return (0);
573 }
574
575 /*ARGSUSED*/
576 static void
nfslog_null_args(struct nfsl_log_file * elfrec,caddr_t * nfsl_args)577 nfslog_null_args(struct nfsl_log_file *elfrec, caddr_t *nfsl_args)
578 {
579 }
580
581 /*ARGSUSED*/
582 static void
nfslog_null_res(struct nfsl_log_file * elfrec,caddr_t * nfsl_res)583 nfslog_null_res(struct nfsl_log_file *elfrec, caddr_t *nfsl_res)
584 {
585 }
586
587 static void
nfslog_fh3_print(struct nfsl_log_file * elfrec,nfs_fh3 * fh3)588 nfslog_fh3_print(struct nfsl_log_file *elfrec, nfs_fh3 *fh3)
589 {
590 if (!nfsl_print_fh)
591 return;
592 if (fh3->fh3_length == sizeof (fhandle_t)) {
593 nfslog_fhandle_print(elfrec, (fhandle_t *)&fh3->fh3_u.data);
594 } else {
595 nfslog_opaque_print_buf(fh3->fh3_u.data, fh3->fh3_length,
596 elfrec->buf, &elfrec->bufoffset,
597 DFLT_BUFFERSIZE + DFLT_OVFSIZE);
598 }
599 }
600
601 /*
602 * NFS VERSION 2
603 */
604
605
606 /* Functions that elf print the arguments */
607
608 static void
nfslog_fhandle_print(struct nfsl_log_file * elfrec,fhandle_t * args)609 nfslog_fhandle_print(struct nfsl_log_file *elfrec, fhandle_t *args)
610 {
611 if (!nfsl_print_fh)
612 return;
613 nfslog_opaque_print_buf(args, sizeof (*args),
614 elfrec->buf, &elfrec->bufoffset,
615 DFLT_BUFFERSIZE + DFLT_OVFSIZE);
616 }
617
618 static void
nfslog_diropargs_print(struct nfsl_log_file * elfrec,nfslog_diropargs * args)619 nfslog_diropargs_print(struct nfsl_log_file *elfrec, nfslog_diropargs *args)
620 {
621 char *elfbuf = elfrec->buf;
622 int elfbufoffset = elfrec->bufoffset;
623
624 if (nfsl_print_fh) {
625 nfslog_fhandle_print(elfrec, &args->da_fhandle);
626 elfbufoffset = elfrec->bufoffset;
627 if (args->da_name != NULL) {
628 elfbufoffset += sprintf(&elfbuf[elfbufoffset],
629 " \"%s\"", args->da_name);
630 } else {
631 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " %s",
632 empty_name);
633 }
634 }
635 elfrec->bufoffset = elfbufoffset;
636 }
637
638 static void
nfslog_sattr_print(struct nfsl_log_file * elfrec,nfslog_sattr * args)639 nfslog_sattr_print(struct nfsl_log_file *elfrec, nfslog_sattr *args)
640 {
641 char *elfbuf = elfrec->buf;
642 int elfbufoffset = elfrec->bufoffset;
643
644 /* BEGIN CSTYLED */
645 if (args->sa_mode != (uint32_t)-1) {
646 elfbufoffset += sprintf(&elfbuf[elfbufoffset],
647 " \"mode=0%o\"", args->sa_mode);
648 }
649 if (args->sa_uid != (uint32_t)-1) {
650 elfbufoffset += sprintf(&elfbuf[elfbufoffset],
651 " \"uid=0x%x\"", args->sa_uid);
652 }
653 if (args->sa_gid != (uint32_t)-1) {
654 elfbufoffset += sprintf(&elfbuf[elfbufoffset],
655 " \"gid=0x%x\"", args->sa_gid);
656 }
657 if (args->sa_size != (uint32_t)-1) {
658 elfbufoffset += sprintf(&elfbuf[elfbufoffset],
659 " \"size=0x%x\"", args->sa_size);
660 }
661 if (args->sa_atime.tv_sec != (uint32_t)-1) {
662 elfbufoffset += sprintf(&elfbuf[elfbufoffset],
663 " \"atime=%s\"",
664 nfsl_get_date_nq((time_t)args->sa_atime.tv_sec));
665 }
666 if (args->sa_mtime.tv_sec != (uint32_t)-1) {
667 elfbufoffset += sprintf(&elfbuf[elfbufoffset],
668 " \"mtime=%s\"",
669 nfsl_get_date_nq((time_t)args->sa_mtime.tv_sec));
670 }
671 /* END CSTYLED */
672 elfrec->bufoffset = elfbufoffset;
673 }
674
675 static void
nfslog_setattrargs_print(struct nfsl_log_file * elfrec,nfslog_setattrargs * args)676 nfslog_setattrargs_print(struct nfsl_log_file *elfrec, nfslog_setattrargs *args)
677 {
678 nfslog_fhandle_print(elfrec, &args->saa_fh);
679 nfslog_sattr_print(elfrec, &args->saa_sa);
680 }
681
682 static void
nfslog_nfsreadargs_print(struct nfsl_log_file * elfrec,nfslog_nfsreadargs * args)683 nfslog_nfsreadargs_print(struct nfsl_log_file *elfrec,
684 nfslog_nfsreadargs *args)
685 {
686 char *elfbuf = elfrec->buf;
687 int elfbufoffset;
688
689 nfslog_fhandle_print(elfrec, &args->ra_fhandle);
690 elfbufoffset = elfrec->bufoffset;
691 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " 0x%x",
692 args->ra_offset);
693 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " 0x%x",
694 args->ra_count);
695 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " 0x%x",
696 args->ra_totcount);
697 elfrec->bufoffset = elfbufoffset;
698 }
699
700 static void
nfslog_writeargs_print(struct nfsl_log_file * elfrec,nfslog_writeargs * args)701 nfslog_writeargs_print(struct nfsl_log_file *elfrec, nfslog_writeargs *args)
702 {
703 char *elfbuf = elfrec->buf;
704 int elfbufoffset = elfrec->bufoffset;
705
706 nfslog_fhandle_print(elfrec, &args->waargs_fhandle);
707 elfbufoffset = elfrec->bufoffset;
708 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " 0x%x",
709 args->waargs_begoff);
710 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " 0x%x",
711 args->waargs_offset);
712 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " 0x%x",
713 args->waargs_totcount);
714 elfrec->bufoffset += sprintf(&elfrec->buf[elfrec->bufoffset], " 0x%x",
715 args->waargs_count);
716 }
717
718 static void
nfslog_writeresult_print(struct nfsl_log_file * elfrec,nfslog_writeresult * res,bool_t print_status)719 nfslog_writeresult_print(struct nfsl_log_file *elfrec, nfslog_writeresult *res,
720 bool_t print_status)
721 {
722 char *elfbuf = elfrec->buf;
723 int elfbufoffset = elfrec->bufoffset;
724
725 if (print_status) {
726 nfslog_nfsstat_print(elfrec, &res->wr_status, print_status);
727 } else if (res->wr_status == NFS_OK) {
728 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " 0x%x",
729 res->nfslog_writeresult_u.wr_size);
730 elfrec->bufoffset = elfbufoffset;
731 }
732 }
733
734 static void
nfslog_creatargs_print(struct nfsl_log_file * elfrec,nfslog_createargs * args)735 nfslog_creatargs_print(struct nfsl_log_file *elfrec, nfslog_createargs *args)
736 {
737 nfslog_diropargs_print(elfrec, &args->ca_da);
738 nfslog_sattr_print(elfrec, &args->ca_sa);
739 }
740
741
742 static void
nfslog_rddirargs_print(struct nfsl_log_file * elfrec,nfslog_rddirargs * args)743 nfslog_rddirargs_print(struct nfsl_log_file *elfrec, nfslog_rddirargs *args)
744 {
745 char *elfbuf = elfrec->buf;
746 int elfbufoffset;
747
748 nfslog_fhandle_print(elfrec, &args->rda_fh);
749 elfbufoffset = elfrec->bufoffset;
750 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " 0x%x",
751 args->rda_offset);
752 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " 0x%x",
753 args->rda_count);
754 elfrec->bufoffset = elfbufoffset;
755 }
756
757 static void
nfslog_rnmargs_print(struct nfsl_log_file * elfrec,nfslog_rnmargs * args)758 nfslog_rnmargs_print(struct nfsl_log_file *elfrec, nfslog_rnmargs *args)
759 {
760 nfslog_diropargs_print(elfrec, &args->rna_from);
761 nfslog_diropargs_print(elfrec, &args->rna_to);
762 }
763
764 static void
nfslog_linkargs_print(struct nfsl_log_file * elfrec,nfslog_linkargs * args)765 nfslog_linkargs_print(struct nfsl_log_file *elfrec, nfslog_linkargs *args)
766 {
767 nfslog_fhandle_print(elfrec, &args->la_from);
768 nfslog_diropargs_print(elfrec, &args->la_to);
769 }
770
771 static void
nfslog_symlinkargs_print(struct nfsl_log_file * elfrec,nfslog_symlinkargs * args)772 nfslog_symlinkargs_print(struct nfsl_log_file *elfrec, nfslog_symlinkargs *args)
773 {
774 char *elfbuf = elfrec->buf;
775 int elfbufoffset;
776
777 nfslog_diropargs_print(elfrec, &args->sla_from);
778 elfbufoffset = elfrec->bufoffset;
779 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " \"%s\"",
780 args->sla_tnm);
781 elfrec->bufoffset = elfbufoffset;
782 nfslog_sattr_print(elfrec, &args->sla_sa);
783 }
784
785 /*
786 * SHARE/UNSHARE fs log args copy
787 */
788 static void
nfslog_sharefsargs_print(struct nfsl_log_file * elfrec,nfslog_sharefsargs * args)789 nfslog_sharefsargs_print(struct nfsl_log_file *elfrec,
790 nfslog_sharefsargs *args)
791 {
792 unsigned int elfbufoffset;
793 char *elfbuf = elfrec->buf;
794
795 nfslog_fhandle_print(elfrec, &args->sh_fh_buf);
796
797 elfbufoffset = elfrec->bufoffset;
798 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " 0x%x",
799 args->sh_flags);
800 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " 0x%x",
801 args->sh_anon);
802 if (nfsl_print_fh) {
803 if (args->sh_path != NULL) {
804 elfbufoffset += sprintf(&elfbuf[elfbufoffset],
805 " \"%s\"", args->sh_path);
806 } else {
807 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " %s",
808 empty_name);
809 }
810 }
811 elfrec->bufoffset = elfbufoffset;
812 }
813
814 static void
nfslog_getfhargs_print(struct nfsl_log_file * elfrec,nfslog_getfhargs * args)815 nfslog_getfhargs_print(struct nfsl_log_file *elfrec,
816 nfslog_getfhargs *args)
817 {
818 unsigned int elfbufoffset;
819 char *elfbuf = elfrec->buf;
820
821 nfslog_fhandle_print(elfrec, &args->gfh_fh_buf);
822
823 elfbufoffset = elfrec->bufoffset;
824 if (nfsl_print_fh) {
825 if (args->gfh_path != NULL) {
826 elfbufoffset += sprintf(&elfbuf[elfbufoffset],
827 " \"%s\"", args->gfh_path);
828 } else {
829 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " %s",
830 empty_name);
831 }
832 }
833 elfrec->bufoffset = elfbufoffset;
834 }
835
836 static void
nfslog_nfsstat_print(struct nfsl_log_file * elfrec,enum nfsstat * res,bool_t print_status)837 nfslog_nfsstat_print(struct nfsl_log_file *elfrec, enum nfsstat *res,
838 bool_t print_status)
839 {
840 if (print_status) {
841 char *statp = nfslog_get_status((short)(*res));
842
843 if (statp != NULL)
844 elfrec->bufoffset +=
845 sprintf(&elfrec->buf[elfrec->bufoffset], " %s",
846 statp);
847 else
848 elfrec->bufoffset +=
849 sprintf(&elfrec->buf[elfrec->bufoffset], " %5d",
850 *res);
851 }
852 }
853
854 static void
nfslog_diropres_print(struct nfsl_log_file * elfrec,nfslog_diropres * res,bool_t print_status)855 nfslog_diropres_print(struct nfsl_log_file *elfrec, nfslog_diropres *res,
856 bool_t print_status)
857 {
858 if (print_status) {
859 nfslog_nfsstat_print(elfrec, &res->dr_status, print_status);
860 } else if (res->dr_status == NFS_OK) {
861 nfslog_fhandle_print(elfrec,
862 &res->nfslog_diropres_u.dr_ok.drok_fhandle);
863 }
864 }
865
866 static void
nfslog_rdlnres_print(struct nfsl_log_file * elfrec,nfslog_rdlnres * res,bool_t print_status)867 nfslog_rdlnres_print(struct nfsl_log_file *elfrec, nfslog_rdlnres *res,
868 bool_t print_status)
869 {
870 if (print_status) {
871 nfslog_nfsstat_print(elfrec, &res->rl_status, print_status);
872 } else if (res->rl_status == NFS_OK) {
873 elfrec->bufoffset += sprintf(&elfrec->buf[elfrec->bufoffset],
874 " \"%s\"", res->nfslog_rdlnres_u.rl_ok);
875 }
876 }
877
878 static void
nfslog_rdresult_print(struct nfsl_log_file * elfrec,nfslog_rdresult * res,bool_t print_status)879 nfslog_rdresult_print(struct nfsl_log_file *elfrec, nfslog_rdresult *res,
880 bool_t print_status)
881 {
882 if (print_status) {
883 nfslog_nfsstat_print(elfrec, &res->r_status, print_status);
884 } else if (res->r_status == NFS_OK) {
885 elfrec->bufoffset += sprintf(&elfrec->buf[elfrec->bufoffset],
886 " 0x%x", res->nfslog_rdresult_u.r_ok.filesize);
887 elfrec->bufoffset += sprintf(&elfrec->buf[elfrec->bufoffset],
888 " 0x%x", res->nfslog_rdresult_u.r_ok.rrok_count);
889 }
890 }
891
892 static void
nfslog_rddirres_print(struct nfsl_log_file * elfrec,nfslog_rddirres * res,bool_t print_status)893 nfslog_rddirres_print(struct nfsl_log_file *elfrec, nfslog_rddirres *res,
894 bool_t print_status)
895 {
896 if (print_status) {
897 nfslog_nfsstat_print(elfrec, &res->rd_status, print_status);
898 } else if (res->rd_status == NFS_OK) {
899 char *elfbuf = elfrec->buf;
900 int elfbufoffset = elfrec->bufoffset;
901
902 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " 0x%x",
903 res->nfslog_rddirres_u.rd_ok.rdok_offset);
904 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " 0x%x",
905 res->nfslog_rddirres_u.rd_ok.rdok_size);
906 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " 0x%x",
907 res->nfslog_rddirres_u.rd_ok.rdok_eof);
908 elfrec->bufoffset = elfbufoffset;
909 }
910 }
911
912 /*
913 * NFS VERSION 3
914 */
915
916 static void
nfslog_diropargs3_print(struct nfsl_log_file * elfrec,nfslog_diropargs3 * args)917 nfslog_diropargs3_print(struct nfsl_log_file *elfrec,
918 nfslog_diropargs3 *args)
919 {
920 if (nfsl_print_fh) {
921 nfslog_fh3_print(elfrec, &args->dir);
922 elfrec->bufoffset += sprintf(&elfrec->buf[elfrec->bufoffset],
923 " \"%s\"", args->name);
924 }
925 }
926
927 static void
nfslog_size3_print(struct nfsl_log_file * elfrec,set_size3 * args)928 nfslog_size3_print(struct nfsl_log_file *elfrec, set_size3 *args)
929 {
930 char *elfbuf = elfrec->buf;
931 int elfbufoffset = elfrec->bufoffset;
932
933 if (args->set_it) {
934 elfbufoffset += sprintf(&elfbuf[elfbufoffset],
935 /* CSTYLED */
936 " \"size=0x%llx\"", args->size);
937 }
938 elfrec->bufoffset = elfbufoffset;
939 }
940
941 static void
nfslog_SETATTR3args_print(struct nfsl_log_file * elfrec,nfslog_SETATTR3args * args)942 nfslog_SETATTR3args_print(struct nfsl_log_file *elfrec,
943 nfslog_SETATTR3args *args)
944 {
945 nfslog_fh3_print(elfrec, &args->object);
946 nfslog_size3_print(elfrec, &args->size);
947 }
948
949 static void
nfslog_READ3args_print(struct nfsl_log_file * elfrec,nfslog_READ3args * args)950 nfslog_READ3args_print(struct nfsl_log_file *elfrec, nfslog_READ3args *args)
951 {
952 nfslog_fh3_print(elfrec, &args->file);
953 elfrec->bufoffset += sprintf(&elfrec->buf[elfrec->bufoffset], " 0x%llx",
954 args->offset);
955 elfrec->bufoffset += sprintf(&elfrec->buf[elfrec->bufoffset], " 0x%x",
956 args->count);
957 }
958
959 static void
nfslog_WRITE3args_print(struct nfsl_log_file * elfrec,nfslog_WRITE3args * args)960 nfslog_WRITE3args_print(struct nfsl_log_file *elfrec,
961 nfslog_WRITE3args *args)
962 {
963 char *elfbuf = elfrec->buf;
964 int elfbufoffset;
965
966 nfslog_fh3_print(elfrec, &args->file);
967 elfbufoffset = elfrec->bufoffset;
968 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " 0x%llx",
969 args->offset);
970 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " 0x%x",
971 args->count);
972 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " 0x%x",
973 args->stable);
974 elfrec->bufoffset = elfbufoffset;
975 }
976
977 static void
nfslog_CREATE3args_print(struct nfsl_log_file * elfrec,nfslog_CREATE3args * args)978 nfslog_CREATE3args_print(struct nfsl_log_file *elfrec,
979 nfslog_CREATE3args *args)
980 {
981 nfslog_diropargs3_print(elfrec, &args->where);
982 elfrec->bufoffset += sprintf(&elfrec->buf[elfrec->bufoffset], " %s",
983 NFSL_CREATEMODE3(args->how.mode));
984 if (args->how.mode != EXCLUSIVE) {
985 nfslog_size3_print(elfrec,
986 &args->how.nfslog_createhow3_u.size);
987 }
988 }
989
990 static void
nfslog_MKDIR3args_print(struct nfsl_log_file * elfrec,nfslog_MKDIR3args * args)991 nfslog_MKDIR3args_print(struct nfsl_log_file *elfrec,
992 nfslog_MKDIR3args *args)
993 {
994 nfslog_diropargs3_print(elfrec, &args->where);
995 }
996
997 static void
nfslog_SYMLINK3args_print(struct nfsl_log_file * elfrec,nfslog_SYMLINK3args * args)998 nfslog_SYMLINK3args_print(struct nfsl_log_file *elfrec,
999 nfslog_SYMLINK3args *args)
1000 {
1001 nfslog_diropargs3_print(elfrec, &args->where);
1002 elfrec->bufoffset += sprintf(&elfrec->buf[elfrec->bufoffset],
1003 " \"%s\"", args->symlink_data);
1004 }
1005
1006 static void
nfslog_MKNOD3args_print(struct nfsl_log_file * elfrec,nfslog_MKNOD3args * args)1007 nfslog_MKNOD3args_print(struct nfsl_log_file *elfrec,
1008 nfslog_MKNOD3args *args)
1009 {
1010 nfslog_diropargs3_print(elfrec, &args->where);
1011 elfrec->bufoffset += sprintf(&elfrec->buf[elfrec->bufoffset], " %s",
1012 NFSL_FTYPE3(args->type));
1013 }
1014
1015 static void
nfslog_REMOVE3args_print(struct nfsl_log_file * elfrec,nfslog_REMOVE3args * args)1016 nfslog_REMOVE3args_print(struct nfsl_log_file *elfrec,
1017 nfslog_REMOVE3args *args)
1018 {
1019 nfslog_diropargs3_print(elfrec, &args->object);
1020 }
1021
1022 static void
nfslog_RMDIR3args_print(struct nfsl_log_file * elfrec,nfslog_RMDIR3args * args)1023 nfslog_RMDIR3args_print(struct nfsl_log_file *elfrec,
1024 nfslog_RMDIR3args *args)
1025 {
1026 nfslog_diropargs3_print(elfrec, &args->object);
1027 }
1028
1029 static void
nfslog_RENAME3args_print(struct nfsl_log_file * elfrec,nfslog_RENAME3args * args)1030 nfslog_RENAME3args_print(struct nfsl_log_file *elfrec,
1031 nfslog_RENAME3args *args)
1032 {
1033 nfslog_diropargs3_print(elfrec, &args->from);
1034 nfslog_diropargs3_print(elfrec, &args->to);
1035 }
1036
1037 static void
nfslog_LINK3args_print(struct nfsl_log_file * elfrec,nfslog_LINK3args * args)1038 nfslog_LINK3args_print(struct nfsl_log_file *elfrec, nfslog_LINK3args *args)
1039 {
1040 nfslog_fh3_print(elfrec, &args->file);
1041 nfslog_diropargs3_print(elfrec, &args->link);
1042 }
1043
1044 static void
nfslog_READDIRPLUS3args_print(struct nfsl_log_file * elfrec,nfslog_READDIRPLUS3args * args)1045 nfslog_READDIRPLUS3args_print(struct nfsl_log_file *elfrec,
1046 nfslog_READDIRPLUS3args *args)
1047 {
1048 nfslog_fh3_print(elfrec, &args->dir);
1049 elfrec->bufoffset += sprintf(&elfrec->buf[elfrec->bufoffset], " 0x%x",
1050 args->dircount);
1051 elfrec->bufoffset += sprintf(&elfrec->buf[elfrec->bufoffset], " 0x%x",
1052 args->maxcount);
1053 }
1054
1055 static void
nfslog_COMMIT3args_print(struct nfsl_log_file * elfrec,nfslog_COMMIT3args * args)1056 nfslog_COMMIT3args_print(struct nfsl_log_file *elfrec,
1057 nfslog_COMMIT3args *args)
1058 {
1059 nfslog_fh3_print(elfrec, &args->file);
1060 elfrec->bufoffset += sprintf(&elfrec->buf[elfrec->bufoffset], " 0x%llx",
1061 args->offset);
1062 elfrec->bufoffset += sprintf(&elfrec->buf[elfrec->bufoffset], " 0x%x",
1063 args->count);
1064 }
1065
1066 static void
nfslog_nfsstat3_print(struct nfsl_log_file * elfrec,enum nfsstat3 * res,bool_t print_status)1067 nfslog_nfsstat3_print(struct nfsl_log_file *elfrec, enum nfsstat3 *res,
1068 bool_t print_status)
1069 {
1070 if (print_status) {
1071 char *statp = nfslog_get_status((short)(*res));
1072
1073 if (statp != NULL)
1074 elfrec->bufoffset +=
1075 sprintf(&elfrec->buf[elfrec->bufoffset], " %s",
1076 statp);
1077 else
1078 elfrec->bufoffset +=
1079 sprintf(&elfrec->buf[elfrec->bufoffset], " %5d",
1080 *res);
1081 }
1082 }
1083
1084 static void
nfslog_LOOKUP3res_print(struct nfsl_log_file * elfrec,nfslog_LOOKUP3res * res,bool_t print_status)1085 nfslog_LOOKUP3res_print(struct nfsl_log_file *elfrec,
1086 nfslog_LOOKUP3res *res, bool_t print_status)
1087 {
1088 if (print_status) {
1089 nfslog_nfsstat3_print(elfrec, &res->status, print_status);
1090 } else if (res->status == NFS3_OK) {
1091 nfslog_fh3_print(elfrec, &res->nfslog_LOOKUP3res_u.object);
1092 }
1093 }
1094
1095 static void
nfslog_READLINK3res_print(struct nfsl_log_file * elfrec,nfslog_READLINK3res * res,bool_t print_status)1096 nfslog_READLINK3res_print(struct nfsl_log_file *elfrec,
1097 nfslog_READLINK3res *res, bool_t print_status)
1098 {
1099 if (print_status) {
1100 nfslog_nfsstat3_print(elfrec, &res->status, print_status);
1101 } else if (res->status == NFS3_OK) {
1102 elfrec->bufoffset += sprintf(&elfrec->buf[elfrec->bufoffset],
1103 " %s", res->nfslog_READLINK3res_u.data);
1104 }
1105 }
1106
1107 static void
nfslog_READ3res_print(struct nfsl_log_file * elfrec,nfslog_READ3res * res,bool_t print_status)1108 nfslog_READ3res_print(struct nfsl_log_file *elfrec, nfslog_READ3res *res,
1109 bool_t print_status)
1110 {
1111 if (print_status) {
1112 nfslog_nfsstat3_print(elfrec, &res->status, print_status);
1113 } else if (res->status == NFS3_OK) {
1114 char *elfbuf = elfrec->buf;
1115 int elfbufoffset = elfrec->bufoffset;
1116
1117 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " 0x%llx",
1118 res->nfslog_READ3res_u.ok.filesize);
1119 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " 0x%x",
1120 res->nfslog_READ3res_u.ok.count);
1121 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " 0x%x",
1122 res->nfslog_READ3res_u.ok.eof);
1123 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " 0x%x",
1124 res->nfslog_READ3res_u.ok.size);
1125 elfrec->bufoffset = elfbufoffset;
1126 }
1127 }
1128
1129 static void
nfslog_WRITE3res_print(struct nfsl_log_file * elfrec,nfslog_WRITE3res * res,bool_t print_status)1130 nfslog_WRITE3res_print(struct nfsl_log_file *elfrec, nfslog_WRITE3res *res,
1131 bool_t print_status)
1132 {
1133 if (print_status) {
1134 nfslog_nfsstat3_print(elfrec, &res->status, print_status);
1135 } else if (res->status == NFS3_OK) {
1136 char *elfbuf = elfrec->buf;
1137 int elfbufoffset = elfrec->bufoffset;
1138
1139 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " 0x%llx",
1140 res->nfslog_WRITE3res_u.ok.filesize);
1141 elfbufoffset += sprintf(&elfbuf[elfbufoffset],
1142 " 0x%x", res->nfslog_WRITE3res_u.ok.count);
1143 elfbufoffset += sprintf(&elfrec->buf[elfbufoffset],
1144 " 0x%x", res->nfslog_WRITE3res_u.ok.committed);
1145 elfrec->bufoffset = elfbufoffset;
1146 }
1147 }
1148
1149 static void
nfslog_CREATE3res_print(struct nfsl_log_file * elfrec,nfslog_CREATE3res * res,bool_t print_status)1150 nfslog_CREATE3res_print(struct nfsl_log_file *elfrec, nfslog_CREATE3res *res,
1151 bool_t print_status)
1152 {
1153 if (print_status) {
1154 nfslog_nfsstat3_print(elfrec, &res->status, print_status);
1155 } else if (res->status == NFS3_OK) {
1156 if (res->nfslog_CREATE3res_u.ok.obj.handle_follows) {
1157 nfslog_fh3_print(elfrec,
1158 &res->nfslog_CREATE3res_u.ok.obj.handle);
1159 }
1160 }
1161 }
1162
1163 static void
nfslog_MKDIR3res_print(struct nfsl_log_file * elfrec,nfslog_MKDIR3res * res,bool_t print_status)1164 nfslog_MKDIR3res_print(struct nfsl_log_file *elfrec, nfslog_MKDIR3res *res,
1165 bool_t print_status)
1166 {
1167 if (print_status) {
1168 nfslog_nfsstat3_print(elfrec, &res->status, print_status);
1169 } else if (res->status == NFS3_OK) {
1170 if (res->nfslog_MKDIR3res_u.obj.handle_follows) {
1171 nfslog_fh3_print(elfrec,
1172 &res->nfslog_MKDIR3res_u.obj.handle);
1173 }
1174 }
1175 }
1176
1177 static void
nfslog_SYMLINK3res_print(struct nfsl_log_file * elfrec,nfslog_SYMLINK3res * res,bool_t print_status)1178 nfslog_SYMLINK3res_print(struct nfsl_log_file *elfrec, nfslog_SYMLINK3res *res,
1179 bool_t print_status)
1180 {
1181 if (print_status) {
1182 nfslog_nfsstat3_print(elfrec, &res->status, print_status);
1183 } else if (res->status == NFS3_OK) {
1184 if (res->nfslog_SYMLINK3res_u.obj.handle_follows) {
1185 nfslog_fh3_print(elfrec,
1186 &res->nfslog_SYMLINK3res_u.obj.handle);
1187 }
1188 }
1189 }
1190
1191 static void
nfslog_MKNOD3res_print(struct nfsl_log_file * elfrec,nfslog_MKNOD3res * res,bool_t print_status)1192 nfslog_MKNOD3res_print(struct nfsl_log_file *elfrec, nfslog_MKNOD3res *res,
1193 bool_t print_status)
1194 {
1195 if (print_status) {
1196 nfslog_nfsstat3_print(elfrec, &res->status, print_status);
1197 } else if (res->status == NFS3_OK) {
1198 if (res->nfslog_MKNOD3res_u.obj.handle_follows) {
1199 nfslog_fh3_print(elfrec,
1200 &res->nfslog_MKNOD3res_u.obj.handle);
1201 }
1202 }
1203 }
1204
1205 static void
nfslog_READDIRPLUS3res_print(struct nfsl_log_file * elfrec,nfslog_READDIRPLUS3res * res,bool_t print_status)1206 nfslog_READDIRPLUS3res_print(struct nfsl_log_file *elfrec,
1207 nfslog_READDIRPLUS3res *res, bool_t print_status)
1208 {
1209 if (print_status) {
1210 nfslog_nfsstat3_print(elfrec, &res->status, print_status);
1211 }
1212 }
1213
1214 /*
1215 * **** End of table functions for logging specific procs ****
1216 *
1217 * Hereafter are the general logging management and dispatcher.
1218 */
1219
1220
1221 /*
1222 * nfsl_ipaddr_print - extracts sender ip address from transport struct
1223 * and prints it in legible form.
1224 */
1225 static void
nfsl_ipaddr_print(struct nfsl_log_file * elfrec,struct netbuf * ptr)1226 nfsl_ipaddr_print(struct nfsl_log_file *elfrec, struct netbuf *ptr)
1227 {
1228 struct hostent *hp;
1229 extern char *inet_ntop();
1230 int size, sin_family, error;
1231 char *elfbuf = elfrec->buf;
1232 char *addrp;
1233 int elfbufoffset = elfrec->bufoffset;
1234
1235 if (ptr->len == 0) {
1236 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " %s",
1237 empty_name);
1238 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " %s",
1239 empty_name);
1240 elfrec->bufoffset = elfbufoffset;
1241 return;
1242 }
1243 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " ");
1244 /* LINTED */
1245 sin_family = ((struct sockaddr_in *)ptr->buf)->sin_family;
1246 switch (sin_family) {
1247 case (AF_INET):
1248 /* LINTED */
1249 addrp = (char *)&((struct sockaddr_in *)ptr->buf)->sin_addr;
1250 size = sizeof (struct in_addr);
1251 break;
1252 case (AF_INET6):
1253 /* LINTED */
1254 addrp = (char *)&((struct sockaddr_in6 *)ptr->buf)->sin6_addr;
1255 size = sizeof (struct in6_addr);
1256 break;
1257 default:
1258 /* unknown protocol: print address in hex form */
1259 for (size = ptr->len, addrp = ptr->buf; size > 0; size--) {
1260 elfbufoffset += sprintf(&elfbuf[elfbufoffset], "%02x",
1261 *addrp);
1262 }
1263 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " %s",
1264 empty_name);
1265 elfrec->bufoffset = elfbufoffset;
1266 return;
1267 }
1268 if (inet_ntop(sin_family, addrp, &elfbuf[elfbufoffset],
1269 (size_t)(DFLT_BUFFERSIZE + DFLT_OVFSIZE - elfbufoffset))
1270 == NULL) {
1271 /* Not enough space to print - should never happen */
1272 elfbuf[elfrec->bufoffset] = '\0'; /* just in case */
1273 return;
1274 }
1275 /* inet_ntop copied address into elfbuf, so update offset */
1276 elfbufoffset += strlen(&elfbuf[elfbufoffset]);
1277 /* get host name and log it as well */
1278 hp = getipnodebyaddr(addrp, size, sin_family, &error);
1279 if (hp != NULL) {
1280 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " \"%s\"",
1281 hp->h_name);
1282 } else {
1283 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " %s",
1284 empty_name);
1285 }
1286 elfrec->bufoffset = elfbufoffset;
1287 }
1288
1289 static void
nfsl_elf_record_header_print(struct nfsl_log_file * elfrec,nfslog_record_header * lhp,char * principal_name,char * tag,struct nfsl_proc_disp * disp,char * progname)1290 nfsl_elf_record_header_print(struct nfsl_log_file *elfrec,
1291 nfslog_record_header *lhp, char *principal_name, char *tag,
1292 struct nfsl_proc_disp *disp, char *progname)
1293 {
1294 struct passwd *pwp = NULL;
1295 char *elfbuf = elfrec->buf;
1296 int elfbufoffset = elfrec->bufoffset;
1297
1298 /*
1299 * Fields: time bytes tag rpc-program rpc-version rpc-procedure
1300 * auth-flavor s-user-name s-uid uid u-name gid net-id
1301 * c-ip c-dns s-dns status rpcarg-path <arguments> <response>
1302 */
1303 elfbufoffset += sprintf(&elfbuf[elfbufoffset], "%s",
1304 nfsl_get_time((time_t)lhp->rh_timestamp.tv_sec));
1305 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " 0x%x",
1306 lhp->rh_reclen);
1307 if ((tag != NULL) && (tag[0] != '\0')) {
1308 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " \"%s\"", tag);
1309 } else {
1310 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " %s",
1311 empty_name);
1312 }
1313 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " %s 0x%x %s",
1314 progname, lhp->rh_version, disp->procname);
1315 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " %s",
1316 NFSL_AUTH_FLAVOR_PRINT(lhp->rh_auth_flavor));
1317 if ((principal_name != NULL) && (principal_name[0] != '\0')) {
1318 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " \"%s\"",
1319 principal_name);
1320 if ((pwp = getpwnam(principal_name)) != NULL) {
1321 elfbufoffset += sprintf(&elfbuf[elfbufoffset],
1322 " 0x%lx", pwp->pw_uid);
1323 } else {
1324 elfbufoffset += sprintf(&elfbuf[elfbufoffset],
1325 " %s", empty_name);
1326 }
1327 } else {
1328 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " %s",
1329 empty_name);
1330 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " %s",
1331 empty_name);
1332 }
1333 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " 0x%lx", lhp->rh_uid);
1334 if (((pwp = getpwuid(lhp->rh_uid)) != NULL) && (pwp->pw_name != NULL)) {
1335 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " \"%s\"",
1336 pwp->pw_name);
1337 } else {
1338 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " %s",
1339 empty_name);
1340 }
1341 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " 0x%lx", lhp->rh_gid);
1342 elfrec->bufoffset = elfbufoffset;
1343 }
1344
1345 static void
nfsl_elf_buffer_header_print(struct nfsl_log_file * elfrec,nfslog_buffer_header * bufhdr)1346 nfsl_elf_buffer_header_print(struct nfsl_log_file *elfrec,
1347 nfslog_buffer_header *bufhdr)
1348 {
1349 int rc;
1350 struct utsname name;
1351 char *elfbuf = elfrec->buf;
1352 int elfbufoffset = elfrec->bufoffset;
1353
1354 rc = uname(&name);
1355 elfbufoffset += sprintf(&elfbuf[elfbufoffset],
1356 "#Version %d.0\n#Software \"%s\"\n",
1357 bufhdr->bh_version, ((rc >= 0) ? name.sysname : empty_name));
1358 elfbufoffset += sprintf(&elfbuf[elfbufoffset], "#Date %s\n",
1359 nfsl_get_date((time_t)bufhdr->bh_timestamp.tv_sec));
1360 elfbufoffset += sprintf(&elfbuf[elfbufoffset], "#Remark %s\n",
1361 empty_name);
1362 elfbufoffset += sprintf(&elfbuf[elfbufoffset],
1363 "#Fields: time bytes tag");
1364 elfbufoffset += sprintf(&elfbuf[elfbufoffset],
1365 " rpc-program rpc-version rpc-procedure");
1366 elfbufoffset += sprintf(&elfbuf[elfbufoffset],
1367 " auth-flavor s-user-name s-uid uid u-name gid net-id c-ip");
1368 elfbufoffset += sprintf(&elfbuf[elfbufoffset],
1369 " c-dns s-dns status rpcarg-path");
1370 elfbufoffset += sprintf(&elfbuf[elfbufoffset],
1371 " rpc-arguments... rpc-response...\n");
1372 elfrec->bufoffset = elfbufoffset;
1373 }
1374
1375 /*
1376 * nfsl_find_elf_dispatch - get the dispatch struct for this request
1377 */
1378 static struct nfsl_proc_disp *
nfsl_find_elf_dispatch(nfslog_request_record * logrec,char ** prognamep)1379 nfsl_find_elf_dispatch(nfslog_request_record *logrec, char **prognamep)
1380 {
1381 nfslog_record_header *logrechdr = &logrec->re_header;
1382 struct nfsl_prog_disp *progtable; /* prog struct */
1383 struct nfsl_vers_disp *verstable; /* version struct */
1384 int i, vers;
1385
1386 /* Find prog element - search because can't use prog as array index */
1387 for (i = 0; (i < nfsl_elf_dispatch_table_arglen) &&
1388 (logrechdr->rh_prognum != nfsl_elf_dispatch_table[i].nfsl_dis_prog);
1389 i++);
1390 if (i >= nfsl_elf_dispatch_table_arglen) { /* program not logged */
1391 /* not an error */
1392 return (NULL);
1393 }
1394 progtable = &nfsl_elf_dispatch_table[i];
1395 /* Find vers element - no validity check - if here it's valid vers */
1396 vers = logrechdr->rh_version - progtable->nfsl_dis_versmin;
1397 verstable = &progtable->nfsl_dis_vers_table[vers];
1398 /* Find proc element - no validity check - if here it's valid proc */
1399 *prognamep = progtable->progname;
1400 return (&verstable->nfsl_dis_proc_table[logrechdr->rh_procnum]);
1401 }
1402
1403 /*
1404 * nfsl_elf_rpc_print - Print the record buffer.
1405 */
1406 static void
nfsl_elf_rpc_print(struct nfsl_log_file * elfrec,nfslog_request_record * logrec,struct nfsl_proc_disp * disp,char * progname,char * path1,char * path2)1407 nfsl_elf_rpc_print(struct nfsl_log_file *elfrec,
1408 nfslog_request_record *logrec, struct nfsl_proc_disp *disp,
1409 char *progname, char *path1, char *path2)
1410 {
1411 if (debug > 1) {
1412 (void) printf("%s %d %s", progname,
1413 logrec->re_header.rh_version, disp->procname);
1414 (void) printf(": '%s', '%s'\n",
1415 ((path1 != NULL) ? path1 : empty_name),
1416 ((path2 != NULL) ? path2 : empty_name));
1417 }
1418 /*
1419 * XXXX programs using this file to get a usable record should
1420 * take "record" struct.
1421 */
1422 /*
1423 * Print the variable fields:
1424 * principal name
1425 * netid
1426 * ip address
1427 * rpc args
1428 * rpc res
1429 * Use the displacements calculated earlier...
1430 */
1431
1432 /*
1433 * Fields: time bytes tag rpc-program rpc-version rpc-procedure
1434 * auth-flavor s-user-name s-uid uid u-name gid net-id c-ip
1435 * c-dns s-dns status rpcarg-path <arguments> <response>
1436 */
1437 nfsl_elf_record_header_print(elfrec, &logrec->re_header,
1438 logrec->re_principal_name, logrec->re_tag,
1439 disp, progname);
1440 if ((logrec->re_netid != NULL) && (logrec->re_netid[0] != '\0')) {
1441 elfrec->bufoffset += sprintf(&elfrec->buf[elfrec->bufoffset],
1442 " \"%s\"", logrec->re_netid);
1443 } else {
1444 elfrec->bufoffset += sprintf(&elfrec->buf[elfrec->bufoffset],
1445 " %s", empty_name);
1446 }
1447 nfsl_ipaddr_print(elfrec, &logrec->re_ipaddr);
1448 elfrec->bufoffset += sprintf(&elfrec->buf[elfrec->bufoffset],
1449 " \"%s\"", hostname);
1450 /* Next is return status */
1451 (*disp->nfsl_dis_res)(elfrec, logrec->re_rpc_res, TRUE);
1452 /* Next is argpath */
1453 if (path1 != NULL) {
1454 elfrec->bufoffset += sprintf(&elfrec->buf[elfrec->bufoffset],
1455 " \"%s\"", path1);
1456 } else {
1457 elfrec->bufoffset += sprintf(&elfrec->buf[elfrec->bufoffset],
1458 " %s", empty_name);
1459 }
1460 /*
1461 * path2 is non-empty for rename/link type operations. If it is non-
1462 * empty print it here as it's a part of the args
1463 */
1464 if (path2 != NULL) {
1465 elfrec->bufoffset += sprintf(&elfrec->buf[elfrec->bufoffset],
1466 " \"%s\"", path2);
1467 }
1468 /* Next print formatted rpc args */
1469 (*disp->nfsl_dis_args)(elfrec, logrec->re_rpc_arg);
1470 /* Next print formatted rpc res (minus status) */
1471 (*disp->nfsl_dis_res)(elfrec, logrec->re_rpc_res, FALSE);
1472 elfrec->bufoffset += sprintf(&elfrec->buf[elfrec->bufoffset], "\n");
1473 }
1474
1475 /*
1476 * nfsl_log_file_add - add a new record to the list
1477 */
1478 static void
nfsl_log_file_add(struct nfsl_log_file * elfrec,struct nfsl_log_file ** elf_listp)1479 nfsl_log_file_add(struct nfsl_log_file *elfrec,
1480 struct nfsl_log_file **elf_listp)
1481 {
1482 elfrec->next = *elf_listp;
1483 elfrec->prev = NULL;
1484 if (*elf_listp != NULL) {
1485 (*elf_listp)->prev = elfrec;
1486 }
1487 *elf_listp = elfrec;
1488 }
1489
1490 /*
1491 * nfsl_log_file_find - finds a record in the list, given a cookie (== elfrec)
1492 * Returns the record.
1493 */
1494 static struct nfsl_log_file *
nfsl_log_file_find(struct nfsl_log_file * elfrec,struct nfsl_log_file * elf_list)1495 nfsl_log_file_find(struct nfsl_log_file *elfrec,
1496 struct nfsl_log_file *elf_list)
1497 {
1498 struct nfsl_log_file *rec;
1499
1500 for (rec = elf_list; (rec != NULL) && (rec != elfrec);
1501 rec = rec->next);
1502 return (rec);
1503 }
1504
1505 /*
1506 * nfsl_log_file_del - delete a record from the list, does not free rec.
1507 * Returns the deleted record.
1508 */
1509 static struct nfsl_log_file *
nfsl_log_file_del(struct nfsl_log_file * elfrec,struct nfsl_log_file ** elf_listp)1510 nfsl_log_file_del(struct nfsl_log_file *elfrec,
1511 struct nfsl_log_file **elf_listp)
1512 {
1513 struct nfsl_log_file *rec;
1514
1515 if ((rec = nfsl_log_file_find(elfrec, *elf_listp)) == NULL) {
1516 return (NULL);
1517 }
1518 if (rec->prev != NULL) {
1519 rec->prev->next = rec->next;
1520 } else {
1521 *elf_listp = rec->next;
1522 }
1523 if (rec->next != NULL) {
1524 rec->next->prev = rec->prev;
1525 }
1526 return (rec);
1527 }
1528
1529 /*
1530 * nfsl_log_file_free - frees a record
1531 */
1532 static void
nfsl_log_file_free(struct nfsl_log_file * elfrec)1533 nfsl_log_file_free(struct nfsl_log_file *elfrec)
1534 {
1535 if (elfrec == NULL)
1536 return;
1537 if (elfrec->path != NULL)
1538 free(elfrec->path);
1539 if (elfrec->buf != NULL)
1540 free(elfrec->buf);
1541 free(elfrec);
1542 }
1543
1544 /*
1545 * Exported Functions
1546 */
1547
1548 /*
1549 * nfslog_open_elf_file - open the output elf file and mallocs needed buffers
1550 * Returns a pointer to the nfsl_log_file on success, NULL on error.
1551 *
1552 * *error contains the last error encountered on this object, It can
1553 * be used to avoid reporting the same error endlessly, by comparing
1554 * the current error to the last error. It is reset to the current error
1555 * code on return.
1556 */
1557 void *
nfslog_open_elf_file(char * elfpath,nfslog_buffer_header * bufhdr,int * error)1558 nfslog_open_elf_file(char *elfpath, nfslog_buffer_header *bufhdr, int *error)
1559 {
1560 struct nfsl_log_file *elfrec;
1561 struct stat stat_buf;
1562 int preverror = *error;
1563
1564 if ((elfrec = malloc(sizeof (*elfrec))) == NULL) {
1565 *error = errno;
1566 if (*error != preverror) {
1567 syslog(LOG_ERR, gettext("nfslog_open_elf_file: %s"),
1568 strerror(*error));
1569 }
1570 return (NULL);
1571 }
1572 bzero(elfrec, sizeof (*elfrec));
1573
1574 elfrec->buf = (char *)malloc(DFLT_BUFFERSIZE + DFLT_OVFSIZE);
1575 if (elfrec->buf == NULL) {
1576 *error = errno;
1577 if (*error != preverror) {
1578 syslog(LOG_ERR, gettext("nfslog_open_elf_file: %s"),
1579 strerror(*error));
1580 }
1581 nfsl_log_file_free(elfrec);
1582 return (NULL);
1583 }
1584
1585 if ((elfrec->path = strdup(elfpath)) == NULL) {
1586 *error = errno;
1587 if (*error != preverror) {
1588 syslog(LOG_ERR, gettext("nfslog_open_elf_file: %s"),
1589 strerror(*error));
1590 }
1591 nfsl_log_file_free(elfrec);
1592 return (NULL);
1593 }
1594
1595 if ((elfrec->fp = fopen(elfpath, "a")) == NULL) {
1596 *error = errno;
1597 if (*error != preverror) {
1598 syslog(LOG_ERR, gettext("Cannot open '%s': %s"),
1599 elfpath, strerror(*error));
1600 }
1601 nfsl_log_file_free(elfrec);
1602 return (NULL);
1603 }
1604
1605 if (stat(elfpath, &stat_buf) == -1) {
1606 *error = errno;
1607 if (*error != preverror) {
1608 syslog(LOG_ERR, gettext("Cannot stat '%s': %s"),
1609 elfpath, strerror(*error));
1610 }
1611 (void) fclose(elfrec->fp);
1612 nfsl_log_file_free(elfrec);
1613 return (NULL);
1614 }
1615
1616 nfsl_log_file_add(elfrec, &elf_file_list);
1617
1618 if (stat_buf.st_size == 0) {
1619 /*
1620 * Print header unto logfile
1621 */
1622 nfsl_elf_buffer_header_print(elfrec, bufhdr);
1623 }
1624
1625 if (hostname[0] == '\0') {
1626 (void) gethostname(hostname, MAXHOSTNAMELEN);
1627 }
1628
1629 return (elfrec);
1630 }
1631
1632 /*
1633 * nfslog_close_elf_file - close elffile and write out last buffer
1634 */
1635 void
nfslog_close_elf_file(void ** elfcookie)1636 nfslog_close_elf_file(void **elfcookie)
1637 {
1638 struct nfsl_log_file *elfrec;
1639
1640 if ((*elfcookie == NULL) || ((elfrec = nfsl_log_file_del(
1641 *elfcookie, &elf_file_list)) == NULL)) {
1642 *elfcookie = NULL;
1643 return;
1644 }
1645 if (elfrec->fp != NULL) {
1646 /* Write the last output buffer to disk */
1647 (void) nfsl_write_elfbuf(elfrec);
1648 (void) fclose(elfrec->fp);
1649 }
1650 nfsl_log_file_free(elfrec);
1651 *elfcookie = NULL;
1652 }
1653
1654 /*
1655 * nfslog_process_elf_rec - processes the record in the buffer and outputs
1656 * to the elf log.
1657 * Return 0 for success, errno else.
1658 */
1659 int
nfslog_process_elf_rec(void * elfcookie,nfslog_request_record * logrec,char * path1,char * path2)1660 nfslog_process_elf_rec(void *elfcookie, nfslog_request_record *logrec,
1661 char *path1, char *path2)
1662 {
1663 struct nfsl_log_file *elfrec;
1664 struct nfsl_proc_disp *disp;
1665 char *progname;
1666
1667 if ((elfrec = nfsl_log_file_find(elfcookie, elf_file_list)) == NULL) {
1668 return (EINVAL);
1669 }
1670 /* Make sure there is room */
1671 if (elfrec->bufoffset > DFLT_BUFFERSIZE) {
1672 if (nfsl_write_elfbuf(elfrec) < 0) {
1673 return (errno);
1674 }
1675 }
1676 if ((disp = nfsl_find_elf_dispatch(logrec, &progname)) != NULL) {
1677 nfsl_elf_rpc_print(elfrec, logrec, disp, progname,
1678 path1, path2);
1679 }
1680 return (0);
1681 }
1682