2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
13 #include <afsconfig.h>
14 #include <afs/param.h>
19 #include <sys/types.h>
20 #if !defined(AFS_SUN3_ENV) && !defined(sys_vax_ul43) && !defined(AFS_DARWIN_ENV)
22 /*#ifdef AFS_AIX_ENV*/
30 #include <afs/afs_args.h>
32 #include <afs/afsutil.h>
34 #if defined(AFS_ALPHA_ENV) || defined(AFS_SGI61_ENV)
35 /* For SGI 6.2, this is changed to 1 if it's a 32 bit kernel. */
36 int afs_icl_sizeofLong = 2;
38 int afs_icl_sizeofLong = 1;
42 int afs_64bit_kernel = 1; /* Default for 6.2+, and always for 6.1 */
43 extern int afs_icl_sizeofLong; /* Used in ICL_SIZEHACK() */
47 /* If _SC_KERN_POINTERS not in sysconf, then we can assume a 32 bit abi. */
48 void set_kernel_sizeof_long(void)
53 retval = sysconf(_SC_KERN_POINTERS);
56 afs_icl_sizeofLong = 2;
60 afs_icl_sizeofLong = 1;
64 #endif /* AFS_SGI62_ENV */
65 #endif /* AFS_SGI61_ENV */
67 #define BUFFER_MULTIPLIER 1024
69 /* make it big enough to snapshot everything at once, since
70 * decoding takes so long.
72 #define IBSIZE 100000 /* default size */
75 struct logInfo *nextp;
79 char dumpFileName[256] = "";
80 RegisterIclDumpFileName(name)
83 (void) sprintf(dumpFileName, "icl.%.250s", name);
86 /* define globals to use for bulk info */
87 afs_icl_bulkSetinfo_t *setInfo = (afs_icl_bulkSetinfo_t *)0;
88 afs_icl_bulkLoginfo_t *logInfo = (afs_icl_bulkLoginfo_t *)0;
90 struct afs_icl_set *icl_allSets = 0;
94 /* given a type and an address, get the size of the thing
97 static icl_GetSize(type, addr)
105 ICL_SIZEHACK(type, addr);
109 /* Check types in printf string "bufferp", making sure that each
110 * is compatible with the corresponding parameter type described
111 * by typesp. Also watch for prematurely running out of parameters
112 * before the string is gone.
115 static int CheckTypes(bufferp, typesp, typeCount, outMsgBuffer)
127 for(tc = *bufferp;; outMsgBuffer++, tc = *(++bufferp)) {
130 /* hit end of string. We win as long as we aren't
133 if (inPercent) return 0;
138 inPercent = 1 - inPercent;
142 if (tc >= '0' && tc <= '9') {
143 /* skip digits in % string */
148 /* 'l' is a type modifier. */
152 /* otherwise, we've finally gotten to the type-describing
153 * character. Make sure there's a type descriptor, and then
154 * check the type descriptor.
158 return 0; /* no more type descriptors left */
160 if (typesp[tix] != 1) /* not a string descriptor */
163 *outMsgBuffer = (char)1;
165 if (tc == 'u' || tc == 'x' || tc == 'd'
167 if (typesp[tix] != 0)
168 return 0; /* not an integer descriptor */
172 *outMsgBuffer = (char)2;
175 *outMsgBuffer = (char)3;
178 *outMsgBuffer = (char)4;
182 *outMsgBuffer = (char)5;
186 /* otherwise we're fine, so eat this descriptor */
192 #else /* AFS_SGI61_ENV */
193 static CheckTypes(bufferp, typesp, typeCount)
204 for(tc = *bufferp;; tc = *(++bufferp)) {
206 /* hit end of string. We win as long as we aren't
209 if (inPercent) return 0;
213 inPercent = 1 - inPercent;
217 if (tc >= '0' && tc <= '9') continue; /* skip digits in % string */
218 /* otherwise, we've finally gotten to the type-describing
219 * character. Make sure there's a type descriptor, and then
220 * check the type descriptor.
224 return 0; /* no more type descriptors left */
225 if (tc == 's' && typesp[tix] != 1) /* not a string descriptor */
227 if ((tc == 'u' || tc == 'l' || tc == 'x' || tc == 'd')
228 && (typesp[tix] != 0))
229 return 0; /* not an integer descriptor */
230 /* otherwise we're fine, so eat this descriptor */
236 #endif /* AFS_SGI61_ENV */
238 /* display a single record.
239 * alp points at the first word in the array to be interpreted
240 * rsize gives the # of words in the array
242 #if defined(AFS_SGI61_ENV) && !defined(AFS_SGI62_ENV)
243 #define uint64_t long long
245 static DisplayRecord(outFilep, alp, rsize)
247 register afs_int32 *alp;
250 char msgBuffer[1024];
252 char outMsgBuffer[1024];
254 uint64_t printfParms[ICL_MAXEXPANSION * /* max parms */ 4];
255 char *printfStrings[ICL_MAXEXPANSION * /* max parms */ 4];
256 #else /* AFS_SGI61_ENV */
257 long printfParms[ICL_MAXEXPANSION * /* max parms */ 4];
258 #endif /* AFS_SGI61_ENV */
259 int printfTypes[ICL_MAXEXPANSION * 4];
265 int pix; /* index in alp */
266 int pfpix; /* index in printfParms */
267 int pftix; /* index in printfTypes */
269 int printed; /* did we print the string yet? */
272 /* decode parameters */
273 temp = alp[0]; /* type encoded in low-order 24 bits, t0 high */
279 for(i=0; i<4*ICL_MAXEXPANSION; i++)
281 /* decode each parameter, getting addrs for afs_hyper_t and strings */
282 for(i=0; !done && i<4; i++) {
283 type = (temp >> (18 - i*6)) & 0x3f;
289 case ICL_TYPE_POINTER:
290 printfTypes[pftix++] = 0;
292 printfParms[pfpix] = alp[pix];
293 printfParms[pfpix] &= 0xffffffff;
294 if (afs_64bit_kernel) {
295 printfParms[pfpix] <<= 32;
296 printfParms[pfpix] |= alp[pix+1];
298 #else /* AFS_SGI61_ENV */
300 printfParms[pfpix] = alp[pix+1];
301 printfParms[pfpix] |= (alp[pix] <<= 32);
302 #else /* AFS_ALPHA_ENV */
303 printfParms[pfpix] = alp[pix];
304 #endif /* AFS_ALPHA_ENV */
305 #endif /* AFS_SGI61_ENV */
309 printfTypes[pftix++] = 0;
310 printfParms[pfpix++] = alp[pix];
314 printfTypes[pftix++] = 0;
315 printfParms[pfpix++] = alp[pix];
316 printfTypes[pftix++] = 0;
317 printfParms[pfpix++] = alp[pix+1];
320 printfTypes[pftix++] = 0;
321 printfParms[pfpix++] = alp[pix];
322 printfTypes[pftix++] = 0;
323 printfParms[pfpix++] = alp[pix+1];
324 printfTypes[pftix++] = 0;
325 printfParms[pfpix++] = alp[pix+2];
326 printfTypes[pftix++] = 0;
327 printfParms[pfpix++] = alp[pix+3];
329 case ICL_TYPE_STRING:
330 printfTypes[pftix++] = 1;
332 printfStrings[pfpix++] = (char*) &alp[pix];
333 #else /* AFS_SGI64_ENV */
335 printfStrings[pfpix++] = (char *) &alp[pix];
336 #else /* AFS_SGI61_ENV */
337 printfParms[pfpix++] = (long) &alp[pix];
338 #endif /* AFS_SGI61_ENV */
339 #endif /* AFS_SGI64_ENV */
341 case ICL_TYPE_UNIXDATE:
342 printfParms[pfpix++] = (long) ctime((time_t *)&alp[pix]);
345 printf("DisplayRecord: Bad type %d in decode switch.\n", type);
352 pix += icl_GetSize(type, (char *) &alp[pix]);
355 /* next, try to decode the opcode into a printf string */
356 dce1_error_inq_text(alp[1], msgBuffer, &status);
358 /* if we got a string back, and it is compatible with the
359 * parms we've got, then print it.
364 if (CheckTypes(msgBuffer, printfTypes, pftix, outMsgBuffer)) {
365 /* we have a string to use, but it ends "(dfs / zcm)",
366 * so we remove the extra gunk.
368 j = strlen(outMsgBuffer);
370 outMsgBuffer[j-11] = 0;
374 fprintf(outFilep, "time %d.%06d, pid %u: ", alp[3]/1000000,
375 alp[3] % 1000000, alp[2]);
376 for (i=0; i<j; i++) {
377 if ((int)outMsgBuffer[i] > 5)
378 fputc(outMsgBuffer[i], outFilep);
380 switch (outMsgBuffer[i]) {
384 fprintf(outFilep, "%s", printfStrings[pfpix++]);
386 case 2: /* signed integer */
387 fprintf(outFilep, "%lld", printfParms[pfpix++]);
389 case 3: /* unsigned integer */
390 fprintf(outFilep, "%llu", printfParms[pfpix++]);
392 case 4: /* octal integer */
393 fprintf(outFilep, "%llo", printfParms[pfpix++]);
395 case 5: /* hex integer */
396 fprintf(outFilep, "%llx", printfParms[pfpix++]);
400 "fstrace: Bad char %d in outMsgBuffer for parm %d\n",
401 outMsgBuffer[i], pfpix);
402 fprintf(outFilep, "fstrace: msgBuffer='%s'\n",
408 fprintf(outFilep, "\n");
411 #else /* AFS_SGI61_ENV */
412 if (CheckTypes(msgBuffer, printfTypes, pftix)) {
413 /* we have a string to use, but it ends "(dfs / zcm)",
414 * so we remove the extra gunk.
416 j = strlen(msgBuffer);
417 if (j > 12) msgBuffer[j-11] = 0;
418 fprintf(outFilep, "time %d.%06d, pid %u: ", alp[3]/1000000,
419 alp[3] % 1000000, alp[2]);
420 fprintf(outFilep, msgBuffer, printfParms[0], printfParms[1],
421 printfParms[2], printfParms[3], printfParms[4],
422 printfParms[5], printfParms[6], printfParms[7],
423 printfParms[8], printfParms[9], printfParms[10],
424 printfParms[11], printfParms[12], printfParms[13],
425 printfParms[14], printfParms[15]);
426 fprintf(outFilep, "\n");
429 #endif /* AFS_SGI61_ENV */
431 fprintf(outFilep, "Type mismatch, using raw print.\n");
432 fprintf(outFilep, "%s", msgBuffer);
436 if (alp[1] == ICL_INFO_TIMESTAMP) {
437 fprintf(outFilep, "time %d.%06d, pid %u: %s\n",
438 alp[3]/1000000, alp[3] % 1000000, alp[2],
439 ctime((time_t *)&alp[4]));
441 fprintf(outFilep, "raw op %d, time %d.%06d, pid %u\n",
442 alp[1], alp[3]/1000000, alp[3] % 1000000, alp[2]);
443 /* now decode each parameter and print it */
446 for(i=0; !done && i<4; i++) {
447 type = (temp >> (18 - i*6)) & 0x3f;
453 fprintf(outFilep, "p%d:%d ", i, alp[pix]);
457 tempParam = alp[pix];
459 tempParam |= alp[pix+1];
460 fprintf(outFilep, "p%d:%lld ", i, tempParam);
461 #else /* AFS_SGI61_ENV */
462 fprintf(outFilep, "p%d:%d ", i, alp[pix]);
463 #endif /* AFS_SGI61_ENV */
465 case ICL_TYPE_POINTER:
467 tempParam = alp[pix];
469 tempParam |= alp[pix+1];
470 fprintf(outFilep, "p%d:0x%llx ", i, tempParam);
471 #else /* AFS_SGI61_ENV */
472 fprintf(outFilep, "p%d:0x%x ", i, alp[pix]);
473 #endif /* AFS_SGI61_ENV */
477 fprintf(outFilep, "p%d:%x.%x ", i, alp[pix], alp[pix+1]);
480 fprintf(outFilep, "p%d:%d.%d.%d.%d ", i, alp[pix],
481 alp[pix+1], alp[pix+2], alp[pix+3]);
483 case ICL_TYPE_STRING:
484 fprintf(outFilep, "p%d:%s ", i, (char *) &alp[pix]);
486 case ICL_TYPE_UNIXDATE:
487 fprintf(outFilep, "p%d:%s ", i, ctime((time_t *)&alp[pix]));
490 printf("DisplayRecord: Bad type %d in raw print switch.\n",
498 pix += icl_GetSize(type, (char *) &alp[pix]);
501 fprintf(outFilep, "\n"); /* done with line */
511 #include <nl_types.h>
513 #if defined(AFS_OSF_ENV) && !defined(AFS_OSF20_ENV)
515 static nl_catd catopen1();
517 static nl_catd _do1_open();
518 static nl_catd cat_already_open();
519 static int make_sets();
520 static FILE *open1catfile();
521 static void add_open_cat();
522 static void cat_hard_close();
523 extern char *strchr();
525 static int catpid[NL_MAXOPEN];
526 static CATD *catsopen[NL_MAXOPEN];
527 #define PATH_FORMAT "/usr/lib/nls/msg/%L/%N:/etc/nls/msg/%L/%N"
528 #define DEFAULT_LANG "C"
529 #define TOO_MANY_HOLES(num_holes, num_non_holes) \
530 (((num_holes) > 100) && ((num_holes) > (num_non_holes)))
535 /*---- n: the number of bytes to be malloc'ed ----*/
539 t = (char *) malloc(n);
541 printf("Failed to get mem\n");
546 nl_catd catopen1 (cat, dummy)
549 /*---- char *cat: the name of the cat to be opened ----*/
550 /*---- int dummy: dummy variable ----*/
554 nl_catd _do_open(); /*---- routine that actually opens
561 if (catd = cat_already_open(cat)) {
562 catd->_count = catd->_count + 1;
566 catd = (CATD *)rmalloc (sizeof(CATD));
569 catd->_name = (char *)rmalloc(strlen(cat) + 1);
570 if ( catd->_name == NULL )
572 strcpy(catd->_name,cat);
574 catd->_magic = CAT_MAGIC;
576 #ifndef AFS_OSF20_ENV
577 catd->_pid = getpid();
580 if (_do1_open(catd) != CATD_ERR)
591 nl_catd _do1_open(catd)
594 /*---- pointer to the partially set up cat descriptor ----*/
597 int make_sets(); /*---- routine to unpack the sets into
598 fast acccess mode ----*/
599 void add_open_cat(); /*---- routine to keep a list of
602 int i; /*---- Misc counter(s) used for loop */
609 catd->_fd = open1catfile( catd->_name );
613 fread((void *)&magic,(size_t)4,(size_t)1,catd->_fd);
614 if (magic != CAT_MAGIC){
615 printf("Magic was %x instead of %x -> %x\n", magic, CAT_MAGIC, CATD_ERR);
622 /* if ((catd->_mem = shmat((int)fileno(catd->_fd), (char *)0, SHM_MAP | SHM_RDONLY))
623 == (char * )ERR ) { */
625 if (1) { /* disable the shmat, share memory segemnt */
627 /*______________________________________________________________________
628 If the file can not be mapped then simulate mapping for the index
629 table so that make_sets cat set things up. (rmalloc an area big
630 enough for the index table and read the whole thing in)
631 ______________________________________________________________________*/
633 /* reset the file pointer to the beginning of catalog */
634 fseek(catd->_fd,(long)0,0);
636 /* malloc the header, if fails return error */
637 catd->_hd = (struct _header *) rmalloc(sizeof(struct _header));
638 if ( catd->_hd == NULL )
641 /* read in the whole header */
642 fread((void *)catd->_hd,(size_t)sizeof(struct _header),(size_t)1,catd->_fd);
644 /* cs is a dummpy to hold a set temperorily. The purpose of */
645 /* this for loop is to fread the whole catalog so that the */
646 /* file pointer will be moved to the end of the catalog. */
647 for (i = 0 ; i < catd->_hd->_n_sets ; i++) {
648 fread((void *)&cs,(size_t)4,(size_t)1,catd->_fd);
649 fseek(catd->_fd, (long)(cs._n_msgs * sizeof(struct _msgptr)),1);
652 /* after the for loop, ftell returns the byte offset of the */
653 /* end of the catalog relative to the begining of the file. */
654 /* i.e. i contains the byte offset of the whole catalog. */
655 i = ftell(catd->_fd);
657 /* malloc _mem as a temp pointer to hold the entire catalog. */
658 catd->_mem = (char *)rmalloc(i);
659 if ( catd->_mem == NULL )
662 /* reset the file pointer to the begining. */
663 fseek(catd->_fd,(long)0,0);
665 /* read in the whole catalog into _mem */
666 fread((void *)catd->_mem,(size_t)i,(size_t)1,catd->_fd);
669 * If there aren't many holes in the set numbers,
670 * fully expand the compacted set array from the
671 * catalog. Then in catgets(), we'll be able to use
672 * the set number to index directly into the expanded
675 * If there are a lot of holes, leave the set array
676 * compacted. In catgets(), we'll search through it
677 * for the requested set.
680 num_holes = catd->_hd->_setmax - catd->_hd->_n_sets;
681 if (!TOO_MANY_HOLES(num_holes, catd->_hd->_n_sets)) {
682 catd->_sets_expanded = TRUE;
683 catd->_n_sets = catd->_hd->_setmax;
686 catd->_sets_expanded = FALSE;
687 catd->_n_sets = catd->_hd->_n_sets - 1;
690 /* malloc one extra set more than the max. set index */
691 catd->_set = (struct _catset *) rmalloc((catd->_n_sets+1)*
692 sizeof (struct _catset));
693 if ( catd->_set == NULL )
696 /* save the max. set number in catd->_setmax */
697 catd->_setmax = catd->_hd->_setmax;
698 /* call make_set to malloc memory for every message */
699 if(make_sets(catd) == -1)
708 /*______________________________________________________________________
709 Normal mapping has occurred, set a few things up and call make_sets
710 ______________________________________________________________________*/
712 catd->_hd =( struct _header * )( catd->_mem );
713 catd->_setmax = catd->_hd->_setmax;
714 catd->_set = (struct _catset *) rmalloc((catd->_hd->_setmax+1)*
715 sizeof (struct _catset));
716 if ( catd->_set == NULL )
718 if(make_sets(catd) == -1)
726 static void add_open_cat(catd)
728 /*---- catd to be added to the list of catalogs ----*/
731 int i = 0; /*---- Misc counter(s) used for loops ----*/
732 while (i < NL_MAXOPEN && catsopen[i]) {
733 if (!strcmp(catd->_name,catsopen[i]->_name)
734 #ifndef AFS_OSF20_ENV
735 && getpid()==catsopen[i]->_pid)
740 return; /*---- The catalog is already here ----*/
744 if (i < NL_MAXOPEN) {
746 catpid[i] = getpid();
755 * FUNCTION: Expands the compacted version of the catalog index table into
756 * the fast access memory version.
758 * EXECUTION ENVIRONMENT:
760 * Make_set executes under a process.
766 static int make_sets(catd)
769 struct _catset *cset;
770 char *base = catd->_mem;
771 int n_sets = catd->_hd->_n_sets;
772 int i; /*---- Misc counter(s) used for loops ----*/
773 int j; /*---- Misc counter(s) used for loops ----*/
774 int msgmax; /*---- The maximum number of _messages in a set ----*/
775 char *cmpct_set_ptr; /*---- pointer into the index table ----*/
776 struct _catset cs; /*---- used to look at the sets in the table -*/
779 cmpct_set_ptr = base + sizeof(struct _header);
781 for (i = 0 ; i < n_sets ; i++) {
782 /* loop through each compacted set */
784 cs = *(struct _catset *)cmpct_set_ptr;
785 /* set the _catset ptr to the base of the current
788 cs._mp = (struct _msgptr *)(cmpct_set_ptr +
789 2 * sizeof(unsigned short));
790 /* set the ms array ptr to the base of
791 compacted array of _msgptr's */
793 cset = (catd->_sets_expanded) ?
794 &catd->_set[cs._setno] : &catd->_set[i];
797 * If there aren't many holes in the message numbers,
798 * fully expand the compacted message array from the
799 * catalog. Then in catgets(), we'll be able to use
800 * the message number to index directly into the
803 * If there are many holes, leave the message array
804 * compacted. In catgets(), we'll search through it
805 * for the requested message.
808 msgmax = cs._mp[cs._n_msgs - 1]._msgno;
809 num_holes = msgmax - cs._n_msgs;
810 if (!TOO_MANY_HOLES(num_holes, cs._n_msgs)) {
811 cset->_msgs_expanded = TRUE;
812 cset->_n_msgs = msgmax;
815 cset->_msgs_expanded = FALSE;
816 cset->_n_msgs = cs._n_msgs - 1;
819 cset->_mp = (struct _msgptr *) rmalloc((1 + cset->_n_msgs) *
820 sizeof(struct _msgptr));
821 if (cset->_mp == NULL)
824 cset->_msgtxt = (char **) rmalloc((1 + cset->_n_msgs) *
826 if (cset->_msgtxt == NULL)
829 if (cset->_msgs_expanded) {
830 for (j = 0 ; j < cs._n_msgs ; j++) {
831 cset->_mp[cs._mp[j]._msgno] = cs._mp[j];
835 for (j = 0 ; j < cs._n_msgs ; j++) {
836 cset->_mp[j] = cs._mp[j];
840 cset->_setno = cs._setno;
841 /* Superfluous but should have the correct data. Increment
842 the base of the set pointer. */
844 cmpct_set_ptr += 2 * sizeof(unsigned short) + cs._n_msgs *
845 sizeof(struct _msgptr);
856 * FUNCTION: Opens a catalog file, looking in the language path first (if
857 * there is no slash) and returns a pointer to the file stream.
859 * EXECUTION ENVIRONMENT:
861 * Opencatfile executes under a process.
863 * RETURNS: Returns a pointer to the file stream, and a NULL pointer on
867 static FILE *open1catfile(file)
870 extern char *getenv();
871 char fl[PATH_MAX]; /*---- place to hold full path ----*/
872 char *nlspath; /*---- pointer to the nlspath val ----*/
873 FILE *fp; /*---- file pointer ----*/
874 char cpth[PATH_MAX]; /*---- current value of nlspath ----*/
876 char *fulllang; /* %L language value */
877 char lang[PATH_MAX]; /* %l language value */
878 char *territory; /* %t language value */
879 char *codeset; /* %c language value */
880 char *ptr; /* for decompose of $LANG */
885 char outptr[PATH_MAX];
888 if (strchr(file,'/')) {
889 if ((fp = fopen(file,"r")))
890 { fcntl(fileno(fp),F_SETFD,1);
891 /* set the close-on-exec flag for
897 if (!(nlspath = getenv("NLSPATH")))
898 nlspath = PATH_FORMAT;
899 if (!(fulllang = getenv("LANG")))
900 fulllang = DEFAULT_LANG;
901 if (fulllang == DEFAULT_LANG)
902 nlspath = PATH_FORMAT; /* if fullang is C, use the
903 the default nlspath: */
906 ** LANG is a composite of three fields:
907 ** language_territory.codeset
908 ** and we're going to break it into those
912 strcpy(lang, fulllang);
917 ptr = strchr( lang, '_' );
921 ptr = strchr(territory, '.');
927 ptr = strchr( lang, '.' );
937 while (*np && *np != ':')
940 if (*np) /*---- iff on a colon then advance --*/
948 while (*ptr != '\0') {
949 while ((*ptr != '\0') && (*ptr != '%')
950 && (nchars < PATH_MAX)) {
951 *(optr++) = *(ptr++);
979 lenstr = strlen(str);
981 if (nchars < PATH_MAX) {
989 if (nchars >= PATH_MAX) {
995 strcpy(cpth, outptr);
997 else { /*---- iff leading | trailing |
998 adjacent colons ... --*/
1002 if (valid == 1 && (fp = fopen(cpth,"r")))
1003 { fcntl(fileno(fp),F_SETFD,1);
1004 /* set the close-on-exec flag for
1009 if (fp = fopen(file,"r"))
1010 { fcntl(fileno(fp),F_SETFD,1);
1011 /* set the close-on-exec flag for
1025 * NAME: cat_already_open
1027 * FUNCTION: Checkes to see if a specific cat has already been opened.
1029 * EXECUTION ENVIRONMENT:
1031 * Cat_already_open executes under a process.
1033 * RETURNS: Returns a pointer to the existing CATD if one exists, and
1034 * a NULL pointer if no CATD exists.
1037 static nl_catd cat_already_open(cat)
1039 /*---- name of the catalog to be opened ----*/
1042 int i; /*---- Misc counter(s) used for loops ----*/
1044 for (i = 0 ; i < NL_MAXOPEN && catsopen[i] ; i++) {
1045 #ifndef AFS_OSF20_ENV
1046 if (!strcmp(cat,catsopen[i]->_name) && getpid()==catsopen[i]->_pid) {
1048 if (!strcmp(cat,catsopen[i]->_name)) {
1050 return(catsopen[i]);
1057 int catclose1(catd) /*---- the catd to be closed ----*/
1058 nl_catd catd; /*---- the catd to be closed ----*/
1064 if (catd == CATD_ERR)
1066 for (i=0; i< NL_MAXOPEN && catsopen[i]; i++) {
1067 #ifndef AFS_OSF20_ENV
1068 if (catd == catsopen[i] && getpid()==catsopen[i]->_pid)
1070 if (catd == catsopen[i])
1074 if (i == NL_MAXOPEN || catsopen[i] == NULL)
1076 if (catd->_fd == (FILE *)NULL)
1077 /*---- return if this is an extra open or
1078 a bad catalog discriptor ----*/
1080 if (cat_already_open(catd->_name)) {
1081 if (catd->_count == 1) {
1082 cat_hard_close(catd);
1083 return (0); /*--- the last legal clsoe ---*/
1085 else if (catd->_count > 1) {
1086 catd->_count = catd->_count - 1;
1087 return(0); /*--- a legal close ---*/
1090 return (-1); /*--- an extra illegal close ---*/
1097 static void cat_hard_close(catd)
1099 /*---- the catd to be closed ----*/
1102 int i; /*---- Misc counter(s) used for loops ----*/
1103 int j; /*---- Misc counter ----*/
1105 if (catd == CATD_ERR)
1108 /*______________________________________________________________________
1109 remove any entry for the catalog in the catsopen array
1110 ______________________________________________________________________*/
1112 for (i = 0 ; i < NL_MAXOPEN && catsopen[i] ; i++) {
1113 if (catd == catsopen[i]) {
1114 for (; i < NL_MAXOPEN-1; i++) {
1115 catsopen[i] = catsopen[i+1];
1116 catpid[i] = catpid[i+1];
1123 /*______________________________________________________________________
1124 close the cat and free up the memory
1125 ______________________________________________________________________*/
1126 if (catd->_mem == FALSE)
1128 for (i = 0 ; i <= catd->_n_sets ; i++) {
1129 if (catd->_set[i]._mp)
1130 free(catd->_set[i]._mp);
1131 /*---- free the _message pointer arrays ----*/
1133 if (catd->_set[i]._msgtxt) {
1134 for (j = 0 ; j <= catd->_set[i]._n_msgs ; j++) {
1135 if (catd->_set[i]._msgtxt[j]) {
1136 /* free(catd->_set[i]._msgtxt[j]);*/
1139 if (catd->_set[i]._msgtxt)
1140 free(catd->_set[i]._msgtxt);
1146 fclose(catd->_fd); /*---- close the ctatlog ----*/
1148 free(catd->_set); /*---- free the sets ----*/
1150 free(catd->_name); /*---- free the name ----*/
1152 free(catd->_hd); /*---- free the header ----*/
1154 free(catd); /*---- free the catd ----*/
1157 static char *_do1_read_msg(nl_catd catd,int setno,int msgno)
1159 /*---- catd: the catd of the catalog to be read from ----*/
1160 /*---- setno: the set number of the message ----*/
1161 /*---- msgno: the msgno of the message ----*/
1164 nl_catd catd1; /*--- catd for different process ----*/
1167 #ifndef AFS_OSF20_ENV
1168 if (getpid() == catd->_pid)
1172 return (_read1_msg (catd, setno, msgno));
1175 * Since our pid is different from the one in
1176 * catd, catd must have come from a catopen()
1177 * in our parent. We need a catd of our own.
1178 * The first time through here, the call to
1179 * catopen() creates a new catd and we try to
1180 * open its message catalog. After that, the
1181 * catopen() just retrieves the catd.
1183 if (((catd1 = catopen1(catd->_name, 0)) != CATD_ERR) &&
1184 ((catd1->_fd == NL_FILE_CLOSED &&
1185 _do1_open(catd1) != CATD_ERR) ||
1186 (catd1->_fd != NL_FILE_UNUSED)))
1187 return (_read1_msg(catd1,setno,msgno));
1194 struct _catset *_cat1_get_catset();
1195 static struct _msgptr *_cat1_get_msgptr();
1196 static char *_read1_msg(nl_catd catd,int setno,int msgno)
1199 struct _catset *set; /*--- ptr to set's _catset structure ---*/
1200 struct _msgptr *msg; /*--- ptr to msg's _msgptr structure ---*/
1201 char **msgtxt; /*--- temporary pointer to the message text
1204 set = _cat1_get_catset(catd, setno);
1206 msg = _cat1_get_msgptr(set, msgno);
1208 msgtxt = &set->_msgtxt[msg - set->_mp];
1209 if (1/*!*msgtxt*/) {
1210 *msgtxt = (char *) malloc(msg->_msglen + 1);
1214 fseek(catd->_fd, (long) msg->_offset, 0);
1215 if (fread((void *) *msgtxt,
1216 (size_t) (msg->_msglen + 1),
1217 (size_t) 1, catd->_fd) != 1)
1228 * NAME: compare_sets
1230 * FUNCTION: Compare function used by bsearch() in _cat_get_catset().
1233 * key - pointer to set number we're searching for
1234 * element - pointer to current _catset structure
1236 * RETURNS: Returns -1, 0, or 1, depending on whether the set number
1237 * is less than, equal to, or greater than the set number of
1238 * the _catset structure.
1243 compare_sets(const void *key, const void *element)
1245 int *setno = (int *) key;
1246 struct _catset *set = (struct _catset *) element;
1248 if (*setno < set->_setno)
1250 if (*setno > set->_setno)
1258 * NAME: _cat_get_catset
1260 * FUNCTION: Find a set in the catd->_set array. Assumes that the
1261 * sets in the array are sorted by increasing set number.
1264 * catd - catalog descripter obtained from catopen()
1265 * setno - message catalogue set number
1267 * RETURNS: Returns a pointer to the set on success.
1268 * On any error, returns NULL.
1272 struct _catset *_cat1_get_catset(nl_catd catd, int setno)
1274 struct _catset *set;
1276 if ((catd == (nl_catd) NULL) || (catd == CATD_ERR))
1277 return (struct _catset *) NULL;
1279 if (catd->_sets_expanded) {
1280 if ((setno < 0) || (setno > catd->_n_sets))
1281 return (struct _catset *) NULL;
1283 set = &catd->_set[setno];
1286 * Catch empty elements in the array. They aren't
1290 if (set->_mp == (struct _msgptr *) NULL)
1291 return (struct _catset *) NULL;
1294 set = (struct _catset *) bsearch((void *) &setno,
1295 catd->_set, catd->_n_sets + 1,
1296 sizeof(struct _catset),
1300 * Since the sets are compacted, there aren't any
1301 * empty elements in the array to check for.
1310 * NAME: compare_msgs
1312 * FUNCTION: Compare function used by bsearch() in _cat_get_msgptr().
1315 * key - pointer to message number we're searching for
1316 * element - pointer to current _msgptr structure
1318 * RETURNS: Returns -1, 0, or 1, depending on whether the message
1319 * number is less than, equal to, or greater than the message
1320 * number of the _msgptr structure.
1325 compare_msgs(const void *key, const void *element)
1327 int *msgno = (int *) key;
1328 struct _msgptr *msg = (struct _msgptr *) element;
1330 if (*msgno < msg->_msgno)
1332 if (*msgno > msg->_msgno)
1339 * NAME: _cat1_get_msgptr
1341 * FUNCTION: Find a message in a set's set->_mp array. Assumes that
1342 * the messages in the array are sorted by increasing
1346 * set - ptr to _catset structure
1347 * msgno - message catalogue message number
1349 * RETURNS: Returns a pointer to the message on success.
1350 * On any error, returns NULL.
1353 static struct _msgptr *_cat1_get_msgptr(struct _catset *set, int msgno)
1355 struct _msgptr *msg;
1357 if (set == (struct _catset *) NULL)
1358 return (struct _msgptr *) NULL;
1360 if (set->_mp == (struct _msgptr *) NULL) /* empty set */
1361 return (struct _msgptr *) NULL;
1363 if (set->_msgs_expanded) {
1364 if ((msgno < 0) || (msgno > set->_n_msgs))
1365 return (struct _msgptr *) NULL;
1367 msg = &set->_mp[msgno];
1370 * Catch empty elements in the array. They aren't
1375 return (struct _msgptr *) NULL;
1378 msg = (struct _msgptr *) bsearch((void *) &msgno,
1379 set->_mp, set->_n_msgs + 1,
1380 sizeof(struct _msgptr),
1384 * Since the messages are compacted, there aren't any
1385 * empty elements in the array to check for.
1392 char *catgets1(nl_catd catd,int setno,int msgno,char *def)
1393 /*---- catd: the catd to get the message from ----*/
1394 /*---- setno: the set number of the message ----*/
1395 /*---- msgno: the message number of the message ----*/
1396 /*---- def: the default string to be returned ----*/
1400 char *_do_read_msg();
1404 if (catd == NULL || catd == CATD_ERR ||
1405 catd->_magic != CAT_MAGIC || catd->_fd == NL_FILE_UNUSED) {
1408 if (catd->_fd == NL_FILE_CLOSED) {
1409 catd = _do1_open(catd);
1410 if (catd == CATD_ERR)
1414 if (catd->_mem) { /*---- for mapped files ----*/
1415 if (setno <= catd->_hd->_setmax) {
1416 if (msgno < catd->_set[setno]._n_msgs) {
1417 if (catd->_set[setno]._mp[msgno]._offset) {
1419 catd->_set[setno]._mp[msgno]._offset);
1425 else { /*---- for unmapped files ----*/
1426 m = _do1_read_msg(catd,setno,msgno);
1436 #define FACILITY_CODE_MASK 0xF0000000
1437 #define FACILITY_CODE_SHIFT 28
1439 #define COMPONENT_CODE_MASK 0x0FFFF000
1440 #define COMPONENT_CODE_SHIFT 12
1442 #define STATUS_CODE_MASK 0x00000FFF
1443 #define STATUS_CODE_SHIFT 0
1445 #define NO_MESSAGE "THIS IS NOT A MESSAGE"
1448 * The system-dependant location for the catalog files is defined in sysconf.h
1449 * RPC_DEFAULT_NLSPATH should be defined in sysconf.h. Otherwise we use
1450 * /usr/afs/etc/C/%s.cat
1453 #ifndef RPC_NLS_FORMAT
1454 #define RPC_NLS_FORMAT "%s.cat"
1457 dce1_error_inq_text (status_to_convert, error_text, status)
1458 afs_uint32 status_to_convert;
1459 unsigned char *error_text;
1463 unsigned short facility_code;
1464 unsigned short component_code;
1465 unsigned short status_code;
1466 unsigned short i, failed=0;
1468 char component_name[4];
1469 char *facility_name;
1470 char filename_prefix[7];
1471 char nls_filename[11];
1472 char alt_filename[80];
1475 static char *facility_names[] = {
1481 * set up output status for future error returns
1488 * check for ok input status
1490 if (status_to_convert == 0)
1496 strcpy ((char *)error_text, "successful completion");
1501 * extract the component, facility and status codes
1503 facility_code = (status_to_convert & FACILITY_CODE_MASK) >> FACILITY_CODE_SHIFT;
1504 component_code = (status_to_convert & COMPONENT_CODE_MASK) >> COMPONENT_CODE_SHIFT;
1505 status_code = (status_to_convert & STATUS_CODE_MASK) >> STATUS_CODE_SHIFT;
1508 * see if this is a recognized facility
1510 if (facility_code == 0 || facility_code > sizeof (facility_names) / sizeof (char *))
1512 sprintf ((char *) error_text, "status %08x (unknown facility)", status_to_convert);
1515 facility_name = facility_names[facility_code - 1];
1517 * Convert component name from RAD-50 component code. (Mapping is:
1518 * 0 => 'a', ..., 25 => 'z', 26 => '{', 27 => '0', ..., 36 => '9'.)
1520 component_name[3] = 0;
1521 component_name[2] = component_code % 40;
1522 component_code /= 40;
1523 component_name[1] = component_code % 40;
1524 component_name[0] = component_code / 40;
1525 for (i = 0; i < 3; i++)
1527 component_name[i] += (component_name[i] <= 26) ? 'a' : ('0' - 27);
1529 sprintf (filename_prefix, "%3s%3s", facility_name, component_name);
1530 sprintf (nls_filename, RPC_NLS_FORMAT, filename_prefix);
1533 * Open the message file
1535 #if defined(AFS_OSF_ENV)
1536 #if defined(AFS_OSF20_ENV)
1537 catd = (nl_catd) catopen (nls_filename, 0);
1539 catd = (nl_catd) catopen1 (nls_filename, 0);
1542 J = (int) catopen (nls_filename, 0);
1545 if (catd == (nl_catd) -1)
1548 * If we did not succeed in opening message file using NLSPATH,
1549 * try to open the message file in a well-known default area
1552 #ifndef RPC_DEFAULT_NLSPATH
1553 sprintf(alt_filename, "%s/C/%s.cat", AFSDIR_CLIENT_ETC_DIRPATH, filename_prefix);
1555 sprintf (alt_filename, RPC_DEFAULT_NLSPATH, filename_prefix);
1558 #if defined(AFS_OSF_ENV)
1559 #if defined(AFS_OSF20_ENV)
1560 catd = (nl_catd) catopen (alt_filename, 0);
1562 catd = (nl_catd) catopen1 (alt_filename, 0);
1565 J = (int) catopen (alt_filename, 0);
1568 if (catd == (nl_catd) -1)
1570 sprintf ((char *) error_text, "status %08x (%s / %s)",
1571 status_to_convert, facility_name, component_name);
1576 * try to get the specified message from the file
1578 #if defined(AFS_OSF_ENV) && !defined(AFS_OSF20_ENV)
1579 message = (char *) catgets1 (catd, 1, status_code, NO_MESSAGE);
1581 message = (char *) catgets (catd, 1, status_code, NO_MESSAGE);
1584 * if everything went well, return the resulting message
1586 if (strcmp (message, NO_MESSAGE) != 0)
1588 sprintf ((char *) error_text, "%s (%s / %s)",
1589 message, facility_name, component_name);
1599 #if defined(AFS_OSF_ENV) && !defined(AFS_OSF20_ENV)
1606 sprintf ((char *) error_text, "status %08x (%s / %s)",
1607 status_to_convert, facility_name, component_name);
1609 #if defined(AFS_OSF_ENV) && !defined(AFS_OSF20_ENV)
1618 icl_DumpKernel(outFilep, setname)
1622 afs_int32 bufferSize = 0;
1625 afs_int32 code, retVal = 0;
1630 afs_int32 dummy, dummy2;
1631 struct logInfo *lip;
1633 /* first, enumerate the logs we're interested in */
1637 /* dump logs for a particular set */
1638 for(i=0; i < ICL_LOGSPERSET; i++) {
1639 code = afs_syscall(AFSCALL_ICL, ICL_OP_ENUMLOGSBYSET,
1640 (long) setname, i, (long) tname, sizeof(tname));
1642 if (errno == EBADF) {
1644 continue; /* missing slot, nothing to worry about */
1648 code = afs_syscall(AFSCALL_ICL, ICL_OP_GETLOGINFO,
1649 (long) tname, (long) &dummy, (long) &dummy2, 0);
1653 if (dummy > bufferSize) /* find biggest log */
1655 lip = (struct logInfo *) malloc(sizeof(struct logInfo));
1656 memset((char *)lip, 0, sizeof(*lip));
1657 lip->nextp = allInfo;
1659 lip->name = (char *) malloc(strlen(tname)+1);
1660 strcpy(lip->name, tname);
1667 for(i=0;i<1000;i++) {
1668 code = afs_syscall(AFSCALL_ICL, ICL_OP_ENUMLOGS,
1669 i, (long) tname, sizeof(tname), (long) &dummy);
1671 if (dummy > bufferSize) /* find biggest log */
1673 lip = (struct logInfo *) malloc(sizeof(struct logInfo));
1674 memset((char *)lip, 0, sizeof(*lip));
1675 lip->nextp = allInfo;
1677 lip->name = (char *) malloc(strlen(tname)+1);
1678 strcpy(lip->name, tname);
1682 if (bufferSize == 0) return -1;
1683 bufferp = (afs_int32 *) malloc(sizeof(afs_int32) * bufferSize);
1684 if (!bufferp) return -1;
1686 fprintf(outFilep, "Found %d logs.\n", i);
1688 /* now print out the contents of each log */
1689 for(lip = allInfo; lip; lip=lip->nextp) {
1690 fprintf(outFilep, "\nContents of log %s:\n", lip->name);
1691 /* read out everything first; gets a more consistent
1694 nwords = 0; /* total words copied out */
1696 /* display all the entries in the log */
1697 if (bufferSize - nwords <= 0) break; /* filled whole buffer */
1698 code = afs_syscall(AFSCALL_ICL, ICL_OP_COPYOUT,
1699 (long) lip->name, (long) (bufferp+nwords),
1700 bufferSize - nwords, (long) &i);
1702 /* otherwise we've got an error */
1703 fprintf(outFilep, "Returned error %d dumping log.\n", errno);
1706 /* otherwise, we have flags in the high order byte, and
1707 * a length (in words) in the remainder.
1709 if ((code >> 24) & ICL_COPYOUTF_MISSEDSOME)
1710 fprintf(outFilep, "Log wrapped; data missing.\n");
1718 } /* for loop over all cookies */
1720 /* otherwise we should display all of the log entries here.
1721 * Note that a record may end in the middle, in which case
1722 * we should start over with the cookie value of the start
1725 for(ix = 0; ix<nwords;) {
1726 /* start of a record */
1727 rlength = (bufferp[ix] >> 24) & 0xff;
1729 fprintf(outFilep, "Internal error: 0 length record\n");
1733 /* ensure that entire record fits */
1734 if (ix+rlength > nwords) {
1735 /* doesn't fit, adjust cookie and break */
1738 /* print the record */
1739 DisplayRecord(outFilep, &bufferp[ix], rlength);
1742 /* obsolete: read entire buffer first */
1743 i += rlength; /* update cookie value, too */
1745 } /* for loop displaying buffer */
1746 } /* for loop over all logs */
1753 /* clear out log 'name' */
1759 code = afs_syscall(AFSCALL_ICL, ICL_OP_CLRLOG, (long)name, 0, 0, 0);
1763 /* clear out set 'name' */
1769 code = afs_syscall(AFSCALL_ICL, ICL_OP_CLRSET, (long) name, 0, 0, 0);
1773 /* clear out all logs */
1778 code = afs_syscall(AFSCALL_ICL, ICL_OP_CLRALL, 0, 0, 0, 0);
1782 /* list out all available sets to outFileP */
1783 int icl_ListSets(outFileP)
1791 for(i=0;i<1000;i++) {
1792 code = afs_syscall(AFSCALL_ICL, ICL_OP_ENUMSETS,
1793 i, (long) tname, sizeof(tname), (long) &states);
1795 (void) fprintf(outFileP, "%s %s%s%s\n", tname,
1796 (states & ICL_SETF_ACTIVE) ? "active" : "inactive",
1797 (states & ICL_SETF_FREED) ? " (dormant)" : "",
1798 (states & ICL_SETF_PERSISTENT) ? " persistent" : "");
1804 /* list out all available logs to outFileP */
1805 int icl_ListLogs(outFileP, int32flg)
1815 for(i=0;i<1000;i++) {
1816 code = afs_syscall(AFSCALL_ICL, ICL_OP_ENUMLOGS,
1817 i, (long) tname, sizeof(tname), (long) &logSize);
1821 /* get more information on the log */
1822 code = afs_syscall(AFSCALL_ICL, ICL_OP_GETLOGINFO, (long) tname,
1823 (long) &logSize, (long) &allocated, 0);
1826 (void) fprintf(outFileP, "%s : %d kbytes (%s)\n", tname, logSize/1024,
1827 allocated ? "allocated" : "unallocated");
1830 (void) fprintf(outFileP, "%s\n", tname);
1836 /* list out all available logs to outFileP */
1837 int icl_ListLogsBySet(outFileP, setname, int32flg)
1848 for(i=0; i < ICL_LOGSPERSET; i++) {
1849 code = afs_syscall(AFSCALL_ICL, ICL_OP_ENUMLOGSBYSET,
1850 (long) setname, i, (long) tname, sizeof(tname));
1852 if (errno == EBADF) {
1854 continue; /* missing */
1860 /* get more information on the log */
1861 code = afs_syscall(AFSCALL_ICL, ICL_OP_GETLOGINFO, (long) tname,
1862 (long) &logSize, (long) &allocated, 0);
1865 (void) fprintf(outFileP, "%s : %d kbytes (%s)\n", tname, logSize/1024,
1866 allocated ? "allocated" : "unallocated");
1869 (void) fprintf(outFileP, "%s\n", tname);
1875 /* activate/deactivate/free specified set */
1876 int icl_ChangeSetState(name, op)
1882 code = afs_syscall(AFSCALL_ICL, ICL_OP_SETSTAT, (long) name, op, 0, 0);
1886 /* activate/deactivate/free all sets */
1887 int icl_ChangeAllSetState(op)
1892 code = afs_syscall(AFSCALL_ICL, ICL_OP_SETSTATALL, op, 0, 0, 0);
1896 /* set size if log */
1897 int icl_ChangeLogSize(name, logSize)
1903 code = afs_syscall(AFSCALL_ICL, ICL_OP_SETLOGSIZE, (long)name, logSize, 0, 0);
1907 /* get logsize of specified log */
1908 int icl_GetLogsize(logname, logSizeP, allocatedP)
1910 afs_int32 *logSizeP;
1914 code = afs_syscall(AFSCALL_ICL, ICL_OP_GETLOGINFO, (long) logname,
1915 (long) logSizeP, (long) allocatedP, 0);
1919 /* get state of specified set */
1920 int icl_GetSetState(setname, stateP)
1925 code = afs_syscall(AFSCALL_ICL, ICL_OP_GETSETINFO, (long) setname,
1926 (long) stateP, 0, 0);
1930 icl_TailKernel(outFilep, logname, waitTime)
1935 afs_int32 bufferSize = 0;
1936 afs_int32 newBufferSize;
1939 afs_int32 code, retVal = 0;
1944 struct logInfo *lip;
1946 /* get information about the specified log */
1947 code = afs_syscall(AFSCALL_ICL, ICL_OP_GETLOGINFO,
1948 (long) logname, (long) &bufferSize, (long) &allocated, 0);
1951 if (errno == ENOENT)
1952 (void) fprintf(stderr, "'%s' not found\n", logname);
1954 (void) fprintf(stderr, "cannot get information on log '%s' (errno = %d)\n",
1961 (void) fprintf(stderr, "'%s' not allocated\n", logname);
1965 if (bufferSize == 0) return -1;
1966 bufferp = (afs_int32 *) malloc(sizeof(afs_int32) * bufferSize);
1969 (void) fprintf(stderr, "cannot allocate %d words for buffer\n",
1974 /* start "infinite" loop */
1977 /* read out all that's currently there */
1978 nwords = 0; /* total words copied out */
1979 i = 0; /* initialize cookie */
1981 /* display all the entries in the log */
1982 if (bufferSize - nwords <= 0)
1983 break; /* filled whole buffer, clear when done */
1984 code = afs_syscall(AFSCALL_ICL, ICL_OP_COPYOUTCLR,
1985 (long) logname, (long) (bufferp+nwords),
1986 bufferSize - nwords, (long) &i);
1988 /* otherwise we've got an error */
1989 fprintf(stderr, "returned error %d dumping log.\n", errno);
1993 /* otherwise, we have flags in the high order byte, and
1994 * a length (in words) in the remainder.
2003 } /* for loop over all cookies */
2005 /* otherwise we should display all of the log entries here.
2006 * Note that a record may end in the middle, in which case
2007 * we should start over with the cookie value of the start
2010 for(ix = 0; ix<nwords;) {
2011 /* start of a record */
2012 rlength = (bufferp[ix] >> 24) & 0xff;
2013 /* ensure that entire record fits */
2014 if (ix+rlength > nwords) {
2015 /* doesn't fit, adjust cookie and break */
2017 fprintf(stderr, "BOGUS: 0 length record\n");
2023 /* print the record */
2024 DisplayRecord(outFilep, &bufferp[ix], rlength);
2026 } /* for loop displaying buffer */
2031 /* see if things have changed */
2032 code = afs_syscall(AFSCALL_ICL, ICL_OP_GETLOGINFO,
2033 (long) logname, (long) &newBufferSize,
2034 (long) &allocated, 0);
2037 if (errno == ENOENT)
2038 (void) fprintf(stderr, "'%s' not found\n", logname);
2040 (void) fprintf(stderr, "cannot get information on log '%s' (errno = %d)\n",
2048 (void) fprintf(stderr, "'%s' no int32er allocated\n", logname);
2053 if (bufferSize == 0)
2055 (void) fprintf(stderr, "buffer size has become 0\n");
2059 if (bufferSize != newBufferSize)
2061 /* have to reallocate a buffer */
2062 bufferSize = newBufferSize;
2064 bufferp = (afs_int32 *) malloc(sizeof(afs_int32) * bufferSize);
2067 (void) fprintf(stderr, "cannot allocate %d words for buffer\n",
2073 } /* infinite loop */
2080 #if !defined(AFS_SGI_ENV)
2081 afs_syscall(call, parm0, parm1, parm2, parm3, parm4, parm5, parm6)
2082 long call, parm0, parm1, parm2, parm3, parm4, parm5, parm6;
2085 #ifdef AFS_LINUX20_ENV
2086 #if defined AFS_LINUX_64BIT_KERNEL
2088 /* don't want to sign extend it to 64bit, so using ulong */
2089 eparm[0] = (unsigned long)parm3;
2090 eparm[1] = (unsigned long)parm4;
2091 eparm[2] = (unsigned long)parm5;
2092 eparm[3] = (unsigned long)parm6;
2100 /* Linux can only handle 5 arguments in the actual syscall. */
2101 if (call == AFSCALL_ICL) {
2102 code = syscall(AFS_SYSCALL, call, parm0, parm1, parm2, eparm);
2105 code = syscall(AFS_SYSCALL, call, parm0, parm1, parm2, parm3);
2107 #if defined(AFS_SPARC64_LINUX20_ENV) || defined(AFS_SPARC_LINUX20_ENV)
2108 /* on sparc this function returns none value, so do it myself */
2109 __asm__ __volatile__ ("
2116 #if !defined(AFS_SGI_ENV) && !defined(AFS_AIX32_ENV)
2117 code = syscall(AFS_SYSCALL, call, parm0, parm1, parm2, parm3, parm4);
2119 #if defined(AFS_SGI_ENV)
2120 code = syscall(AFS_ICL, call, parm0, parm1, parm2, parm3, parm4); /* XXX */
2122 code = syscall(AFSCALL_ICL, parm0, parm1, parm2, parm3, parm4);
2126 #endif /* AFS_LINUX20_ENV */
2133 /* init function, called once, under icl_lock */
2139 /* setup signal handler, in user space */
2145 icl_CreateSet(name, baseLogp, fatalLogp, outSetpp)
2147 struct afs_icl_log *baseLogp;
2148 struct afs_icl_log *fatalLogp;
2149 struct afs_icl_set **outSetpp;
2151 return icl_CreateSetWithFlags(name, baseLogp, fatalLogp, /*flags*/0, outSetpp);
2154 /* create a set, given pointers to base and fatal logs, if any.
2155 * Logs are unlocked, but referenced, and *outSetpp is returned
2156 * referenced. Function bumps reference count on logs, since it
2157 * addds references from the new icl_set. When the set is destroyed,
2158 * those references will be released.
2160 icl_CreateSetWithFlags(name, baseLogp, fatalLogp, flags, outSetpp)
2162 struct afs_icl_log *baseLogp;
2163 struct afs_icl_log *fatalLogp;
2165 struct afs_icl_set **outSetpp;
2167 register struct afs_icl_set *setp;
2169 afs_int32 states = ICL_DEFAULT_SET_STATES;
2171 if (!icl_inited) icl_Init();
2173 for (setp = icl_allSets; setp; setp = setp->nextp) {
2174 if (strcmp(setp->name, name) == 0) {
2177 if (flags & ICL_CRSET_FLAG_PERSISTENT)
2179 setp->states |= ICL_SETF_PERSISTENT;
2185 /* determine initial state */
2186 if (flags & ICL_CRSET_FLAG_DEFAULT_ON)
2187 states = ICL_SETF_ACTIVE;
2188 else if (flags & ICL_CRSET_FLAG_DEFAULT_OFF)
2189 states = ICL_SETF_FREED;
2190 if (flags & ICL_CRSET_FLAG_PERSISTENT)
2191 states |= ICL_SETF_PERSISTENT;
2193 setp = (struct afs_icl_set *) osi_Alloc(sizeof(struct afs_icl_set));
2194 memset((caddr_t)setp, 0, sizeof(*setp));
2196 if (states & ICL_SETF_FREED)
2197 states &= ~ICL_SETF_ACTIVE; /* if freed, can't be active */
2198 setp->states = states;
2200 setp->name = (char *)osi_Alloc(strlen(name)+1);
2201 strcpy(setp->name, name);
2202 setp->nevents = ICL_DEFAULTEVENTS;
2203 setp->eventFlags = (char *)osi_Alloc(ICL_DEFAULTEVENTS);
2204 for(i=0; i<ICL_DEFAULTEVENTS; i++)
2205 setp->eventFlags[i] = 0xff; /* default to enabled */
2207 /* update this global info under the icl_lock */
2208 setp->nextp = icl_allSets;
2211 /* set's basic lock is still held, so we can finish init */
2213 setp->logs[0] = baseLogp;
2214 icl_LogHold(baseLogp);
2215 if (!(setp->states & ICL_SETF_FREED))
2216 icl_LogUse(baseLogp); /* log is actually being used */
2219 setp->logs[1] = fatalLogp;
2220 icl_LogHold(fatalLogp);
2221 if (!(setp->states & ICL_SETF_FREED))
2222 icl_LogUse(fatalLogp); /* log is actually being used */
2229 /* function to change event enabling information for a particular set */
2230 icl_SetEnable(setp, eventID, setValue)
2231 struct afs_icl_set *setp;
2237 if (!ICL_EVENTOK(setp, eventID)) {
2240 tp = &setp->eventFlags[ICL_EVENTBYTE(eventID)];
2242 *tp |= ICL_EVENTMASK(eventID);
2244 *tp &= ~(ICL_EVENTMASK(eventID));
2248 /* return indication of whether a particular event ID is enabled
2249 * for tracing. If *getValuep is set to 0, the event is disabled,
2250 * otherwise it is enabled. All events start out enabled by default.
2252 icl_GetEnable(setp, eventID, getValuep)
2253 struct afs_icl_set *setp;
2257 if (!ICL_EVENTOK(setp, eventID)) {
2260 if (setp->eventFlags[ICL_EVENTBYTE(eventID)] & ICL_EVENTMASK(eventID))
2267 /* hold and release event sets */
2269 register struct afs_icl_set *setp;
2275 /* free a set. Called with icl_lock locked */
2277 register struct afs_icl_set *setp;
2279 register struct afs_icl_set **lpp, *tp;
2281 register struct afs_icl_log *tlp;
2283 for(lpp = &icl_allSets, tp = *lpp; tp; lpp = &tp->nextp, tp = *lpp) {
2285 /* found the dude we want to remove */
2287 osi_Free(setp->name, 1+strlen(setp->name));
2288 osi_Free(setp->eventFlags, ICL_EVENTBYTES(setp->nevents));
2289 for(i=0; i < ICL_LOGSPERSET; i++) {
2290 if (tlp = setp->logs[i])
2293 osi_Free(setp, sizeof(struct afs_icl_set));
2294 break; /* won't find it twice */
2300 /* do the release, watching for deleted entries */
2302 register struct afs_icl_set *setp;
2304 if (--setp->refCount == 0 && (setp->states & ICL_SETF_DELETED)) {
2305 icl_ZapSet(setp); /* destroys setp's lock! */
2310 /* free a set entry, dropping its reference count */
2312 register struct afs_icl_set *setp;
2314 setp->states |= ICL_SETF_DELETED;
2319 /* find a set by name, returning it held */
2320 struct afs_icl_set *icl_FindSet(name)
2323 register struct afs_icl_set *tp;
2325 for(tp = icl_allSets; tp; tp=tp->nextp) {
2326 if (strcmp(tp->name, name) == 0) {
2327 /* this is the dude we want */
2335 /* zero out all the logs in the set */
2337 struct afs_icl_set *setp;
2342 struct afs_icl_log *logp;
2344 for(i = 0; i < ICL_LOGSPERSET; i++) {
2345 logp = setp->logs[i];
2348 tcode = icl_ZeroLog(logp);
2349 if (tcode != 0) code = tcode; /* save the last bad one */
2356 icl_EnumerateSets(aproc, arock)
2360 register struct afs_icl_set *tp, *np;
2361 register afs_int32 code;
2364 for(tp = icl_allSets; tp; tp=np) {
2365 tp->refCount++; /* hold this guy */
2366 code = (*aproc)(tp->name, arock, tp);
2367 np = tp->nextp; /* tp may disappear next, but not np */
2368 if (--tp->refCount == 0 && (tp->states & ICL_SETF_DELETED))
2375 icl_AddLogToSet(setp, newlogp)
2376 struct afs_icl_set *setp;
2377 struct afs_icl_log *newlogp;
2381 struct afs_icl_log *logp;
2383 for(i = 0; i < ICL_LOGSPERSET; i++) {
2384 if (!setp->logs[i]) {
2385 setp->logs[i] = newlogp;
2387 icl_LogHold(newlogp);
2388 if (!(setp->states & ICL_SETF_FREED)) {
2389 /* bump up the number of sets using the log */
2390 icl_LogUse(newlogp);
2398 icl_SetSetStat(setp, op)
2399 struct afs_icl_set *setp;
2404 struct afs_icl_log *logp;
2407 case ICL_OP_SS_ACTIVATE: /* activate a log */
2409 * If we are not already active, see if we have released
2410 * our demand that the log be allocated (FREED set). If
2411 * we have, reassert our desire.
2413 if (!(setp->states & ICL_SETF_ACTIVE)) {
2414 if (setp->states & ICL_SETF_FREED) {
2415 /* have to reassert desire for logs */
2416 for(i = 0; i < ICL_LOGSPERSET; i++) {
2417 logp = setp->logs[i];
2424 setp->states &= ~ICL_SETF_FREED;
2426 setp->states |= ICL_SETF_ACTIVE;
2431 case ICL_OP_SS_DEACTIVATE: /* deactivate a log */
2432 /* this doesn't require anything beyond clearing the ACTIVE flag */
2433 setp->states &= ~ICL_SETF_ACTIVE;
2437 case ICL_OP_SS_FREE: /* deassert design for log */
2439 * if we are already in this state, do nothing; otherwise
2440 * deassert desire for log
2442 if (setp->states & ICL_SETF_ACTIVE)
2445 if (!(setp->states & ICL_SETF_FREED)) {
2446 for(i = 0; i < ICL_LOGSPERSET; i++) {
2447 logp = setp->logs[i];
2450 icl_LogFreeUse(logp);
2454 setp->states |= ICL_SETF_FREED;
2467 struct afs_icl_log *afs_icl_allLogs = 0;
2469 /* hold and release logs */
2471 register struct afs_icl_log *logp;
2477 /* hold and release logs, called with lock already held */
2479 register struct afs_icl_log *logp;
2485 /* keep track of how many sets believe the log itself is allocated */
2487 register struct afs_icl_log *logp;
2489 if (logp->setCount == 0) {
2490 /* this is the first set actually using the log -- allocate it */
2491 if (logp->logSize == 0) {
2492 /* we weren't passed in a hint and it wasn't set */
2493 logp->logSize = ICL_DEFAULT_LOGSIZE;
2495 logp->datap = (afs_int32 *) osi_Alloc(sizeof(afs_int32) * logp->logSize);
2501 /* decrement the number of real users of the log, free if possible */
2502 icl_LogFreeUse(logp)
2503 register struct afs_icl_log *logp;
2505 if (--logp->setCount == 0) {
2506 /* no more users -- free it (but keep log structure around)*/
2507 osi_Free(logp->datap, sizeof(afs_int32) * logp->logSize);
2508 logp->firstUsed = logp->firstFree = 0;
2509 logp->logElements = 0;
2510 logp->datap = (afs_int32 *)0;
2515 /* set the size of the log to 'logSize' */
2516 icl_LogSetSize(logp, logSize)
2517 register struct afs_icl_log *logp;
2521 /* nothing to worry about since it's not allocated */
2522 logp->logSize = logSize;
2526 logp->firstUsed = logp->firstFree = 0;
2527 logp->logElements = 0;
2529 /* free and allocate a new one */
2530 osi_Free(logp->datap, sizeof(afs_int32) * logp->logSize);
2531 logp->datap = (afs_int32 *) osi_Alloc(sizeof(afs_int32) * logSize);
2532 logp->logSize = logSize;
2538 /* free a log. Called with icl_lock locked. */
2540 register struct afs_icl_log *logp;
2542 register struct afs_icl_log **lpp, *tp;
2544 for(lpp = &afs_icl_allLogs, tp = *lpp; tp; lpp = &tp->nextp, tp = *lpp) {
2546 /* found the dude we want to remove */
2548 osi_Free(logp->name, 1+strlen(logp->name));
2549 osi_Free(logp->datap, logp->logSize * sizeof(afs_int32));
2550 osi_Free(logp, sizeof(struct icl_log));
2551 break; /* won't find it twice */
2557 /* do the release, watching for deleted entries */
2559 register struct afs_icl_log *logp;
2561 if (--logp->refCount == 0 && (logp->states & ICL_LOGF_DELETED)) {
2562 icl_ZapLog(logp); /* destroys logp's lock! */
2567 /* do the release, watching for deleted entries, log already held */
2569 register struct afs_icl_log *logp;
2571 if (--logp->refCount == 0 && (logp->states & ICL_LOGF_DELETED)) {
2572 icl_ZapLog(logp); /* destroys logp's lock! */
2577 /* zero out the log */
2579 register struct afs_icl_log *logp;
2581 logp->firstUsed = logp->firstFree = 0;
2582 logp->logElements = 0;
2586 /* free a log entry, and drop its reference count */
2588 register struct afs_icl_log *logp;
2590 logp->states |= ICL_LOGF_DELETED;
2596 icl_EnumerateLogs(aproc, arock)
2600 register struct afs_icl_log *tp;
2601 register afs_int32 code;
2604 for(tp = afs_icl_allLogs; tp; tp=tp->nextp) {
2605 tp->refCount++; /* hold this guy */
2606 code = (*aproc)(tp->name, arock, tp);
2607 if (--tp->refCount == 0)
2615 afs_icl_bulkSetinfo_t *GetBulkSetInfo()
2617 unsigned int infoSize;
2619 infoSize = sizeof(afs_icl_bulkSetinfo_t) +
2620 (ICL_RPC_MAX_SETS-1) * sizeof(afs_icl_setinfo_t);
2623 setInfo = (afs_icl_bulkSetinfo_t *)malloc(infoSize);
2626 (void) fprintf(stderr, "Could not allocate the memory for bulk set info structure\n");
2630 memset((char *)setInfo, 0, infoSize);
2635 afs_icl_bulkLoginfo_t *GetBulkLogInfo()
2636 { unsigned int infoSize;
2638 infoSize = sizeof(afs_icl_bulkLoginfo_t) +
2639 (ICL_RPC_MAX_LOGS-1) * sizeof(afs_icl_loginfo_t);
2642 logInfo = (afs_icl_bulkLoginfo_t *)malloc(infoSize);
2645 (void) fprintf(stderr, "Could not allocate the memory for bulk log info structure\n");
2650 memset((char *)logInfo, 0, infoSize);
2655 static DoDump(as, arock)
2656 register struct cmd_syndesc *as;
2661 afs_int32 waitTime = 10 /* seconds */;
2665 FILE *outfp = stdout;
2667 struct cmd_item * itemp;
2669 if (geteuid() != 0) {
2670 printf("fstrace must be run as root\n");
2674 if (as->parms[3].items) {
2675 if (!as->parms[1].items)
2677 (void) fprintf(stderr, "-sleep can only be used with -follow\n");
2680 waitTime = strtol(as->parms[3].items->data,
2684 if (as->parms[2].items)
2686 /* try to open the specified output file */
2687 if ((outfp = fopen(as->parms[2].items->data, "w")) == NULL)
2689 (void) fprintf(stderr, "Cannot open file '%s' for writing\n",
2690 as->parms[2].items->data);
2694 #ifdef AFS_SGI64_ENV
2695 startTime = time((time_t *) 0);
2697 startTime = time(0);
2699 (void) fprintf(outfp, "AFS Trace Dump -\n\n Date: %s\n",
2702 if (as->parms[0].items)
2704 for (itemp = as->parms[0].items; itemp; itemp = itemp->next)
2706 tcode = icl_DumpKernel(outfp, itemp->data);
2709 (void) fprintf(stderr, "Unable to dump set %s (errno = %d)\n",
2710 itemp->data, errno);
2714 } else if (as->parms[1].items) {
2715 logname = as->parms[1].items->data;
2716 code = icl_TailKernel(outfp, logname, waitTime);
2718 (void) fprintf(stderr, "Error tailing kernel log '%s' (errno = %d)\n",
2722 code = icl_DumpKernel(outfp, NULL);
2724 (void) fprintf(outfp, "\nAFS Trace Dump - %s\n",
2725 code ? "FAILED" : "Completed");
2727 if (outfp != stdout)
2728 (void) fclose(outfp);
2733 static void SetUpDump()
2735 struct cmd_syndesc *dumpSyntax;
2737 dumpSyntax = cmd_CreateSyntax("dump", DoDump, (char *)NULL, "dump AFS trace logs");
2738 (void)cmd_AddParm(dumpSyntax, "-set", CMD_LIST, CMD_OPTIONAL, "set_name");
2739 (void)cmd_AddParm(dumpSyntax, "-follow", CMD_SINGLE, CMD_OPTIONAL, "log_name");
2740 (void)cmd_AddParm(dumpSyntax, "-file", CMD_SINGLE, CMD_OPTIONAL, "output_filename");
2741 (void)cmd_AddParm(dumpSyntax, "-sleep", CMD_SINGLE, CMD_OPTIONAL, "seconds_between_reads");
2744 static DoShowLog(as, arock)
2745 register struct cmd_syndesc *as;
2748 afs_int32 retVal = 0;
2753 struct cmd_item * itemp;
2755 if (geteuid() != 0) {
2756 printf("fstrace must be run as root\n");
2759 if (as->parms[2].items) int32flg = 1;
2761 if (as->parms[0].items) {
2762 /* enumerate logs for the specified sets */
2763 for (itemp = as->parms[0].items; itemp; itemp = itemp->next) {
2764 (void) fprintf(stdout, "Logs for set '%s':\n", itemp->data);
2765 code = icl_ListLogsBySet(stdout, itemp->data, int32flg);
2767 (void) fprintf(stderr, "Error in enumerating set %s (errno = %d)\n",
2768 itemp->data, errno);
2773 else if (as->parms[1].items) {
2774 /* print out log information */
2775 for (itemp = as->parms[1].items; itemp; itemp = itemp->next) {
2776 code = icl_GetLogsize(itemp->data, &logSize, &allocated);
2778 (void) fprintf(stdout, "%s : %d kbytes (%s)\n", itemp->data,
2779 logSize/1024, allocated ? "allocated" : "unallocated");
2781 (void) fprintf(stderr, "Could not find log '%s' (errno = %d)\n",
2782 itemp->data, errno);
2789 (void) fprintf(stdout, "Available logs:\n");
2790 code = icl_ListLogs(stdout, int32flg);
2792 (void) fprintf(stderr, "Error in listing logs (errno = %d)\n", errno);
2800 static void SetUpShowLog()
2802 struct cmd_syndesc *showSyntax;
2804 showSyntax = cmd_CreateSyntax("lslog", DoShowLog, (char *)NULL,"list available logs");
2805 (void)cmd_AddParm(showSyntax, "-set", CMD_LIST, CMD_OPTIONAL,"set_name");
2806 (void)cmd_AddParm(showSyntax, "-log", CMD_LIST, CMD_OPTIONAL,"log_name");
2807 (void)cmd_AddParm(showSyntax, "-long", CMD_FLAG, CMD_OPTIONAL,"");
2810 static DoShowSet(as, arock)
2811 register struct cmd_syndesc *as;
2814 afs_int32 retVal = 0;
2817 struct cmd_item * itemp;
2819 if (geteuid() != 0) {
2820 printf("fstrace must be run as root\n");
2823 if (as->parms[0].items) {
2824 /* print information on the specified sets */
2825 for (itemp = as->parms[0].items; itemp; itemp = itemp->next) {
2826 code = icl_GetSetState(itemp->data, &state);
2828 (void) fprintf(stderr, "Error getting status on set %s (errno = %d)\n",
2829 itemp->data, errno);
2833 (void) fprintf(stdout, "Set %s: %s%s%s\n", itemp->data,
2834 (state & ICL_SETF_ACTIVE) ? "active" : "inactive",
2835 (state & ICL_SETF_FREED) ? " (dormant)" : "",
2836 (state & ICL_SETF_PERSISTENT) ? " persistent" : "");
2841 (void) fprintf(stdout, "Available sets:\n");
2842 code = icl_ListSets(stdout);
2844 (void) fprintf(stderr, "Error in listing sets (errno = %d)\n", errno);
2852 static void SetUpShowSet()
2854 struct cmd_syndesc *showSyntax;
2856 showSyntax = cmd_CreateSyntax("lsset", DoShowSet, (char *)NULL, "list available event sets");
2857 (void)cmd_AddParm(showSyntax, "-set", CMD_LIST, CMD_OPTIONAL, "set_name");
2860 static DoClear(as, arock)
2861 register struct cmd_syndesc *as;
2864 afs_int32 retVal = 0;
2866 struct cmd_item * itemp;
2868 if (geteuid() != 0) {
2869 printf("fstrace must be run as root\n");
2872 if (as->parms[0].items) {
2873 /* clear logs for the specified sets */
2874 for (itemp = as->parms[0].items; itemp; itemp = itemp->next) {
2875 code = icl_ClearSet(itemp->data);
2877 (void) fprintf(stderr, "Error in clearing set %s (errno = %d)\n",
2878 itemp->data, errno);
2882 } else if (as->parms[1].items) {
2883 /* clear specified log */
2884 for (itemp = as->parms[0].items; itemp; itemp = itemp->next) {
2885 code = icl_ClearLog(itemp->data);
2887 (void) fprintf(stderr, "Error in clearing log %s (errno = %d)\n",
2888 itemp->data, errno);
2894 /* clear all logs */
2895 code = icl_ClearAll();
2897 (void) fprintf(stderr, "Error in clearing logs (errno = %d)\n", errno);
2905 static void SetUpClear()
2907 struct cmd_syndesc *clearSyntax;
2909 clearSyntax = cmd_CreateSyntax("clear", DoClear, (char *)NULL, "clear logs by logname or by event set");
2910 (void)cmd_AddParm(clearSyntax, "-set", CMD_LIST, CMD_OPTIONAL,"set_name");
2911 (void)cmd_AddParm(clearSyntax, "-log", CMD_LIST, CMD_OPTIONAL, "log_name");
2914 static DoSet(as, arock)
2915 register struct cmd_syndesc *as;
2918 afs_int32 retVal = 0;
2923 struct cmd_item * itemp;
2925 if (geteuid() != 0) {
2926 printf("fstrace must be run as root\n");
2929 if (as->parms[1].items) {
2930 op = ICL_OP_SS_ACTIVATE;
2931 operation = "active";
2932 } else if (as->parms[2].items) {
2933 op = ICL_OP_SS_DEACTIVATE;
2934 operation = "inactive";
2935 } else if (as->parms[3].items) {
2936 op = ICL_OP_SS_DEACTIVATE;
2937 operation = "inactive";
2940 /* assume active" */
2941 op = ICL_OP_SS_ACTIVATE;
2942 operation = "active";
2945 if (as->parms[0].items) {
2946 /* activate specified sets */
2947 for (itemp = as->parms[0].items; itemp; itemp = itemp->next) {
2948 code = icl_ChangeSetState(itemp->data, op);
2950 (void) fprintf(stderr, "cannot set state of %s to %s (errno = %d)\n",
2951 itemp->data, operation, errno);
2955 /* try to make it dormant as well */
2956 code = icl_ChangeSetState(itemp->data, ICL_OP_SS_FREE);
2958 (void) fprintf(stderr, "cannot set state of %s to dormant (errno = %d)\n",
2959 itemp->data, errno);
2967 code = icl_ChangeAllSetState(op);
2969 (void) fprintf(stderr, "cannot set the state of all sets to %s (errno = %d)\n",
2974 /* try to make it dormant as well */
2975 code = icl_ChangeAllSetState(ICL_OP_SS_FREE);
2977 (void) fprintf(stderr, "cannot set the state of all sets to dormant (errno = %d)\n", errno);
2986 static void SetUpSet()
2988 struct cmd_syndesc *setSyntax;
2990 setSyntax = cmd_CreateSyntax("setset", DoSet, (char *)NULL,"set state of event sets");
2991 (void)cmd_AddParm(setSyntax, "-set", CMD_LIST, CMD_OPTIONAL,"set_name");
2992 (void)cmd_AddParm(setSyntax, "-active", CMD_FLAG, CMD_OPTIONAL,"");
2993 (void)cmd_AddParm(setSyntax, "-inactive", CMD_FLAG, CMD_OPTIONAL, "");
2994 (void)cmd_AddParm(setSyntax, "-dormant", CMD_FLAG, CMD_OPTIONAL,"");
2997 static DoResize(as, arock)
2998 register struct cmd_syndesc *as;
3001 afs_int32 retVal = 0;
3003 afs_int32 bufferSize;
3004 struct cmd_item * itemp;
3006 if (geteuid() != 0) {
3007 printf("fstrace must be run as root\n");
3010 /* get buffer size */
3011 bufferSize = atoi(as->parms[1].items->data);
3012 bufferSize *= BUFFER_MULTIPLIER;
3013 if (bufferSize == 0)
3014 bufferSize = ICL_DEFAULT_LOGSIZE;
3016 /* set the size of the specified logs */
3017 if (itemp = as->parms[0].items) {
3018 for (; itemp; itemp = itemp->next) {
3019 code = icl_ChangeLogSize(itemp->data, bufferSize);
3021 (void) fprintf(stderr, "Error in changing log %s buffer size (errno = %d)\n",
3022 itemp->data, errno);
3027 /* Use the only current support log, "cmfx" */
3028 code = icl_ChangeLogSize("cmfx", bufferSize);
3030 (void) fprintf(stderr, "Error in changing log cmfx buffer size (errno = %d)\n", errno);
3038 static void SetUpResize()
3040 struct cmd_syndesc *setsizeSyntax;
3042 setsizeSyntax = cmd_CreateSyntax("setlog", DoResize, (char *)NULL, "set the size of a log");
3043 (void)cmd_AddParm(setsizeSyntax, "-log", CMD_LIST, CMD_OPTIONAL,"log_name");
3044 (void)cmd_AddParm(setsizeSyntax, "-buffersize", CMD_SINGLE, CMD_REQUIRED, "1-kilobyte_units");
3047 #include "AFS_component_version_number.c"
3053 setlocale(LC_ALL, "");
3054 #ifdef AFS_SGI62_ENV
3055 set_kernel_sizeof_long();
3058 /* set up user interface then dispatch */
3066 return(cmd_Dispatch(argc, argv));
3069 #include "AFS_component_version_number.c"
3072 printf("fstrace is NOT supported for this OS\n");