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 * 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 146 freenetbuf(struct netbuf *pnb) 147 { 148 free(pnb->buf); 149 free(pnb); 150 } 151 152 static struct transentry * 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 * 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 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 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 * 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 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 * 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 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 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 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 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