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