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, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /*
23 * Copyright (c) 1999 by Sun Microsystems, Inc.
24 * All rights reserved.
25 */
26
27 #include <stdio.h>
28 #include <errno.h>
29 #include <malloc.h>
30 #include <strings.h>
31 #include <stddef.h>
32 #include <search.h>
33 #include <syslog.h>
34 #include <libintl.h>
35 #include <unistd.h>
36 #include <rpc/rpc.h>
37 #include <netconfig.h>
38 #include <netdir.h>
39 #include <nfs/nfs_sec.h>
40 #include <nfs/export.h>
41 #include <rpc/auth.h>
42 #include <rpc/svc.h>
43 #include <rpc/xdr.h>
44 #include <rpc/clnt.h>
45 #include <nfs/nfs.h>
46 #include <nfs/nfs_log.h>
47 #include <assert.h>
48 #include "fhtab.h"
49 #include "nfslogd.h"
50
51 /*
52 * How long should an entry stay in the list before being forced
53 * out and a trans log entry printed
54 */
55 #define TRANS_ENTRY_TIMEOUT 60
56
57 extern char *addrtoname(void *);
58
59 struct transentry {
60 struct transentry *next;
61 struct transentry *prev;
62 timestruc32_t starttime; /* when did transaction start? */
63 timestruc32_t lastupdate; /* last operation for this entry */
64 #define TRANS_OPER_READ 1
65 #define TRANS_OPER_WRITE 2
66 #define TRANS_OPER_SETATTR 3
67 #define TRANS_OPER_REMOVE 4
68 #define TRANS_OPER_MKDIR 5
69 #define TRANS_OPER_CREATE 6
70 #define TRANS_OPER_RMDIR 7
71 #define TRANS_OPER_RENAME 8
72 #define TRANS_OPER_MKNOD 9
73 #define TRANS_OPER_LINK 10
74 #define TRANS_OPER_SYMLINK 11
75 uchar_t optype; /* read, write, ...? */
76 #define TRANS_DATATYPE_NA /* not applicable data type */
77 #define TRANS_DATATYPE_ASCII 0 /* transfer done as ascii */
78 #define TRANS_DATATYPE_BINARY 1 /* transfer done as binary */
79 uchar_t datatype;
80 /*
81 * Action taken by server before transfer was made -- noaction,
82 * compressed, tar or uncompressed.
83 */
84 #define TRANS_OPTION_NOACTION 0
85 uchar_t transoption;
86 char *pathname;
87 struct netbuf *pnb;
88 uid_t uid;
89 int nfsvers;
90 char *netid;
91 char *principal_name;
92 uint64_t totalbytes; /* total operated upon in history */
93 union {
94 fhandle_t fh;
95 nfs_fh3 fh3;
96 } fh_u;
97 };
98
99 struct nfslog_trans_file {
100 struct nfslog_trans_file *next; /* next file in list */
101 struct nfslog_trans_file *prev; /* next file in list */
102 int refcnt; /* number of references to this struct */
103 char *path; /* pathname of file */
104 FILE *fp; /* file pointer */
105 /* timestamp of the last transaction processed for this file */
106 timestruc32_t lasttrans_timestamp;
107 /* 'current' time that last trans was processed */
108 time_t last_trans_read;
109 uint32_t trans_to_log; /* transactions that are to be logged */
110 uint32_t trans_output_type;
111 struct transentry *te_list_v3_read;
112 struct transentry *te_list_v3_write;
113 struct transentry *te_list_v2_read;
114 struct transentry *te_list_v2_write;
115 };
116
117 static struct nfslog_trans_file *trans_file_head = NULL;
118
119 static void nfslog_print_trans_logentry(struct transentry *,
120 struct nfslog_trans_file *);
121
122
123 static struct netbuf *
netbufdup(struct netbuf * pnb)124 netbufdup(struct netbuf *pnb)
125 {
126 struct netbuf *pnewnb;
127 uint32_t size;
128
129 size = offsetof(struct netbuf, buf);
130 size += pnb->len;
131
132 if ((pnewnb = (struct netbuf *)malloc(sizeof (*pnewnb))) == NULL)
133 return (NULL);
134 if ((pnewnb->buf = malloc(pnb->len)) == NULL) {
135 free(pnewnb);
136 return (NULL);
137 }
138
139 pnewnb->maxlen = pnb->maxlen;
140 pnewnb->len = pnb->len;
141 bcopy(pnb->buf, pnewnb->buf, pnb->len);
142 return (pnewnb);
143 }
144
145 static void
freenetbuf(struct netbuf * pnb)146 freenetbuf(struct netbuf *pnb)
147 {
148 free(pnb->buf);
149 free(pnb);
150 }
151
152 static struct transentry *
create_te()153 create_te()
154 {
155 struct transentry *pte;
156
157 if ((pte = (struct transentry *)calloc(1, sizeof (*pte))) == NULL) {
158 /* failure message or action */
159 return (NULL);
160 }
161
162 pte->next = pte->prev = NULL;
163
164 return (pte);
165 }
166
167 static struct transentry *
insert_te(struct transentry * te_list,struct transentry * entry)168 insert_te(
169 struct transentry *te_list,
170 struct transentry *entry)
171 {
172 struct transentry *pte;
173
174 /*
175 * First check for any non-filehandle comparisons that may be needed.
176 */
177 switch (entry->optype) {
178 case TRANS_OPER_REMOVE:
179 case TRANS_OPER_RENAME:
180 for (pte = te_list->next; pte != te_list; pte = pte->next) {
181 /* if path names match, then return */
182 if (strcmp(pte->pathname, entry->pathname) == 0) {
183 return (pte);
184 }
185 }
186 return (NULL);
187 default:
188 break;
189 }
190
191 for (pte = te_list->next; pte != te_list; pte = pte->next) {
192 /* If the file handles match, then we have a hit */
193 if (entry->nfsvers == NFS_VERSION) {
194 if (bcmp(&(pte->fh_u.fh), &(entry->fh_u.fh),
195 sizeof (fhandle_t)) == 0) {
196 switch (entry->optype) {
197 case TRANS_OPER_READ:
198 case TRANS_OPER_WRITE:
199 if (pte->uid == entry->uid) {
200 return (pte);
201 }
202 break;
203 default:
204 return (pte);
205 }
206 }
207 } else {
208 if (pte->fh_u.fh3.fh3_length ==
209 entry->fh_u.fh3.fh3_length &&
210 bcmp(pte->fh_u.fh3.fh3_u.data,
211 entry->fh_u.fh3.fh3_u.data,
212 pte->fh_u.fh3.fh3_length) == 0)
213 switch (entry->optype) {
214 case TRANS_OPER_READ:
215 case TRANS_OPER_WRITE:
216 if (pte->uid == entry->uid) {
217 return (pte);
218 }
219 break;
220 default:
221 return (pte);
222 }
223 }
224 }
225 /*
226 * XXX - should compare more of the information to make sure
227 * it is a match.
228 */
229
230 /*
231 * other operation types do not generate an entry for
232 * further analysis
233 */
234 switch (entry->optype) {
235 case TRANS_OPER_READ:
236 case TRANS_OPER_WRITE:
237 break;
238 default:
239 return (NULL);
240 }
241
242 insque(entry, te_list);
243
244 return (NULL); /* NULL signifies insertion and no record found */
245 }
246
247 static void
remove_te(struct transentry * pte)248 remove_te(struct transentry *pte)
249 {
250 if (pte->next)
251 remque(pte);
252
253 if (pte->principal_name) free(pte->principal_name);
254 if (pte->pathname) free(pte->pathname);
255 if (pte->pnb) freenetbuf(pte->pnb);
256 if (pte->netid) free(pte->netid);
257
258 free(pte);
259 }
260
261 /*
262 * nfslog_trans_file_free - frees a record
263 */
264 static void
nfslog_trans_file_free(struct nfslog_trans_file * transrec)265 nfslog_trans_file_free(struct nfslog_trans_file *transrec)
266 {
267 if (transrec == NULL)
268 return;
269 if (transrec->path != NULL) {
270 if (debug)
271 (void) printf("freeing transpath '%s'\n",
272 transrec->path);
273 free(transrec->path);
274 }
275 free(transrec);
276 }
277
278 /*
279 * On success returns a pointer to the trans_file that matches
280 * 'path', 'output_type' and 'transtolog'. The reference count for this
281 * object is incremented as well.
282 * Returns NULL if it is not in the list.
283 */
284 static struct nfslog_trans_file *
nfslog_trans_file_find(char * path,uint32_t output_type,uint32_t transtolog)285 nfslog_trans_file_find(
286 char *path,
287 uint32_t output_type,
288 uint32_t transtolog)
289 {
290 struct nfslog_trans_file *tfp;
291
292 for (tfp = trans_file_head; tfp != NULL; tfp = tfp->next) {
293 if ((strcmp(path, tfp->path) == 0) &&
294 (output_type == tfp->trans_output_type) &&
295 (transtolog == tfp->trans_to_log)) {
296 if (debug)
297 (void) printf("Found transfile '%s'\n", path);
298 (tfp->refcnt)++;
299 return (tfp);
300 }
301 }
302 return (NULL);
303 }
304
305
306 /*
307 * nfslog_close_trans_file - decrements the reference count on
308 * this object. On last reference it closes transfile and
309 * frees resources
310 */
311 static void
nfslog_close_trans_file(struct nfslog_trans_file * tf)312 nfslog_close_trans_file(struct nfslog_trans_file *tf)
313 {
314 assert(tf != NULL);
315 assert(tf->refcnt > 0);
316 if (tf->refcnt > 1) {
317 (tf->refcnt)--;
318 return;
319 }
320
321 if (tf->fp != NULL) {
322 (void) fsync(fileno(tf->fp));
323 (void) fclose(tf->fp);
324 }
325
326 /*
327 * Disconnect from list
328 */
329 tf->prev->next = tf->next;
330 if (tf->next != NULL)
331 tf->next->prev = tf->prev;
332
333 /*
334 * Adjust the head of the list if appropriate
335 */
336 if (tf == trans_file_head)
337 trans_file_head = tf->next;
338
339 nfslog_trans_file_free(tf);
340 }
341
342 /*
343 * nfslog_open_trans_file - open the output trans file and mallocs.
344 * The object is then inserted at the beginning of the global
345 * transfile list.
346 * Returns 0 for success, error else.
347 *
348 * *error contains the last error encountered on this object. It can
349 * be used to avoid reporting the same error endlessly, by comparing
350 * the current error to the last error. It is reset to the current error
351 * code on return.
352 */
353 void *
nfslog_open_trans_file(char * transpath,uint32_t output_type,uint32_t transtolog,int * error)354 nfslog_open_trans_file(
355 char *transpath,
356 uint32_t output_type,
357 uint32_t transtolog,
358 int *error)
359 {
360 int preverror = *error;
361 struct nfslog_trans_file *transrec;
362
363 transrec = nfslog_trans_file_find(transpath, output_type, transtolog);
364 if (transrec != NULL)
365 return (transrec);
366
367 if ((transrec = malloc(sizeof (*transrec))) == NULL) {
368 *error = errno;
369 if (*error != preverror) {
370 syslog(LOG_ERR, gettext("nfslog_open_trans_file: %s"),
371 strerror(*error));
372 }
373 return (NULL);
374 }
375 bzero(transrec, sizeof (*transrec));
376
377 if ((transrec->path = strdup(transpath)) == NULL) {
378 *error = errno;
379 if (*error != preverror) {
380 syslog(LOG_ERR, gettext("nfslog_open_trans_file: %s"),
381 strerror(*error));
382 }
383 nfslog_trans_file_free(transrec);
384 return (NULL);
385 }
386
387 if ((transrec->fp = fopen(transpath, "a")) == NULL) {
388 *error = errno;
389 if (*error != preverror) {
390 syslog(LOG_ERR, gettext("Cannot open '%s': %s"),
391 transpath, strerror(*error));
392 }
393 nfslog_trans_file_free(transrec);
394 return (NULL);
395 }
396
397 transrec->te_list_v3_read =
398 (struct transentry *)malloc(sizeof (struct transentry));
399 transrec->te_list_v3_write =
400 (struct transentry *)malloc(sizeof (struct transentry));
401 transrec->te_list_v2_read =
402 (struct transentry *)malloc(sizeof (struct transentry));
403 transrec->te_list_v2_write =
404 (struct transentry *)malloc(sizeof (struct transentry));
405
406 if (transrec->te_list_v3_read == NULL ||
407 transrec->te_list_v3_write == NULL ||
408 transrec->te_list_v2_read == NULL ||
409 transrec->te_list_v2_write == NULL) {
410 if (transrec->te_list_v3_read)
411 free(transrec->te_list_v3_read);
412 if (transrec->te_list_v3_write)
413 free(transrec->te_list_v3_write);
414 if (transrec->te_list_v2_read)
415 free(transrec->te_list_v2_read);
416 if (transrec->te_list_v2_write)
417 free(transrec->te_list_v2_write);
418 nfslog_close_trans_file(transrec);
419 return (NULL);
420 }
421
422 transrec->te_list_v3_read->next =
423 transrec->te_list_v3_read->prev = transrec->te_list_v3_read;
424 transrec->te_list_v3_write->next =
425 transrec->te_list_v3_write->prev = transrec->te_list_v3_write;
426 transrec->te_list_v2_read->next =
427 transrec->te_list_v2_read->prev = transrec->te_list_v2_read;
428 transrec->te_list_v2_write->next =
429 transrec->te_list_v2_write->prev = transrec->te_list_v2_write;
430
431 /*
432 * Indicate what transaction types to log
433 */
434 transrec->trans_to_log = transtolog;
435
436 /*
437 * Indicate whether to print 'full' or 'basic' version
438 * of the transactions
439 */
440 transrec->trans_output_type = output_type;
441
442 /*
443 * Insert at the beginning of the list.
444 */
445 transrec->next = trans_file_head;
446 if (trans_file_head != NULL)
447 trans_file_head->prev = transrec;
448 trans_file_head = transrec->prev = transrec;
449
450 transrec->refcnt = 1;
451
452 transrec->lasttrans_timestamp.tv_sec = 0;
453 transrec->lasttrans_timestamp.tv_nsec = 0;
454 transrec->last_trans_read = time(0);
455
456 if (debug)
457 (void) printf("New transfile '%s'\n", transrec->path);
458
459 return (transrec);
460 }
461
462 void
nfslog_process_trans_timeout(struct nfslog_trans_file * tf,uint32_t force_flush)463 nfslog_process_trans_timeout(
464 struct nfslog_trans_file *tf,
465 uint32_t force_flush)
466 {
467 struct transentry *pte;
468 time_t cur_time = time(0);
469
470 /*
471 * If we have not seen a transaction on this file for
472 * a long time, then we need to flush everything out since
473 * we may not be getting anything else in for awhile.
474 */
475 if (difftime(cur_time, tf->last_trans_read) >
476 (2 * MAX(TRANS_ENTRY_TIMEOUT, idle_time)))
477 force_flush = TRUE;
478
479 restart1:
480 for (pte = tf->te_list_v3_read->next;
481 pte != tf->te_list_v3_read;
482 pte = pte->next) {
483 if (force_flush == TRUE ||
484 (difftime(tf->lasttrans_timestamp.tv_sec,
485 pte->lastupdate.tv_sec) >
486 MAX(TRANS_ENTRY_TIMEOUT, idle_time))) {
487 nfslog_print_trans_logentry(pte, tf);
488 remove_te(pte);
489 goto restart1;
490 }
491 }
492 restart2:
493 for (pte = tf->te_list_v3_write->next;
494 pte != tf->te_list_v3_write;
495 pte = pte->next) {
496 if (force_flush == TRUE ||
497 (difftime(tf->lasttrans_timestamp.tv_sec,
498 pte->lastupdate.tv_sec) >
499 MAX(TRANS_ENTRY_TIMEOUT, idle_time))) {
500 nfslog_print_trans_logentry(pte, tf);
501 remove_te(pte);
502 goto restart2;
503 }
504 }
505 restart3:
506 for (pte = tf->te_list_v2_read->next;
507 pte != tf->te_list_v2_read;
508 pte = pte->next) {
509 if (force_flush == TRUE ||
510 (difftime(tf->lasttrans_timestamp.tv_sec,
511 pte->lastupdate.tv_sec) >
512 MAX(TRANS_ENTRY_TIMEOUT, idle_time))) {
513 nfslog_print_trans_logentry(pte, tf);
514 remove_te(pte);
515 goto restart3;
516 }
517 }
518 restart4:
519 for (pte = tf->te_list_v2_write->next;
520 pte != tf->te_list_v2_write;
521 pte = pte->next) {
522 if (force_flush == TRUE ||
523 (difftime(tf->lasttrans_timestamp.tv_sec,
524 pte->lastupdate.tv_sec) >
525 MAX(TRANS_ENTRY_TIMEOUT, idle_time))) {
526 nfslog_print_trans_logentry(pte, tf);
527 remove_te(pte);
528 goto restart4;
529 }
530 }
531
532 (void) fflush(tf->fp);
533 }
534
535 /*
536 * Flushes outstanding transactions to disk, and closes
537 * the transaction log.
538 */
539 void
nfslog_close_transactions(void ** transcookie)540 nfslog_close_transactions(void **transcookie)
541 {
542 assert(*transcookie != NULL);
543 nfslog_process_trans_timeout(
544 (struct nfslog_trans_file *)(*transcookie), TRUE);
545 nfslog_close_trans_file((struct nfslog_trans_file *)(*transcookie));
546 *transcookie = NULL;
547 }
548
549 static struct transentry *
trans_read(nfslog_request_record * logrec,struct nfslog_trans_file * tf,char * fhpath,char * path1)550 trans_read(
551 nfslog_request_record *logrec,
552 struct nfslog_trans_file *tf,
553 char *fhpath,
554 char *path1)
555 {
556 struct transentry *newte;
557 struct transentry *pte = NULL;
558 /* LINTED */
559 nfslog_nfsreadargs *args = (nfslog_nfsreadargs *)logrec->re_rpc_arg;
560 /* LINTED */
561 nfslog_rdresult *res = (nfslog_rdresult *)logrec->re_rpc_res;
562
563 if (res->r_status != NFS_OK)
564 return (NULL);
565
566 if ((newte = create_te()) == NULL)
567 return (NULL);
568
569 if (!path1) {
570 newte->pathname = nfslog_get_path(&args->ra_fhandle,
571 NULL, fhpath, "trans_read");
572 } else {
573 newte->pathname = strdup(path1);
574 }
575
576 /* prep the struct for insertion */
577 newte->starttime = logrec->re_header.rh_timestamp;
578 newte->lastupdate = logrec->re_header.rh_timestamp;
579 newte->optype = TRANS_OPER_READ;
580 newte->datatype = TRANS_DATATYPE_BINARY;
581 newte->transoption = TRANS_OPTION_NOACTION;
582 newte->pnb = netbufdup(&(logrec->re_ipaddr));
583 newte->uid = logrec->re_header.rh_uid;
584 newte->nfsvers = NFS_VERSION;
585 newte->netid = strdup(logrec->re_netid);
586 if (logrec->re_principal_name)
587 newte->principal_name = strdup(logrec->re_principal_name);
588 else
589 newte->principal_name = NULL;
590 newte->totalbytes = res->nfslog_rdresult_u.r_ok.rrok_count;
591 newte->fh_u.fh = *(NFSLOG_GET_FHANDLE2(&args->ra_fhandle));
592
593 if (res->nfslog_rdresult_u.r_ok.rrok_count <
594 res->nfslog_rdresult_u.r_ok.filesize) {
595 if (pte = insert_te(tf->te_list_v2_read, newte)) {
596 /* free this since entry was found (not inserted) */
597 remove_te(newte);
598
599 pte->totalbytes +=
600 res->nfslog_rdresult_u.r_ok.rrok_count;
601
602 if (pte->lastupdate.tv_sec <=
603 logrec->re_header.rh_timestamp.tv_sec)
604 pte->lastupdate =
605 logrec->re_header.rh_timestamp;
606
607 if (pte->totalbytes <
608 res->nfslog_rdresult_u.r_ok.filesize) {
609 pte = NULL; /* prevent printing of log entry */
610 }
611 }
612 } else {
613 pte = newte; /* print a log record - complete file read */
614 }
615
616 return (pte);
617 }
618
619 static struct transentry *
trans_write(nfslog_request_record * logrec,struct nfslog_trans_file * tf,char * fhpath,char * path1)620 trans_write(
621 nfslog_request_record *logrec,
622 struct nfslog_trans_file *tf,
623 char *fhpath,
624 char *path1)
625 {
626 struct transentry *newte;
627 struct transentry *pte = NULL;
628 /* LINTED */
629 nfslog_writeargs *args = (nfslog_writeargs *)logrec->re_rpc_arg;
630 /* LINTED */
631 nfslog_writeresult *res = (nfslog_writeresult *)logrec->re_rpc_res;
632
633 if (res->wr_status != NFS_OK)
634 return (NULL);
635
636 if ((newte = create_te()) == NULL)
637 return (NULL);
638
639 if (!path1) {
640 newte->pathname = nfslog_get_path(&args->waargs_fhandle,
641 NULL, fhpath, "trans_write");
642 } else {
643 newte->pathname = strdup(path1);
644 }
645
646 newte->starttime = logrec->re_header.rh_timestamp;
647 newte->lastupdate = logrec->re_header.rh_timestamp;
648 newte->optype = TRANS_OPER_WRITE;
649 newte->datatype = TRANS_DATATYPE_BINARY;
650 newte->transoption = TRANS_OPTION_NOACTION;
651 newte->pnb = netbufdup(&(logrec->re_ipaddr));
652 newte->uid = logrec->re_header.rh_uid;
653 newte->nfsvers = NFS_VERSION;
654 newte->netid = strdup(logrec->re_netid);
655 if (logrec->re_principal_name)
656 newte->principal_name = strdup(logrec->re_principal_name);
657 else
658 newte->principal_name = NULL;
659 newte->totalbytes = args->waargs_totcount;
660 newte->fh_u.fh = *(NFSLOG_GET_FHANDLE2(&args->waargs_fhandle));
661
662 if (pte = insert_te(tf->te_list_v2_write, newte)) {
663 /*
664 * if the write would have increased the total byte count
665 * over the filesize, then generate a log entry and remove
666 * the write record and insert the new one.
667 */
668 if (pte->totalbytes + args->waargs_totcount >
669 res->nfslog_writeresult_u.wr_size) {
670 nfslog_print_trans_logentry(pte, tf);
671 remove_te(pte);
672 (void) insert_te(tf->te_list_v2_write, newte);
673 pte = NULL;
674 } else {
675 /* free this since entry was found (not inserted) */
676 remove_te(newte);
677
678 pte->totalbytes += args->waargs_totcount;
679
680 if (pte->lastupdate.tv_sec <=
681 logrec->re_header.rh_timestamp.tv_sec) {
682 pte->lastupdate =
683 logrec->re_header.rh_timestamp;
684 }
685 pte = NULL; /* prevent printing of log entry */
686 }
687 }
688 return (pte);
689 }
690
691 static struct transentry *
trans_setattr(nfslog_request_record * logrec,struct nfslog_trans_file * tf,char * fhpath,char * path1)692 trans_setattr(
693 nfslog_request_record *logrec,
694 struct nfslog_trans_file *tf,
695 char *fhpath,
696 char *path1)
697 {
698 struct transentry *newte;
699 struct transentry *pte = NULL;
700 /* LINTED */
701 nfslog_setattrargs *args = (nfslog_setattrargs *)logrec->re_rpc_arg;
702 /* LINTED */
703 nfsstat *res = (nfsstat *)logrec->re_rpc_res;
704
705 if (*res != NFS_OK)
706 return (NULL);
707
708 if (args->saa_sa.sa_size == (uint32_t)-1)
709 return (NULL);
710 /*
711 * should check the size of the file to see if it
712 * is being truncated below current eof. if so
713 * a record should be generated.... XXX
714 */
715 if (args->saa_sa.sa_size != 0)
716 return (NULL);
717
718 if ((newte = create_te()) == NULL)
719 return (NULL);
720
721 if (!path1) {
722 newte->pathname = nfslog_get_path(&args->saa_fh, NULL,
723 fhpath, "trans_setattr2");
724 } else {
725 newte->pathname = strdup(path1);
726 }
727
728 newte->starttime = logrec->re_header.rh_timestamp;
729 newte->lastupdate = logrec->re_header.rh_timestamp;
730 newte->optype = TRANS_OPER_SETATTR;
731 newte->datatype = TRANS_DATATYPE_BINARY;
732 newte->transoption = TRANS_OPTION_NOACTION;
733 newte->pnb = netbufdup(&(logrec->re_ipaddr));
734 newte->uid = logrec->re_header.rh_uid;
735 newte->nfsvers = NFS_VERSION;
736 newte->netid = strdup(logrec->re_netid);
737 if (logrec->re_principal_name)
738 newte->principal_name = strdup(logrec->re_principal_name);
739 else
740 newte->principal_name = NULL;
741 newte->totalbytes = 0;
742 newte->fh_u.fh = *(NFSLOG_GET_FHANDLE2(&args->saa_fh));
743
744 if (pte = insert_te(tf->te_list_v2_write, newte)) {
745 nfslog_print_trans_logentry(pte, tf);
746 remove_te(pte);
747 }
748 if (pte = insert_te(tf->te_list_v2_read, newte)) {
749 nfslog_print_trans_logentry(pte, tf);
750 remove_te(pte);
751 }
752
753 return (newte);
754 }
755
756 static struct transentry *
trans_create(nfslog_request_record * logrec,struct nfslog_trans_file * tf,char * fhpath,char * path1)757 trans_create(
758 nfslog_request_record *logrec,
759 struct nfslog_trans_file *tf,
760 char *fhpath,
761 char *path1)
762 {
763 struct transentry *newte;
764 struct transentry *pte = NULL;
765 /* LINTED */
766 nfslog_createargs *args = (nfslog_createargs *)logrec->re_rpc_arg;
767 /* LINTED */
768 nfslog_diropres *res = (nfslog_diropres *)logrec->re_rpc_res;
769
770 if (res->dr_status != NFS_OK)
771 return (NULL);
772
773 if ((newte = create_te()) == NULL)
774 return (NULL);
775
776 if (!path1) {
777 newte->pathname =
778 nfslog_get_path(&args->ca_da.da_fhandle,
779 args->ca_da.da_name,
780 fhpath, "trans_create2");
781 } else {
782 newte->pathname = strdup(path1);
783 }
784
785 newte->starttime = logrec->re_header.rh_timestamp;
786 newte->lastupdate = logrec->re_header.rh_timestamp;
787 newte->optype = TRANS_OPER_CREATE;
788 newte->datatype = TRANS_DATATYPE_BINARY;
789 newte->transoption = TRANS_OPTION_NOACTION;
790 newte->pnb = netbufdup(&(logrec->re_ipaddr));
791 newte->uid = logrec->re_header.rh_uid;
792 newte->nfsvers = NFS_VERSION;
793 newte->netid = strdup(logrec->re_netid);
794 if (logrec->re_principal_name)
795 newte->principal_name = strdup(logrec->re_principal_name);
796 else
797 newte->principal_name = NULL;
798
799 if (args->ca_sa.sa_size == (uint32_t)-1)
800 newte->totalbytes = 0;
801 else
802 newte->totalbytes = args->ca_sa.sa_size;
803
804 newte->fh_u.fh = *(NFSLOG_GET_FHANDLE2(
805 &res->nfslog_diropres_u.dr_ok.drok_fhandle));
806
807 /*
808 * if the file is being truncated on create, we need to flush
809 * any outstanding read/write transactions
810 */
811 if (args->ca_sa.sa_size != (uint32_t)-1) {
812 if (pte = insert_te(tf->te_list_v2_write, newte)) {
813 nfslog_print_trans_logentry(pte, tf);
814 remove_te(pte);
815 }
816 if (pte = insert_te(tf->te_list_v2_read, newte)) {
817 nfslog_print_trans_logentry(pte, tf);
818 remove_te(pte);
819 }
820 }
821
822 return (newte);
823 }
824
825 static struct transentry *
trans_remove(nfslog_request_record * logrec,struct nfslog_trans_file * tf,char * fhpath,char * path1)826 trans_remove(
827 nfslog_request_record *logrec,
828 struct nfslog_trans_file *tf,
829 char *fhpath,
830 char *path1)
831 {
832 struct transentry *newte;
833 struct transentry *pte = NULL;
834 /* LINTED */
835 nfslog_diropargs *args = (nfslog_diropargs *)logrec->re_rpc_arg;
836 /* LINTED */
837 nfsstat *res = (nfsstat *)logrec->re_rpc_res;
838
839 if (*res != NFS_OK)
840 return (NULL);
841
842 if ((newte = create_te()) == NULL)
843 return (NULL);
844
845 if (!path1) {
846 char *name = args->da_name;
847 fhandle_t *dfh = &args->da_fhandle;
848 newte->pathname = nfslog_get_path(dfh, name,
849 fhpath, "trans_remove2");
850 } else {
851 newte->pathname = strdup(path1);
852 }
853
854 newte->starttime = logrec->re_header.rh_timestamp;
855 newte->lastupdate = logrec->re_header.rh_timestamp;
856 newte->optype = TRANS_OPER_REMOVE;
857 newte->datatype = TRANS_DATATYPE_BINARY;
858 newte->transoption = TRANS_OPTION_NOACTION;
859 newte->pnb = netbufdup(&(logrec->re_ipaddr));
860 newte->uid = logrec->re_header.rh_uid;
861 newte->nfsvers = NFS_VERSION;
862 newte->netid = strdup(logrec->re_netid);
863 if (logrec->re_principal_name)
864 newte->principal_name = strdup(logrec->re_principal_name);
865 else
866 newte->principal_name = NULL;
867 newte->totalbytes = 0;
868 newte->fh_u.fh = *(NFSLOG_GET_FHANDLE2(&args->da_fhandle));
869
870 if (pte = insert_te(tf->te_list_v2_write, newte)) {
871 nfslog_print_trans_logentry(pte, tf);
872 remove_te(pte);
873 }
874 if (pte = insert_te(tf->te_list_v2_read, newte)) {
875 nfslog_print_trans_logentry(pte, tf);
876 remove_te(pte);
877 }
878 if (pte = insert_te(tf->te_list_v3_write, newte)) {
879 nfslog_print_trans_logentry(pte, tf);
880 remove_te(pte);
881 }
882 if (pte = insert_te(tf->te_list_v3_read, newte)) {
883 nfslog_print_trans_logentry(pte, tf);
884 remove_te(pte);
885 }
886
887 return (newte);
888 }
889
890 static struct transentry *
trans_mkdir(nfslog_request_record * logrec,char * fhpath,char * path1)891 trans_mkdir(
892 nfslog_request_record *logrec,
893 char *fhpath,
894 char *path1)
895 {
896 struct transentry *newte;
897 /* LINTED */
898 nfslog_createargs *args = (nfslog_createargs *)logrec->re_rpc_arg;
899 /* LINTED */
900 nfslog_diropres *res = (nfslog_diropres *)logrec->re_rpc_res;
901
902 if (res->dr_status != NFS_OK)
903 return (NULL);
904
905 if ((newte = create_te()) == NULL)
906 return (NULL);
907
908 if (!path1) {
909 nfslog_diropargs *dargs = &args->ca_da;
910 char *name = dargs->da_name;
911 fhandle_t *dfh = &dargs->da_fhandle;
912 newte->pathname = nfslog_get_path(dfh, name,
913 fhpath, "trans_mkdir2");
914 } else {
915 newte->pathname = strdup(path1);
916 }
917
918 newte->starttime = logrec->re_header.rh_timestamp;
919 newte->lastupdate = logrec->re_header.rh_timestamp;
920 newte->optype = TRANS_OPER_MKDIR;
921 newte->datatype = TRANS_DATATYPE_BINARY;
922 newte->transoption = TRANS_OPTION_NOACTION;
923 newte->pnb = netbufdup(&(logrec->re_ipaddr));
924 newte->uid = logrec->re_header.rh_uid;
925 newte->nfsvers = NFS_VERSION;
926 newte->netid = strdup(logrec->re_netid);
927 if (logrec->re_principal_name)
928 newte->principal_name = strdup(logrec->re_principal_name);
929 else
930 newte->principal_name = NULL;
931 newte->totalbytes = 0;
932 newte->fh_u.fh = *(NFSLOG_GET_FHANDLE2(&args->ca_da.da_fhandle));
933
934 return (newte);
935 }
936
937 static struct transentry *
trans_rmdir(nfslog_request_record * logrec,char * fhpath,char * path1)938 trans_rmdir(
939 nfslog_request_record *logrec,
940 char *fhpath,
941 char *path1)
942 {
943 struct transentry *newte;
944 /* LINTED */
945 nfslog_diropargs *args = (nfslog_diropargs *)logrec->re_rpc_arg;
946 /* LINTED */
947 nfsstat *res = (nfsstat *)logrec->re_rpc_res;
948
949 if (*res != NFS_OK)
950 return (NULL);
951
952 if ((newte = create_te()) == NULL)
953 return (NULL);
954
955 if (!path1) {
956 char *name = args->da_name;
957 fhandle_t *dfh = &args->da_fhandle;
958 newte->pathname = nfslog_get_path(dfh, name,
959 fhpath, "trans_rmdir2");
960 } else {
961 newte->pathname = strdup(path1);
962 }
963
964 newte->starttime = logrec->re_header.rh_timestamp;
965 newte->lastupdate = logrec->re_header.rh_timestamp;
966 newte->optype = TRANS_OPER_RMDIR;
967 newte->datatype = TRANS_DATATYPE_BINARY;
968 newte->transoption = TRANS_OPTION_NOACTION;
969 newte->pnb = netbufdup(&(logrec->re_ipaddr));
970 newte->uid = logrec->re_header.rh_uid;
971 newte->nfsvers = NFS_VERSION;
972 newte->netid = strdup(logrec->re_netid);
973 if (logrec->re_principal_name)
974 newte->principal_name = strdup(logrec->re_principal_name);
975 else
976 newte->principal_name = NULL;
977 newte->totalbytes = 0;
978 newte->fh_u.fh = *(NFSLOG_GET_FHANDLE2(&args->da_fhandle));
979
980 return (newte);
981 }
982
983 static struct transentry *
trans_rename(nfslog_request_record * logrec,struct nfslog_trans_file * tf,char * fhpath,char * path1,char * path2)984 trans_rename(
985 nfslog_request_record *logrec,
986 struct nfslog_trans_file *tf,
987 char *fhpath,
988 char *path1,
989 char *path2)
990 {
991 struct transentry *newte;
992 struct transentry *pte = NULL;
993 /* LINTED */
994 nfslog_rnmargs *args = (nfslog_rnmargs *)logrec->re_rpc_arg;
995 /* LINTED */
996 nfsstat *res = (nfsstat *)logrec->re_rpc_res;
997 char *tpath1 = NULL;
998 char *tpath2 = NULL;
999
1000 if (*res != NFS_OK)
1001 return (NULL);
1002
1003 if ((newte = create_te()) == NULL)
1004 return (NULL);
1005
1006 if (!path1) {
1007 char *from_name, *to_name;
1008 fhandle_t *from_dfh, *to_dfh;
1009
1010 from_name = args->rna_from.da_name;
1011 from_dfh = &args->rna_from.da_fhandle;
1012 to_name = args->rna_to.da_name;
1013 to_dfh = &args->rna_to.da_fhandle;
1014
1015 path1 = tpath1 = nfslog_get_path(from_dfh, from_name,
1016 fhpath, "trans_rename from");
1017 path2 = tpath2 = nfslog_get_path(to_dfh, to_name,
1018 fhpath, "trans_rename to");
1019 }
1020
1021 newte->pathname = path1; /* no need to strdup here */
1022 newte->starttime = logrec->re_header.rh_timestamp;
1023 newte->lastupdate = logrec->re_header.rh_timestamp;
1024 newte->optype = TRANS_OPER_RENAME;
1025 newte->datatype = TRANS_DATATYPE_BINARY;
1026 newte->transoption = TRANS_OPTION_NOACTION;
1027 newte->pnb = netbufdup(&(logrec->re_ipaddr));
1028 newte->uid = logrec->re_header.rh_uid;
1029 newte->nfsvers = NFS_VERSION;
1030 newte->netid = strdup(logrec->re_netid);
1031 if (logrec->re_principal_name)
1032 newte->principal_name = strdup(logrec->re_principal_name);
1033 else
1034 newte->principal_name = NULL;
1035 newte->totalbytes = 0;
1036 newte->fh_u.fh = *(NFSLOG_GET_FHANDLE2(&args->rna_from.da_fhandle));
1037
1038 /* switch path names for the file for renames */
1039 if (pte = insert_te(tf->te_list_v2_write, newte)) {
1040 free(pte->pathname);
1041 pte->pathname = strdup(path2);
1042 }
1043 if (pte = insert_te(tf->te_list_v2_read, newte)) {
1044 free(pte->pathname);
1045 pte->pathname = strdup(path2);
1046 }
1047 if (pte = insert_te(tf->te_list_v3_write, newte)) {
1048 free(pte->pathname);
1049 pte->pathname = strdup(path2);
1050 }
1051 if (pte = insert_te(tf->te_list_v3_read, newte)) {
1052 free(pte->pathname);
1053 pte->pathname = strdup(path2);
1054 }
1055
1056 newte->pathname = (char *)malloc(strlen(path1) + strlen(path2) + 3);
1057 /* check for NULL malloc */
1058 (void) sprintf(newte->pathname, "%s->%s", path1, path2);
1059
1060 if (tpath1) {
1061 free(tpath1);
1062 free(tpath2);
1063 }
1064
1065 return (newte);
1066 }
1067
1068 static struct transentry *
trans_link(nfslog_request_record * logrec,char * fhpath,char * path1,char * path2)1069 trans_link(
1070 nfslog_request_record *logrec,
1071 char *fhpath,
1072 char *path1,
1073 char *path2)
1074 {
1075 struct transentry *newte;
1076 /* LINTED */
1077 nfslog_linkargs *args = (nfslog_linkargs *)logrec->re_rpc_arg;
1078 /* LINTED */
1079 nfsstat *res = (nfsstat *)logrec->re_rpc_res;
1080 char *tpath1 = NULL;
1081 char *tpath2 = NULL;
1082
1083 if (*res != NFS_OK)
1084 return (NULL);
1085
1086 if ((newte = create_te()) == NULL)
1087 return (NULL);
1088
1089 if (!path1) {
1090 fhandle_t *fh = &args->la_from;
1091 char *name = args->la_to.da_name;
1092 fhandle_t *dfh = &args->la_to.da_fhandle;
1093
1094 path1 = tpath1 = nfslog_get_path(fh, NULL,
1095 fhpath, "trans_link from");
1096 path2 = tpath2 = nfslog_get_path(dfh, name,
1097 fhpath, "trans_link to");
1098 }
1099
1100 newte->starttime = logrec->re_header.rh_timestamp;
1101 newte->lastupdate = logrec->re_header.rh_timestamp;
1102 newte->optype = TRANS_OPER_LINK;
1103 newte->datatype = TRANS_DATATYPE_BINARY;
1104 newte->transoption = TRANS_OPTION_NOACTION;
1105 newte->pnb = netbufdup(&(logrec->re_ipaddr));
1106 newte->uid = logrec->re_header.rh_uid;
1107 newte->nfsvers = NFS_VERSION;
1108 newte->netid = strdup(logrec->re_netid);
1109 if (logrec->re_principal_name)
1110 newte->principal_name = strdup(logrec->re_principal_name);
1111 else
1112 newte->principal_name = NULL;
1113 newte->totalbytes = 0;
1114 newte->fh_u.fh = *(NFSLOG_GET_FHANDLE2(&args->la_from));
1115
1116 newte->pathname = (char *)malloc(strlen(path1) + strlen(path2) + 3);
1117 /* check for NULL malloc */
1118 (void) sprintf(newte->pathname, "%s->%s", path1, path2);
1119
1120 if (tpath1) {
1121 free(tpath1);
1122 free(tpath2);
1123 }
1124
1125 return (newte);
1126 }
1127
1128 static struct transentry *
trans_symlink(nfslog_request_record * logrec,char * fhpath,char * path1)1129 trans_symlink(
1130 nfslog_request_record *logrec,
1131 char *fhpath,
1132 char *path1)
1133 {
1134 struct transentry *newte;
1135 /* LINTED */
1136 nfslog_symlinkargs *args = (nfslog_symlinkargs *)logrec->re_rpc_arg;
1137 /* LINTED */
1138 nfsstat *res = (nfsstat *)logrec->re_rpc_res;
1139 char *tpath1 = NULL;
1140
1141 if (*res != NFS_OK)
1142 return (NULL);
1143
1144 if ((newte = create_te()) == NULL)
1145 return (NULL);
1146
1147 if (!path1) {
1148 char *name = args->sla_from.da_name;
1149 fhandle_t *dfh = &args->sla_from.da_fhandle;
1150
1151 path1 = tpath1 = nfslog_get_path(dfh, name,
1152 fhpath, "trans_symlink");
1153 }
1154
1155 newte->starttime = logrec->re_header.rh_timestamp;
1156 newte->lastupdate = logrec->re_header.rh_timestamp;
1157 newte->optype = TRANS_OPER_SYMLINK;
1158 newte->datatype = TRANS_DATATYPE_BINARY;
1159 newte->transoption = TRANS_OPTION_NOACTION;
1160 newte->pnb = netbufdup(&(logrec->re_ipaddr));
1161 newte->uid = logrec->re_header.rh_uid;
1162 newte->nfsvers = NFS_VERSION;
1163 newte->netid = strdup(logrec->re_netid);
1164 if (logrec->re_principal_name)
1165 newte->principal_name = strdup(logrec->re_principal_name);
1166 else
1167 newte->principal_name = NULL;
1168 newte->totalbytes = 0;
1169 newte->fh_u.fh = *(NFSLOG_GET_FHANDLE2(&args->sla_from.da_fhandle));
1170
1171 newte->pathname = (char *)malloc(strlen(path1) +
1172 strlen(args->sla_tnm) + 3);
1173 (void) sprintf(newte->pathname, "%s->%s", path1, args->sla_tnm);
1174
1175 if (tpath1)
1176 free(tpath1);
1177
1178 return (newte);
1179 }
1180
1181 static struct transentry *
trans_read3(nfslog_request_record * logrec,struct nfslog_trans_file * tf,char * fhpath,char * path1)1182 trans_read3(
1183 nfslog_request_record *logrec,
1184 struct nfslog_trans_file *tf,
1185 char *fhpath,
1186 char *path1)
1187 {
1188 struct transentry *newte;
1189 struct transentry *pte = NULL;
1190 /* LINTED */
1191 nfslog_READ3args *args = (nfslog_READ3args *)logrec->re_rpc_arg;
1192 /* LINTED */
1193 nfslog_READ3res *res = (nfslog_READ3res *)logrec->re_rpc_res;
1194
1195 if (res->status != NFS3_OK)
1196 return (NULL);
1197
1198 if ((newte = create_te()) == NULL)
1199 return (NULL);
1200
1201 if (!path1) {
1202 fhandle_t *fh = NFSLOG_GET_FHANDLE3(&args->file);
1203 newte->pathname = nfslog_get_path(fh, NULL,
1204 fhpath, "trans_read3");
1205 } else {
1206 newte->pathname = strdup(path1);
1207 }
1208
1209 /* prep the struct for insertion */
1210 newte->starttime = logrec->re_header.rh_timestamp;
1211 newte->lastupdate = logrec->re_header.rh_timestamp;
1212 newte->optype = TRANS_OPER_READ;
1213 newte->datatype = TRANS_DATATYPE_BINARY;
1214 newte->transoption = TRANS_OPTION_NOACTION;
1215 newte->pnb = netbufdup(&(logrec->re_ipaddr));
1216 newte->uid = logrec->re_header.rh_uid;
1217 newte->nfsvers = NFS_V3;
1218 newte->netid = strdup(logrec->re_netid);
1219 if (logrec->re_principal_name)
1220 newte->principal_name = strdup(logrec->re_principal_name);
1221 else
1222 newte->principal_name = NULL;
1223 newte->totalbytes = res->nfslog_READ3res_u.ok.count;
1224 newte->fh_u.fh3 = args->file;
1225
1226 if (res->nfslog_READ3res_u.ok.count <
1227 res->nfslog_READ3res_u.ok.filesize) {
1228 if (pte = insert_te(tf->te_list_v3_read, newte)) {
1229 /* free this since entry was found (not inserted) */
1230 remove_te(newte);
1231
1232 pte->totalbytes += res->nfslog_READ3res_u.ok.count;
1233
1234 if (pte->lastupdate.tv_sec <=
1235 logrec->re_header.rh_timestamp.tv_sec)
1236 pte->lastupdate =
1237 logrec->re_header.rh_timestamp;
1238
1239 if (pte->totalbytes <
1240 res->nfslog_READ3res_u.ok.filesize) {
1241 pte = NULL; /* prevent printing of log entry */
1242 }
1243 }
1244 } else {
1245 pte = newte; /* print a log record - complete file read */
1246 }
1247
1248 return (pte);
1249 }
1250
1251 static struct transentry *
trans_write3(nfslog_request_record * logrec,struct nfslog_trans_file * tf,char * fhpath,char * path1)1252 trans_write3(
1253 nfslog_request_record *logrec,
1254 struct nfslog_trans_file *tf,
1255 char *fhpath,
1256 char *path1)
1257 {
1258 struct transentry *newte;
1259 struct transentry *pte = NULL;
1260 /* LINTED */
1261 nfslog_WRITE3args *args = (nfslog_WRITE3args *)logrec->re_rpc_arg;
1262 /* LINTED */
1263 nfslog_WRITE3res *res = (nfslog_WRITE3res *)logrec->re_rpc_res;
1264
1265 if (res->status != NFS3_OK)
1266 return (NULL);
1267
1268 if ((newte = create_te()) == NULL)
1269 return (NULL);
1270
1271 if (!path1) {
1272 fhandle_t *fh = NFSLOG_GET_FHANDLE3(&args->file);
1273 newte->pathname = nfslog_get_path(fh, NULL,
1274 fhpath, "trans_write3");
1275 } else {
1276 newte->pathname = strdup(path1);
1277 }
1278
1279 newte->starttime = logrec->re_header.rh_timestamp;
1280 newte->lastupdate = logrec->re_header.rh_timestamp;
1281 newte->optype = TRANS_OPER_WRITE;
1282 newte->datatype = TRANS_DATATYPE_BINARY;
1283 newte->transoption = TRANS_OPTION_NOACTION;
1284 newte->pnb = netbufdup(&(logrec->re_ipaddr));
1285 newte->uid = logrec->re_header.rh_uid;
1286 newte->nfsvers = NFS_V3;
1287 newte->netid = strdup(logrec->re_netid);
1288 if (logrec->re_principal_name)
1289 newte->principal_name = strdup(logrec->re_principal_name);
1290 else
1291 newte->principal_name = NULL;
1292 newte->totalbytes = res->nfslog_WRITE3res_u.ok.count;
1293 newte->fh_u.fh3 = args->file;
1294
1295 if (pte = insert_te(tf->te_list_v3_write, newte)) {
1296 /*
1297 * if the write would have increased the total byte count
1298 * over the filesize, then generate a log entry and remove
1299 * the write record and insert the new one.
1300 */
1301 if (pte->totalbytes + res->nfslog_WRITE3res_u.ok.count >
1302 res->nfslog_WRITE3res_u.ok.filesize) {
1303 nfslog_print_trans_logentry(pte, tf);
1304 remove_te(pte);
1305 (void) insert_te(tf->te_list_v3_write, newte);
1306 pte = NULL;
1307 } else {
1308 /* free this since entry was found (not inserted) */
1309 remove_te(newte);
1310
1311 pte->totalbytes += res->nfslog_WRITE3res_u.ok.count;
1312
1313 if (pte->lastupdate.tv_sec <=
1314 logrec->re_header.rh_timestamp.tv_sec) {
1315 pte->lastupdate =
1316 logrec->re_header.rh_timestamp;
1317 }
1318 pte = NULL; /* prevent printing of log entry */
1319 }
1320 }
1321 return (pte);
1322 }
1323
1324 static struct transentry *
trans_setattr3(nfslog_request_record * logrec,struct nfslog_trans_file * tf,char * fhpath,char * path1)1325 trans_setattr3(
1326 nfslog_request_record *logrec,
1327 struct nfslog_trans_file *tf,
1328 char *fhpath,
1329 char *path1)
1330 {
1331 struct transentry *newte;
1332 struct transentry *pte = NULL;
1333 /* LINTED */
1334 nfslog_SETATTR3args *args = (nfslog_SETATTR3args *)logrec->re_rpc_arg;
1335 /* LINTED */
1336 nfsstat3 *res = (nfsstat3 *)logrec->re_rpc_res;
1337
1338 if (*res != NFS3_OK)
1339 return (NULL);
1340
1341 if (!args->size.set_it)
1342 return (NULL);
1343 /*
1344 * should check the size of the file to see if it
1345 * is being truncated below current eof. if so
1346 * a record should be generated.... XXX
1347 */
1348 if (args->size.size != 0)
1349 return (NULL);
1350
1351 if ((newte = create_te()) == NULL)
1352 return (NULL);
1353
1354 if (!path1) {
1355 fhandle_t *fh = NFSLOG_GET_FHANDLE3(&args->object);
1356 newte->pathname = nfslog_get_path(fh, NULL,
1357 fhpath, "trans_setattr3");
1358 } else {
1359 newte->pathname = strdup(path1);
1360 }
1361
1362 newte->starttime = logrec->re_header.rh_timestamp;
1363 newte->lastupdate = logrec->re_header.rh_timestamp;
1364 newte->optype = TRANS_OPER_SETATTR;
1365 newte->datatype = TRANS_DATATYPE_BINARY;
1366 newte->transoption = TRANS_OPTION_NOACTION;
1367 newte->pnb = netbufdup(&(logrec->re_ipaddr));
1368 newte->uid = logrec->re_header.rh_uid;
1369 newte->nfsvers = NFS_V3;
1370 newte->netid = strdup(logrec->re_netid);
1371 if (logrec->re_principal_name)
1372 newte->principal_name = strdup(logrec->re_principal_name);
1373 else
1374 newte->principal_name = NULL;
1375 newte->totalbytes = 0;
1376 newte->fh_u.fh3 = args->object;
1377
1378 if (pte = insert_te(tf->te_list_v3_write, newte)) {
1379 nfslog_print_trans_logentry(pte, tf);
1380 remove_te(pte);
1381 }
1382 if (pte = insert_te(tf->te_list_v3_read, newte)) {
1383 nfslog_print_trans_logentry(pte, tf);
1384 remove_te(pte);
1385 }
1386
1387 return (newte);
1388 }
1389
1390 static struct transentry *
trans_create3(nfslog_request_record * logrec,struct nfslog_trans_file * tf,char * fhpath,char * path1)1391 trans_create3(
1392 nfslog_request_record *logrec,
1393 struct nfslog_trans_file *tf,
1394 char *fhpath,
1395 char *path1)
1396 {
1397 struct transentry *newte;
1398 struct transentry *pte = NULL;
1399 /* LINTED */
1400 nfslog_CREATE3args *args = (nfslog_CREATE3args *)logrec->re_rpc_arg;
1401 /* LINTED */
1402 nfslog_CREATE3res *res = (nfslog_CREATE3res *)logrec->re_rpc_res;
1403
1404 if (res->status != NFS3_OK)
1405 return (NULL);
1406
1407 if ((newte = create_te()) == NULL)
1408 return (NULL);
1409
1410 if (!path1) {
1411 newte->pathname =
1412 nfslog_get_path(NFSLOG_GET_FHANDLE3(&args->where.dir),
1413 args->where.name,
1414 fhpath, "trans_create3");
1415 } else {
1416 newte->pathname = strdup(path1);
1417 }
1418
1419 newte->starttime = logrec->re_header.rh_timestamp;
1420 newte->lastupdate = logrec->re_header.rh_timestamp;
1421 newte->optype = TRANS_OPER_CREATE;
1422 newte->datatype = TRANS_DATATYPE_BINARY;
1423 newte->transoption = TRANS_OPTION_NOACTION;
1424 newte->pnb = netbufdup(&(logrec->re_ipaddr));
1425 newte->uid = logrec->re_header.rh_uid;
1426 newte->nfsvers = NFS_V3;
1427 newte->netid = strdup(logrec->re_netid);
1428 if (logrec->re_principal_name)
1429 newte->principal_name = strdup(logrec->re_principal_name);
1430 else
1431 newte->principal_name = NULL;
1432
1433 if (!args->how.nfslog_createhow3_u.size.set_it)
1434 newte->totalbytes = 0;
1435 else
1436 newte->totalbytes =
1437 args->how.nfslog_createhow3_u.size.size;
1438
1439 newte->fh_u.fh3 = args->where.dir;
1440
1441 if (args->how.nfslog_createhow3_u.size.set_it) {
1442 if (pte = insert_te(tf->te_list_v3_write, newte)) {
1443 nfslog_print_trans_logentry(pte, tf);
1444 remove_te(pte);
1445 }
1446 if (pte = insert_te(tf->te_list_v3_read, newte)) {
1447 nfslog_print_trans_logentry(pte, tf);
1448 remove_te(pte);
1449 }
1450 }
1451
1452 return (newte);
1453 }
1454
1455 static struct transentry *
trans_remove3(nfslog_request_record * logrec,struct nfslog_trans_file * tf,char * fhpath,char * path1)1456 trans_remove3(
1457 nfslog_request_record *logrec,
1458 struct nfslog_trans_file *tf,
1459 char *fhpath,
1460 char *path1)
1461 {
1462 struct transentry *newte;
1463 struct transentry *pte = NULL;
1464 /* LINTED */
1465 nfslog_REMOVE3args *args = (nfslog_REMOVE3args *)logrec->re_rpc_arg;
1466 /* LINTED */
1467 nfsstat3 *res = (nfsstat3 *)logrec->re_rpc_res;
1468
1469 if (*res != NFS3_OK)
1470 return (NULL);
1471
1472 if ((newte = create_te()) == NULL)
1473 return (NULL);
1474
1475 if (!path1) {
1476 newte->pathname =
1477 nfslog_get_path(NFSLOG_GET_FHANDLE3(&args->object.dir),
1478 args->object.name,
1479 fhpath, "trans_remove3");
1480 } else {
1481 newte->pathname = strdup(path1);
1482 }
1483
1484 newte->starttime = logrec->re_header.rh_timestamp;
1485 newte->lastupdate = logrec->re_header.rh_timestamp;
1486 newte->optype = TRANS_OPER_REMOVE;
1487 newte->datatype = TRANS_DATATYPE_BINARY;
1488 newte->transoption = TRANS_OPTION_NOACTION;
1489 newte->pnb = netbufdup(&(logrec->re_ipaddr));
1490 newte->uid = logrec->re_header.rh_uid;
1491 newte->nfsvers = NFS_V3;
1492 newte->netid = strdup(logrec->re_netid);
1493 if (logrec->re_principal_name)
1494 newte->principal_name = strdup(logrec->re_principal_name);
1495 else
1496 newte->principal_name = NULL;
1497 newte->totalbytes = 0;
1498 newte->fh_u.fh3 = args->object.dir;
1499
1500 if (pte = insert_te(tf->te_list_v3_write, newte)) {
1501 nfslog_print_trans_logentry(pte, tf);
1502 remove_te(pte);
1503 }
1504 if (pte = insert_te(tf->te_list_v3_read, newte)) {
1505 nfslog_print_trans_logentry(pte, tf);
1506 remove_te(pte);
1507 }
1508 if (pte = insert_te(tf->te_list_v2_write, newte)) {
1509 nfslog_print_trans_logentry(pte, tf);
1510 remove_te(pte);
1511 }
1512 if (pte = insert_te(tf->te_list_v2_read, newte)) {
1513 nfslog_print_trans_logentry(pte, tf);
1514 remove_te(pte);
1515 }
1516
1517 return (newte);
1518 }
1519
1520 static struct transentry *
trans_mkdir3(nfslog_request_record * logrec,char * fhpath,char * path1)1521 trans_mkdir3(
1522 nfslog_request_record *logrec,
1523 char *fhpath,
1524 char *path1)
1525 {
1526 struct transentry *newte;
1527 /* LINTED */
1528 nfslog_MKDIR3args *args = (nfslog_MKDIR3args *)logrec->re_rpc_arg;
1529 /* LINTED */
1530 nfslog_MKDIR3res *res = (nfslog_MKDIR3res *)logrec->re_rpc_res;
1531
1532 if (res->status != NFS3_OK)
1533 return (NULL);
1534
1535 if ((newte = create_te()) == NULL)
1536 return (NULL);
1537
1538 if (!path1) {
1539 newte->pathname =
1540 nfslog_get_path(NFSLOG_GET_FHANDLE3(&args->where.dir),
1541 args->where.name,
1542 fhpath, "trans_mkdir3");
1543 } else {
1544 newte->pathname = strdup(path1);
1545 }
1546
1547 newte->starttime = logrec->re_header.rh_timestamp;
1548 newte->lastupdate = logrec->re_header.rh_timestamp;
1549 newte->optype = TRANS_OPER_MKDIR;
1550 newte->datatype = TRANS_DATATYPE_BINARY;
1551 newte->transoption = TRANS_OPTION_NOACTION;
1552 newte->pnb = netbufdup(&(logrec->re_ipaddr));
1553 newte->uid = logrec->re_header.rh_uid;
1554 newte->nfsvers = NFS_V3;
1555 newte->netid = strdup(logrec->re_netid);
1556 if (logrec->re_principal_name)
1557 newte->principal_name = strdup(logrec->re_principal_name);
1558 else
1559 newte->principal_name = NULL;
1560 newte->totalbytes = 0;
1561 newte->fh_u.fh3 = args->where.dir;
1562
1563 return (newte);
1564 }
1565
1566 static struct transentry *
trans_rmdir3(nfslog_request_record * logrec,char * fhpath,char * path1)1567 trans_rmdir3(
1568 nfslog_request_record *logrec,
1569 char *fhpath,
1570 char *path1)
1571 {
1572 struct transentry *newte;
1573 /* LINTED */
1574 nfslog_RMDIR3args *args = (nfslog_RMDIR3args *)logrec->re_rpc_arg;
1575 /* LINTED */
1576 nfsstat3 *res = (nfsstat3 *)logrec->re_rpc_res;
1577
1578 if (*res != NFS3_OK)
1579 return (NULL);
1580
1581 if ((newte = create_te()) == NULL)
1582 return (NULL);
1583
1584 if (!path1) {
1585 newte->pathname =
1586 nfslog_get_path(NFSLOG_GET_FHANDLE3(&args->object.dir),
1587 args->object.name,
1588 fhpath, "trans_rmdir3");
1589 } else {
1590 newte->pathname = strdup(path1);
1591 }
1592
1593 newte->starttime = logrec->re_header.rh_timestamp;
1594 newte->lastupdate = logrec->re_header.rh_timestamp;
1595 newte->optype = TRANS_OPER_RMDIR;
1596 newte->datatype = TRANS_DATATYPE_BINARY;
1597 newte->transoption = TRANS_OPTION_NOACTION;
1598 newte->pnb = netbufdup(&(logrec->re_ipaddr));
1599 newte->uid = logrec->re_header.rh_uid;
1600 newte->nfsvers = NFS_V3;
1601 newte->netid = strdup(logrec->re_netid);
1602 if (logrec->re_principal_name)
1603 newte->principal_name = strdup(logrec->re_principal_name);
1604 else
1605 newte->principal_name = NULL;
1606 newte->totalbytes = 0;
1607 newte->fh_u.fh3 = args->object.dir;
1608
1609 return (newte);
1610 }
1611
1612 static struct transentry *
trans_rename3(nfslog_request_record * logrec,struct nfslog_trans_file * tf,char * fhpath,char * path1,char * path2)1613 trans_rename3(
1614 nfslog_request_record *logrec,
1615 struct nfslog_trans_file *tf,
1616 char *fhpath,
1617 char *path1,
1618 char *path2)
1619 {
1620 struct transentry *newte;
1621 struct transentry *pte = NULL;
1622 /* LINTED */
1623 nfslog_RENAME3args *args = (nfslog_RENAME3args *)logrec->re_rpc_arg;
1624 /* LINTED */
1625 nfsstat3 *res = (nfsstat3 *)logrec->re_rpc_res;
1626 char *tpath1 = NULL;
1627 char *tpath2 = NULL;
1628
1629 if (*res != NFS3_OK)
1630 return (NULL);
1631
1632 if ((newte = create_te()) == NULL)
1633 return (NULL);
1634
1635 if (!path1) {
1636 path1 = tpath1 =
1637 nfslog_get_path(NFSLOG_GET_FHANDLE3(&args->from.dir),
1638 args->from.name, fhpath, "trans_rename3 from");
1639 path2 = tpath2 =
1640 nfslog_get_path(NFSLOG_GET_FHANDLE3(&args->to.dir),
1641 args->to.name, fhpath, "trans_rename3 to");
1642 }
1643
1644 newte->pathname = path1; /* no need to strdup here */
1645 newte->starttime = logrec->re_header.rh_timestamp;
1646 newte->lastupdate = logrec->re_header.rh_timestamp;
1647 newte->optype = TRANS_OPER_RENAME;
1648 newte->datatype = TRANS_DATATYPE_BINARY;
1649 newte->transoption = TRANS_OPTION_NOACTION;
1650 newte->pnb = netbufdup(&(logrec->re_ipaddr));
1651 newte->uid = logrec->re_header.rh_uid;
1652 newte->nfsvers = NFS_V3;
1653 newte->netid = strdup(logrec->re_netid);
1654 if (logrec->re_principal_name)
1655 newte->principal_name = strdup(logrec->re_principal_name);
1656 else
1657 newte->principal_name = NULL;
1658 newte->totalbytes = 0;
1659 newte->fh_u.fh3 = args->from.dir;
1660
1661 /* switch path names for the file for renames */
1662 if (pte = insert_te(tf->te_list_v3_write, newte)) {
1663 free(pte->pathname);
1664 pte->pathname = strdup(path2);
1665 }
1666 if (pte = insert_te(tf->te_list_v3_read, newte)) {
1667 free(pte->pathname);
1668 pte->pathname = strdup(path2);
1669 }
1670 if (pte = insert_te(tf->te_list_v2_write, newte)) {
1671 free(pte->pathname);
1672 pte->pathname = strdup(path2);
1673 }
1674 if (pte = insert_te(tf->te_list_v2_read, newte)) {
1675 free(pte->pathname);
1676 pte->pathname = strdup(path2);
1677 }
1678
1679 newte->pathname = (char *)malloc(strlen(path1) + strlen(path2) + 3);
1680 /* check for NULL malloc */
1681 (void) sprintf(newte->pathname, "%s->%s", path1, path2);
1682
1683 if (tpath1) {
1684 free(tpath1);
1685 free(tpath2);
1686 }
1687
1688 return (newte);
1689 }
1690
1691 static struct transentry *
trans_mknod3(nfslog_request_record * logrec,char * fhpath,char * path1)1692 trans_mknod3(
1693 nfslog_request_record *logrec,
1694 char *fhpath,
1695 char *path1)
1696 {
1697 struct transentry *newte;
1698 /* LINTED */
1699 nfslog_MKNOD3args *args = (nfslog_MKNOD3args *)logrec->re_rpc_arg;
1700 /* LINTED */
1701 nfslog_MKNOD3res *res = (nfslog_MKNOD3res *)logrec->re_rpc_res;
1702
1703 if (res->status != NFS3_OK)
1704 return (NULL);
1705
1706 if ((newte = create_te()) == NULL)
1707 return (NULL);
1708
1709 if (!path1) {
1710 newte->pathname =
1711 nfslog_get_path(NFSLOG_GET_FHANDLE3(&args->where.dir),
1712 args->where.name,
1713 fhpath, "trans_mknod3");
1714 } else {
1715 newte->pathname = strdup(path1);
1716 }
1717
1718 newte->starttime = logrec->re_header.rh_timestamp;
1719 newte->lastupdate = logrec->re_header.rh_timestamp;
1720 newte->optype = TRANS_OPER_MKNOD;
1721 newte->datatype = TRANS_DATATYPE_BINARY;
1722 newte->transoption = TRANS_OPTION_NOACTION;
1723 newte->pnb = netbufdup(&(logrec->re_ipaddr));
1724 newte->uid = logrec->re_header.rh_uid;
1725 newte->nfsvers = NFS_V3;
1726 newte->netid = strdup(logrec->re_netid);
1727 if (logrec->re_principal_name)
1728 newte->principal_name = strdup(logrec->re_principal_name);
1729 else
1730 newte->principal_name = NULL;
1731
1732 newte->totalbytes = 0;
1733 newte->fh_u.fh3 = args->where.dir;
1734
1735 return (newte);
1736 }
1737
1738 static struct transentry *
trans_link3(nfslog_request_record * logrec,char * fhpath,char * path1,char * path2)1739 trans_link3(
1740 nfslog_request_record *logrec,
1741 char *fhpath,
1742 char *path1,
1743 char *path2)
1744 {
1745 struct transentry *newte;
1746 /* LINTED */
1747 nfslog_LINK3args *args = (nfslog_LINK3args *)logrec->re_rpc_arg;
1748 /* LINTED */
1749 nfsstat3 *res = (nfsstat3 *)logrec->re_rpc_res;
1750
1751 char *tpath1 = NULL;
1752 char *tpath2 = NULL;
1753
1754 if (*res != NFS3_OK)
1755 return (NULL);
1756
1757 if ((newte = create_te()) == NULL)
1758 return (NULL);
1759
1760 if (!path1) {
1761 tpath1 = nfslog_get_path(NFSLOG_GET_FHANDLE3(&args->file),
1762 NULL, fhpath, "trans_link3 from");
1763 tpath2 = nfslog_get_path(NFSLOG_GET_FHANDLE3(&args->link.dir),
1764 args->link.name, fhpath, "trans_link3 to");
1765 path1 = tpath1;
1766 path2 = tpath2;
1767 }
1768
1769 newte->starttime = logrec->re_header.rh_timestamp;
1770 newte->lastupdate = logrec->re_header.rh_timestamp;
1771 newte->optype = TRANS_OPER_LINK;
1772 newte->datatype = TRANS_DATATYPE_BINARY;
1773 newte->transoption = TRANS_OPTION_NOACTION;
1774 newte->pnb = netbufdup(&(logrec->re_ipaddr));
1775 newte->uid = logrec->re_header.rh_uid;
1776 newte->nfsvers = NFS_V3;
1777 newte->netid = strdup(logrec->re_netid);
1778 if (logrec->re_principal_name)
1779 newte->principal_name = strdup(logrec->re_principal_name);
1780 else
1781 newte->principal_name = NULL;
1782 newte->totalbytes = 0;
1783 newte->fh_u.fh3 = args->file;
1784
1785 newte->pathname = (char *)malloc(strlen(path1) + strlen(path2) + 3);
1786 /* check for NULL malloc */
1787 (void) sprintf(newte->pathname, "%s->%s", path1, path2);
1788
1789 if (tpath1) {
1790 free(tpath1);
1791 free(tpath2);
1792 }
1793
1794 return (newte);
1795 }
1796
1797 static struct transentry *
trans_symlink3(nfslog_request_record * logrec,char * fhpath,char * path1)1798 trans_symlink3(
1799 nfslog_request_record *logrec,
1800 char *fhpath,
1801 char *path1)
1802 {
1803 struct transentry *newte;
1804 /* LINTED */
1805 nfslog_SYMLINK3args *args = (nfslog_SYMLINK3args *)logrec->re_rpc_arg;
1806 /* LINTED */
1807 nfslog_SYMLINK3res *res = (nfslog_SYMLINK3res *)logrec->re_rpc_res;
1808 char *name;
1809
1810 if (res->status != NFS3_OK)
1811 return (NULL);
1812
1813 if ((newte = create_te()) == NULL)
1814 return (NULL);
1815
1816 if (path1) {
1817 name = strdup(path1);
1818 } else {
1819 name = nfslog_get_path(NFSLOG_GET_FHANDLE3(&args->where.dir),
1820 args->where.name, fhpath, "trans_symlink3");
1821 }
1822
1823 newte->starttime = logrec->re_header.rh_timestamp;
1824 newte->lastupdate = logrec->re_header.rh_timestamp;
1825 newte->optype = TRANS_OPER_SYMLINK;
1826 newte->datatype = TRANS_DATATYPE_BINARY;
1827 newte->transoption = TRANS_OPTION_NOACTION;
1828 newte->pnb = netbufdup(&(logrec->re_ipaddr));
1829 newte->uid = logrec->re_header.rh_uid;
1830 newte->nfsvers = NFS_V3;
1831 newte->netid = strdup(logrec->re_netid);
1832 if (logrec->re_principal_name)
1833 newte->principal_name = strdup(logrec->re_principal_name);
1834 else
1835 newte->principal_name = NULL;
1836 newte->totalbytes = 0;
1837 newte->fh_u.fh3 = args->where.dir;
1838
1839 newte->pathname = (char *)malloc(strlen(name) +
1840 strlen(args->symlink_data) + 3);
1841 /* check for NULL malloc */
1842 (void) sprintf(newte->pathname, "%s->%s", name, args->symlink_data);
1843
1844 free(name);
1845
1846 return (newte);
1847 }
1848
1849 /*
1850 * nfslog_process_trans_rec - processes the record in the buffer and outputs
1851 * to the trans log.
1852 * Return 0 for success, errno else.
1853 */
1854 int
nfslog_process_trans_rec(void * transcookie,nfslog_request_record * logrec,char * fhpath,char * path1,char * path2)1855 nfslog_process_trans_rec(void *transcookie, nfslog_request_record *logrec,
1856 char *fhpath, char *path1, char *path2)
1857 {
1858 struct transentry *pte = NULL;
1859 struct nfslog_trans_file *tf = (struct nfslog_trans_file *)transcookie;
1860
1861 /* ignore programs other than nfs */
1862 if (logrec->re_header.rh_prognum != NFS_PROGRAM)
1863 return (0);
1864
1865 /* update the timestamp for use later in the timeout sequences */
1866 if (tf->lasttrans_timestamp.tv_sec <
1867 logrec->re_header.rh_timestamp.tv_sec)
1868 tf->lasttrans_timestamp =
1869 logrec->re_header.rh_timestamp;
1870
1871 /* current time of this processing */
1872 tf->last_trans_read = time(0);
1873
1874 /* ignore anything that is not a read or write */
1875 switch (logrec->re_header.rh_version) {
1876 case NFS_VERSION:
1877 switch (logrec->re_header.rh_procnum) {
1878 case RFS_READ:
1879 if (tf->trans_to_log & TRANSTOLOG_OPER_READ)
1880 pte = trans_read(logrec, tf, fhpath, path1);
1881 break;
1882 case RFS_WRITE:
1883 if (tf->trans_to_log & TRANSTOLOG_OPER_WRITE)
1884 pte = trans_write(logrec, tf, fhpath, path1);
1885 break;
1886 case RFS_SETATTR:
1887 if (tf->trans_to_log & TRANSTOLOG_OPER_SETATTR)
1888 pte = trans_setattr(logrec, tf,
1889 fhpath, path1);
1890 break;
1891 case RFS_REMOVE:
1892 if (tf->trans_to_log & TRANSTOLOG_OPER_REMOVE)
1893 pte = trans_remove(logrec, tf, fhpath, path1);
1894 break;
1895 case RFS_MKDIR:
1896 if (tf->trans_to_log & TRANSTOLOG_OPER_MKDIR)
1897 pte = trans_mkdir(logrec, fhpath, path1);
1898 break;
1899 case RFS_RMDIR:
1900 if (tf->trans_to_log & TRANSTOLOG_OPER_RMDIR)
1901 pte = trans_rmdir(logrec, fhpath, path1);
1902 break;
1903 case RFS_CREATE:
1904 if (tf->trans_to_log & TRANSTOLOG_OPER_CREATE)
1905 pte = trans_create(logrec, tf, fhpath, path1);
1906 break;
1907 case RFS_RENAME:
1908 if (tf->trans_to_log & TRANSTOLOG_OPER_RENAME)
1909 pte = trans_rename(logrec, tf,
1910 fhpath, path1, path2);
1911 break;
1912 case RFS_LINK:
1913 if (tf->trans_to_log & TRANSTOLOG_OPER_LINK)
1914 pte = trans_link(logrec, fhpath, path1, path2);
1915 break;
1916 case RFS_SYMLINK:
1917 if (tf->trans_to_log & TRANSTOLOG_OPER_SYMLINK)
1918 pte = trans_symlink(logrec, fhpath, path1);
1919 break;
1920 default:
1921 break;
1922 }
1923 break;
1924 case NFS_V3:
1925 switch (logrec->re_header.rh_procnum) {
1926 case NFSPROC3_READ:
1927 if (tf->trans_to_log & TRANSTOLOG_OPER_READ)
1928 pte = trans_read3(logrec, tf, fhpath, path1);
1929 break;
1930 case NFSPROC3_WRITE:
1931 if (tf->trans_to_log & TRANSTOLOG_OPER_WRITE)
1932 pte = trans_write3(logrec, tf, fhpath, path1);
1933 break;
1934 case NFSPROC3_SETATTR:
1935 if (tf->trans_to_log & TRANSTOLOG_OPER_SETATTR)
1936 pte = trans_setattr3(logrec, tf,
1937 fhpath, path1);
1938 break;
1939 case NFSPROC3_REMOVE:
1940 if (tf->trans_to_log & TRANSTOLOG_OPER_REMOVE)
1941 pte = trans_remove3(logrec, tf,
1942 fhpath, path1);
1943 break;
1944 case NFSPROC3_MKDIR:
1945 if (tf->trans_to_log & TRANSTOLOG_OPER_MKDIR)
1946 pte = trans_mkdir3(logrec, fhpath, path1);
1947 break;
1948 case NFSPROC3_RMDIR:
1949 if (tf->trans_to_log & TRANSTOLOG_OPER_RMDIR)
1950 pte = trans_rmdir3(logrec, fhpath, path1);
1951 break;
1952 case NFSPROC3_CREATE:
1953 if (tf->trans_to_log & TRANSTOLOG_OPER_CREATE)
1954 pte = trans_create3(logrec, tf,
1955 fhpath, path1);
1956 break;
1957 case NFSPROC3_RENAME:
1958 if (tf->trans_to_log & TRANSTOLOG_OPER_RENAME)
1959 pte = trans_rename3(logrec, tf,
1960 fhpath, path1, path2);
1961 break;
1962 case NFSPROC3_MKNOD:
1963 if (tf->trans_to_log & TRANSTOLOG_OPER_MKNOD)
1964 pte = trans_mknod3(logrec, fhpath, path1);
1965 break;
1966 case NFSPROC3_LINK:
1967 if (tf->trans_to_log & TRANSTOLOG_OPER_LINK)
1968 pte = trans_link3(logrec,
1969 fhpath, path1, path2);
1970 break;
1971 case NFSPROC3_SYMLINK:
1972 if (tf->trans_to_log & TRANSTOLOG_OPER_SYMLINK)
1973 pte = trans_symlink3(logrec, fhpath, path1);
1974 break;
1975 default:
1976 break;
1977 }
1978 break;
1979 default:
1980 break;
1981 }
1982
1983 if (pte != NULL) {
1984 nfslog_print_trans_logentry(pte, tf);
1985 remove_te(pte);
1986 }
1987
1988 return (0);
1989 }
1990
1991 static void
nfslog_print_trans_logentry(struct transentry * pte,struct nfslog_trans_file * tf)1992 nfslog_print_trans_logentry(struct transentry *pte,
1993 struct nfslog_trans_file *tf)
1994 {
1995 char *remotehost;
1996 char datatype;
1997 char transoption;
1998 char *optype;
1999 char *prin;
2000 int prinid;
2001 char nfs_ident[32];
2002
2003 remotehost = addrtoname(pte->pnb->buf);
2004
2005 datatype = (pte->datatype == TRANS_DATATYPE_BINARY ? 'b' : 'a');
2006 transoption = (pte->transoption == TRANS_OPTION_NOACTION ? '_' : '?');
2007
2008 if (tf->trans_output_type == TRANSLOG_BASIC) {
2009 (void) strcpy(nfs_ident, "nfs");
2010 } else {
2011 (void) strcpy(nfs_ident,
2012 (pte->nfsvers == NFS_V3 ? "nfs3-" : "nfs-"));
2013 (void) strcat(nfs_ident, pte->netid);
2014 }
2015
2016 switch (pte->optype) {
2017 case TRANS_OPER_READ:
2018 optype = (tf->trans_output_type == TRANSLOG_EXTENDED ?
2019 "read" : "o");
2020 break;
2021 case TRANS_OPER_WRITE:
2022 optype = (tf->trans_output_type == TRANSLOG_EXTENDED ?
2023 "write" : "i");
2024 break;
2025 case TRANS_OPER_REMOVE:
2026 optype = (tf->trans_output_type == TRANSLOG_EXTENDED ?
2027 "remove" : "?");
2028 break;
2029 case TRANS_OPER_MKDIR:
2030 optype = (tf->trans_output_type == TRANSLOG_EXTENDED ?
2031 "mkdir" : "?");
2032 break;
2033 case TRANS_OPER_CREATE:
2034 optype = (tf->trans_output_type == TRANSLOG_EXTENDED ?
2035 "create" : "?");
2036 break;
2037 case TRANS_OPER_RMDIR:
2038 optype = (tf->trans_output_type == TRANSLOG_EXTENDED ?
2039 "rmdir" : "?");
2040 break;
2041 case TRANS_OPER_SETATTR:
2042 optype = (tf->trans_output_type == TRANSLOG_EXTENDED ?
2043 "setattr" : "?");
2044 break;
2045 case TRANS_OPER_RENAME:
2046 optype = (tf->trans_output_type == TRANSLOG_EXTENDED ?
2047 "rename" : "?");
2048 break;
2049 case TRANS_OPER_MKNOD:
2050 optype = (tf->trans_output_type == TRANSLOG_EXTENDED ?
2051 "mknod" : "?");
2052 break;
2053 case TRANS_OPER_LINK:
2054 optype = (tf->trans_output_type == TRANSLOG_EXTENDED ?
2055 "link" : "?");
2056 break;
2057 case TRANS_OPER_SYMLINK:
2058 optype = (tf->trans_output_type == TRANSLOG_EXTENDED ?
2059 "symlink" : "?");
2060 break;
2061 default:
2062 optype = "?";
2063 break;
2064 }
2065 if (strcmp(pte->principal_name, "") == 0) {
2066 prinid = 0;
2067 prin = "*";
2068 } else {
2069 prinid = 1;
2070 prin = pte->principal_name;
2071 }
2072 (void) fprintf(tf->fp,
2073 "%.24s %d %s %d %s %c %c %s %c %ld %s %d %s\n",
2074 ctime((time_t *)&pte->starttime.tv_sec),
2075 pte->lastupdate.tv_sec - pte->starttime.tv_sec,
2076 remotehost,
2077 (uint32_t)pte->totalbytes,
2078 pte->pathname,
2079 datatype,
2080 transoption,
2081 optype,
2082 'r', /* anonymous == 'a', guest == 'g', real == 'r'), */
2083 pte->uid,
2084 nfs_ident,
2085 /* authenticated - fill in kerb/security? */
2086 prinid,
2087 /* authenticated ? authuser : "*" */
2088 prin);
2089 }
2090