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>
18 #include <sys/types.h>
20 #if !defined(AFS_SUN3_ENV) && !defined(sys_vax_ul43)
22 /*#ifdef AFS_AIX_ENV*/
33 #include <afs/afs_args.h>
35 #include <afs/afsutil.h>
38 #include <afs/sys_prototypes.h>
40 #if defined(AFS_OSF_ENV) || defined(AFS_SGI61_ENV) || (defined(AFS_AIX51_ENV) && defined(AFS_64BIT_KERNEL))
41 /* For SGI 6.2, this is changed to 1 if it's a 32 bit kernel. */
42 int afs_icl_sizeofLong = 2;
44 int afs_icl_sizeofLong = 1;
47 #if defined(AFS_SGI61_ENV) || (defined(AFS_AIX51_ENV) && defined(AFS_64BIT_KERNEL))
48 int afs_64bit_kernel = 1; /* Default for 6.2+, and always for 6.1 */
49 extern int afs_icl_sizeofLong; /* Used in ICL_SIZEHACK() */
53 /* If _SC_KERN_POINTERS not in sysconf, then we can assume a 32 bit abi. */
55 set_kernel_sizeof_long(void)
60 retval = sysconf(_SC_KERN_POINTERS);
63 afs_icl_sizeofLong = 2;
66 afs_icl_sizeofLong = 1;
70 #endif /* AFS_SGI62_ENV */
71 #endif /* AFS_SGI61_ENV */
73 int afs_syscall(long call, long parm0, long parm1, long parm2, long parm3,
74 long parm4, long parm5, long parm6);
75 void dce1_error_inq_text(afs_uint32 status_to_convert,
76 char *error_text, int *status);
77 int icl_CreateSetWithFlags(char *name, struct afs_icl_log *baseLogp,
78 struct afs_icl_log *fatalLogp, afs_uint32 flags,
79 struct afs_icl_set **outSetpp);
80 int icl_LogHold(register struct afs_icl_log *logp);
81 int icl_LogUse(register struct afs_icl_log *logp);
82 int icl_LogReleNL(register struct afs_icl_log *logp);
83 int icl_LogRele(register struct afs_icl_log *logp);
84 int icl_ZeroLog(register struct afs_icl_log *logp);
85 int icl_LogFreeUse(register struct afs_icl_log *logp);
87 #define BUFFER_MULTIPLIER 1024
89 /* make it big enough to snapshot everything at once, since
90 * decoding takes so long.
92 #define IBSIZE 100000 /* default size */
95 struct logInfo *nextp;
99 char dumpFileName[256] = "";
101 RegisterIclDumpFileName(char *name)
103 (void)sprintf(dumpFileName, "icl.%.250s", name);
106 /* define globals to use for bulk info */
107 afs_icl_bulkSetinfo_t *setInfo = (afs_icl_bulkSetinfo_t *) 0;
108 afs_icl_bulkLoginfo_t *logInfo = (afs_icl_bulkLoginfo_t *) 0;
110 struct afs_icl_set *icl_allSets = 0;
114 /* given a type and an address, get the size of the thing
118 icl_GetSize(afs_int32 type, char *addr)
124 ICL_SIZEHACK(type, addr);
128 /* Check types in printf string "bufferp", making sure that each
129 * is compatible with the corresponding parameter type described
130 * by typesp. Also watch for prematurely running out of parameters
131 * before the string is gone.
133 #if defined(AFS_SGI61_ENV) || (defined(AFS_AIX51_ENV) && defined(AFS_64BIT_KERNEL))
135 CheckTypes(char *bufferp, int *typesp, int typeCount, char *outMsgBuffer)
143 for (tc = *bufferp;; outMsgBuffer++, tc = *(++bufferp)) {
146 /* hit end of string. We win as long as we aren't
155 inPercent = 1 - inPercent;
159 if (tc >= '0' && tc <= '9') {
160 /* skip digits in % string */
165 /* 'l' is a type modifier. */
169 /* otherwise, we've finally gotten to the type-describing
170 * character. Make sure there's a type descriptor, and then
171 * check the type descriptor.
175 return 0; /* no more type descriptors left */
177 if (typesp[tix] != 1) /* not a string descriptor */
180 *outMsgBuffer = (char)1;
182 if (tc == 'u' || tc == 'x' || tc == 'd' || tc == 'o') {
183 if (typesp[tix] != 0)
184 return 0; /* not an integer descriptor */
188 *outMsgBuffer = (char)2;
191 *outMsgBuffer = (char)3;
194 *outMsgBuffer = (char)4;
198 *outMsgBuffer = (char)5;
202 /* otherwise we're fine, so eat this descriptor */
208 #else /* AFS_SGI61_ENV */
210 CheckTypes(char *bufferp, int *typesp, int typeCount)
218 for (tc = *bufferp;; tc = *(++bufferp)) {
220 /* hit end of string. We win as long as we aren't
229 inPercent = 1 - inPercent;
233 if (tc >= '0' && tc <= '9')
234 continue; /* skip digits in % string */
235 /* otherwise, we've finally gotten to the type-describing
236 * character. Make sure there's a type descriptor, and then
237 * check the type descriptor.
241 return 0; /* no more type descriptors left */
242 if (tc == 's' && typesp[tix] != 1) /* not a string descriptor */
244 if ((tc == 'u' || tc == 'l' || tc == 'x' || tc == 'd')
245 && (typesp[tix] != 0))
246 return 0; /* not an integer descriptor */
247 /* otherwise we're fine, so eat this descriptor */
253 #endif /* AFS_SGI61_ENV */
255 /* display a single record.
256 * alp points at the first word in the array to be interpreted
257 * rsize gives the # of words in the array
259 #if defined(AFS_SGI61_ENV) && !defined(AFS_SGI62_ENV)
260 #define uint64_t long long
263 DisplayRecord(FILE *outFilep, register afs_int32 *alp, afs_int32 rsize)
265 char msgBuffer[1024];
266 #if defined(AFS_SGI61_ENV) || (defined(AFS_AIX51_ENV) && defined(AFS_64BIT_KERNEL))
267 char outMsgBuffer[1024];
269 uint64_t printfParms[ICL_MAXEXPANSION * /* max parms */ 4];
270 char *printfStrings[ICL_MAXEXPANSION * /* max parms */ 4];
271 #else /* AFS_SGI61_ENV */
272 long printfParms[ICL_MAXEXPANSION * /* max parms */ 4];
273 #endif /* AFS_SGI61_ENV */
274 int printfTypes[ICL_MAXEXPANSION * 4];
280 int pix; /* index in alp */
281 int pfpix; /* index in printfParms */
282 int pftix; /* index in printfTypes */
284 int printed; /* did we print the string yet? */
287 /* decode parameters */
288 temp = alp[0]; /* type encoded in low-order 24 bits, t0 high */
294 for (i = 0; i < 4 * ICL_MAXEXPANSION; i++)
296 /* decode each parameter, getting addrs for afs_hyper_t and strings */
297 for (i = 0; !done && i < 4; i++) {
298 type = (temp >> (18 - i * 6)) & 0x3f;
304 case ICL_TYPE_POINTER:
305 printfTypes[pftix++] = 0;
306 #if defined(AFS_SGI61_ENV) || (defined(AFS_AIX51_ENV) && defined(AFS_64BIT_KERNEL))
307 printfParms[pfpix] = alp[pix];
308 printfParms[pfpix] &= 0xffffffff;
309 if (afs_64bit_kernel) {
310 printfParms[pfpix] <<= 32;
311 printfParms[pfpix] |= alp[pix + 1];
313 #elif defined(AFS_OSF_ENV)
314 printfParms[pfpix] = alp[pix + 1];
315 printfParms[pfpix] |= (alp[pix] <<= 32);
316 #else /* !AFS_OSF_ENV && !AFS_SGI61_ENV */
317 printfParms[pfpix] = alp[pix];
322 printfTypes[pftix++] = 0;
323 printfParms[pfpix++] = alp[pix];
327 printfTypes[pftix++] = 0;
328 printfParms[pfpix++] = alp[pix];
329 printfTypes[pftix++] = 0;
330 printfParms[pfpix++] = alp[pix + 1];
333 printfTypes[pftix++] = 0;
334 printfParms[pfpix++] = alp[pix];
335 printfTypes[pftix++] = 0;
336 printfParms[pfpix++] = alp[pix + 1];
337 printfTypes[pftix++] = 0;
338 printfParms[pfpix++] = alp[pix + 2];
339 printfTypes[pftix++] = 0;
340 printfParms[pfpix++] = alp[pix + 3];
342 case ICL_TYPE_STRING:
343 printfTypes[pftix++] = 1;
345 printfStrings[pfpix++] = (char *)&alp[pix];
346 #else /* AFS_SGI64_ENV */
347 #if defined(AFS_SGI61_ENV) || (defined(AFS_AIX51_ENV) && defined(AFS_64BIT_KERNEL))
348 printfStrings[pfpix++] = (char *)&alp[pix];
349 #else /* AFS_SGI61_ENV */
350 printfParms[pfpix++] = (long)&alp[pix];
351 #endif /* AFS_SGI61_ENV */
352 #endif /* AFS_SGI64_ENV */
354 case ICL_TYPE_UNIXDATE:
356 printfParms[pfpix++] = (long)ctime(&tmv);
359 printf("DisplayRecord: Bad type %d in decode switch.\n", type);
366 pix += icl_GetSize(type, (char *)&alp[pix]);
369 /* next, try to decode the opcode into a printf string */
370 dce1_error_inq_text(alp[1], msgBuffer, &status);
372 /* if we got a string back, and it is compatible with the
373 * parms we've got, then print it.
377 #if defined(AFS_SGI61_ENV) || (defined(AFS_AIX51_ENV) && defined(AFS_64BIT_KERNEL))
378 if (CheckTypes(msgBuffer, printfTypes, pftix, outMsgBuffer)) {
379 /* we have a string to use, but it ends "(dfs / zcm)",
380 * so we remove the extra gunk.
382 j = strlen(outMsgBuffer);
384 outMsgBuffer[j - 11] = 0;
388 fprintf(outFilep, "time %d.%06d, pid %u: ", alp[3] / 1000000,
389 alp[3] % 1000000, alp[2]);
390 for (i = 0; i < j; i++) {
391 if ((int)outMsgBuffer[i] > 5)
392 fputc(outMsgBuffer[i], outFilep);
394 switch (outMsgBuffer[i]) {
398 fprintf(outFilep, "%s", printfStrings[pfpix++]);
400 case 2: /* signed integer */
401 fprintf(outFilep, "%" AFS_INT64_FMT, printfParms[pfpix++]);
403 case 3: /* unsigned integer */
404 fprintf(outFilep, "%llu", printfParms[pfpix++]);
406 case 4: /* octal integer */
407 fprintf(outFilep, "%llo", printfParms[pfpix++]);
409 case 5: /* hex integer */
410 fprintf(outFilep, "%llx", printfParms[pfpix++]);
414 "fstrace: Bad char %d in outMsgBuffer for parm %d\n",
415 outMsgBuffer[i], pfpix);
416 fprintf(outFilep, "fstrace: msgBuffer='%s'\n",
422 fprintf(outFilep, "\n");
425 #else /* AFS_SGI61_ENV */
426 if (CheckTypes(msgBuffer, printfTypes, pftix)) {
427 /* we have a string to use, but it ends "(dfs / zcm)",
428 * so we remove the extra gunk.
430 j = strlen(msgBuffer);
432 msgBuffer[j - 11] = 0;
433 fprintf(outFilep, "time %d.%06d, pid %u: ", alp[3] / 1000000,
434 alp[3] % 1000000, alp[2]);
435 fprintf(outFilep, msgBuffer, printfParms[0], printfParms[1],
436 printfParms[2], printfParms[3], printfParms[4],
437 printfParms[5], printfParms[6], printfParms[7],
438 printfParms[8], printfParms[9], printfParms[10],
439 printfParms[11], printfParms[12], printfParms[13],
440 printfParms[14], printfParms[15]);
441 fprintf(outFilep, "\n");
444 #endif /* AFS_SGI61_ENV */
446 fprintf(outFilep, "Type mismatch, using raw print.\n");
447 fprintf(outFilep, "%s", msgBuffer);
451 if (alp[1] == ICL_INFO_TIMESTAMP) {
453 fprintf(outFilep, "time %d.%06d, pid %u: %s\n", alp[3] / 1000000,
454 alp[3] % 1000000, alp[2], ctime(&tmv));
456 fprintf(outFilep, "raw op %d, time %d.%06d, pid %u\n", alp[1],
457 alp[3] / 1000000, alp[3] % 1000000, alp[2]);
458 /* now decode each parameter and print it */
461 for (i = 0; !done && i < 4; i++) {
462 type = (temp >> (18 - i * 6)) & 0x3f;
468 fprintf(outFilep, "p%d:%d ", i, alp[pix]);
472 tempParam = alp[pix];
474 tempParam |= alp[pix + 1];
475 fprintf(outFilep, "p%d:%" AFS_INT64_FMT " ", i, tempParam);
476 #else /* AFS_SGI61_ENV */
477 fprintf(outFilep, "p%d:%d ", i, alp[pix]);
478 #endif /* AFS_SGI61_ENV */
480 case ICL_TYPE_POINTER:
482 tempParam = alp[pix];
484 tempParam |= alp[pix + 1];
485 fprintf(outFilep, "p%d:0x%llx ", i, tempParam);
486 #else /* AFS_SGI61_ENV */
487 fprintf(outFilep, "p%d:0x%x ", i, alp[pix]);
488 #endif /* AFS_SGI61_ENV */
492 fprintf(outFilep, "p%d:%x.%x ", i, alp[pix],
496 fprintf(outFilep, "p%d:%d.%d.%d.%d ", i, alp[pix],
497 alp[pix + 1], alp[pix + 2], alp[pix + 3]);
499 case ICL_TYPE_STRING:
500 fprintf(outFilep, "p%d:%s ", i, (char *)&alp[pix]);
502 case ICL_TYPE_UNIXDATE:
504 fprintf(outFilep, "p%d:%s ", i,
509 ("DisplayRecord: Bad type %d in raw print switch.\n",
517 pix += icl_GetSize(type, (char *)&alp[pix]);
520 fprintf(outFilep, "\n"); /* done with line */
530 #include <nl_types.h>
532 #if defined(AFS_OSF_ENV) && !defined(AFS_OSF20_ENV)
534 static nl_catd catopen1();
536 static nl_catd _do1_open();
537 static nl_catd cat_already_open();
538 static int make_sets();
539 static FILE *open1catfile();
540 static void add_open_cat();
541 static void cat_hard_close();
542 extern char *strchr();
544 static int catpid[NL_MAXOPEN];
545 static CATD *catsopen[NL_MAXOPEN];
546 #define PATH_FORMAT "/usr/lib/nls/msg/%L/%N:/etc/nls/msg/%L/%N"
547 #define DEFAULT_LANG "C"
548 #define TOO_MANY_HOLES(num_holes, num_non_holes) \
549 (((num_holes) > 100) && ((num_holes) > (num_non_holes)))
553 /*---- n: the number of bytes to be malloc'ed ----*/
557 t = (char *)malloc(n);
559 printf("Failed to get mem\n");
566 catopen1(char *cat, int dummy)
567 /*---- char *cat: the name of the cat to be opened ----*/
568 /*---- int dummy: dummy variable ----*/
572 nl_catd _do_open(); /*---- routine that actually opens
579 if (catd = cat_already_open(cat)) {
580 catd->_count = catd->_count + 1;
584 catd = (CATD *) rmalloc(sizeof(CATD));
587 catd->_name = (char *)rmalloc(strlen(cat) + 1);
588 if (catd->_name == NULL)
590 strcpy(catd->_name, cat);
592 catd->_magic = CAT_MAGIC;
594 #ifndef AFS_OSF20_ENV
595 catd->_pid = getpid();
598 if (_do1_open(catd) != CATD_ERR)
610 _do1_open(nl_catd catd)
611 /*---- pointer to the partially set up cat descriptor ----*/
613 int make_sets(); /*---- routine to unpack the sets into
614 fast acccess mode ----*/
615 void add_open_cat(); /*---- routine to keep a list of
618 int i; /*---- Misc counter(s) used for loop */
625 catd->_fd = open1catfile(catd->_name);
629 fread((void *)&magic, (size_t) 4, (size_t) 1, catd->_fd);
630 if (magic != CAT_MAGIC) {
631 printf("Magic was %x instead of %x -> %x\n", magic, CAT_MAGIC,
639 /* if ((catd->_mem = shmat((int)fileno(catd->_fd), NULL, SHM_MAP | SHM_RDONLY))
640 == (char * )ERR ) { */
642 if (1) { /* disable the shmat, share memory segemnt */
644 /*______________________________________________________________________
645 If the file can not be mapped then simulate mapping for the index
646 table so that make_sets cat set things up. (rmalloc an area big
647 enough for the index table and read the whole thing in)
648 ______________________________________________________________________*/
650 /* reset the file pointer to the beginning of catalog */
651 fseek(catd->_fd, (long)0, 0);
653 /* malloc the header, if fails return error */
654 catd->_hd = (struct _header *)rmalloc(sizeof(struct _header));
655 if (catd->_hd == NULL)
658 /* read in the whole header */
659 fread((void *)catd->_hd, (size_t) sizeof(struct _header), (size_t) 1,
662 /* cs is a dummpy to hold a set temperorily. The purpose of */
663 /* this for loop is to fread the whole catalog so that the */
664 /* file pointer will be moved to the end of the catalog. */
665 for (i = 0; i < catd->_hd->_n_sets; i++) {
666 fread((void *)&cs, (size_t) 4, (size_t) 1, catd->_fd);
667 fseek(catd->_fd, (long)(cs._n_msgs * sizeof(struct _msgptr)), 1);
670 /* after the for loop, ftell returns the byte offset of the */
671 /* end of the catalog relative to the begining of the file. */
672 /* i.e. i contains the byte offset of the whole catalog. */
673 i = ftell(catd->_fd);
675 /* malloc _mem as a temp pointer to hold the entire catalog. */
676 catd->_mem = (char *)rmalloc(i);
677 if (catd->_mem == NULL)
680 /* reset the file pointer to the begining. */
681 fseek(catd->_fd, (long)0, 0);
683 /* read in the whole catalog into _mem */
684 fread((void *)catd->_mem, (size_t) i, (size_t) 1, catd->_fd);
687 * If there aren't many holes in the set numbers,
688 * fully expand the compacted set array from the
689 * catalog. Then in catgets(), we'll be able to use
690 * the set number to index directly into the expanded
693 * If there are a lot of holes, leave the set array
694 * compacted. In catgets(), we'll search through it
695 * for the requested set.
698 num_holes = catd->_hd->_setmax - catd->_hd->_n_sets;
699 if (!TOO_MANY_HOLES(num_holes, catd->_hd->_n_sets)) {
700 catd->_sets_expanded = TRUE;
701 catd->_n_sets = catd->_hd->_setmax;
703 catd->_sets_expanded = FALSE;
704 catd->_n_sets = catd->_hd->_n_sets - 1;
707 /* malloc one extra set more than the max. set index */
709 (struct _catset *)rmalloc((catd->_n_sets + 1) *
710 sizeof(struct _catset));
711 if (catd->_set == NULL)
714 /* save the max. set number in catd->_setmax */
715 catd->_setmax = catd->_hd->_setmax;
716 /* call make_set to malloc memory for every message */
717 if (make_sets(catd) == -1)
725 /*______________________________________________________________________
726 Normal mapping has occurred, set a few things up and call make_sets
727 ______________________________________________________________________*/
729 catd->_hd = (struct _header *)(catd->_mem);
730 catd->_setmax = catd->_hd->_setmax;
732 (struct _catset *)rmalloc((catd->_hd->_setmax + 1) *
733 sizeof(struct _catset));
734 if (catd->_set == NULL)
736 if (make_sets(catd) == -1)
745 add_open_cat(nl_catd catd)
746 /*---- catd to be added to the list of catalogs ----*/
748 int i = 0; /*---- Misc counter(s) used for loops ----*/
749 while (i < NL_MAXOPEN && catsopen[i]) {
750 if (!strcmp(catd->_name, catsopen[i]->_name)
751 #ifndef AFS_OSF20_ENV
752 && getpid() == catsopen[i]->_pid)
756 return; /*---- The catalog is already here ----*/
760 if (i < NL_MAXOPEN) {
762 catpid[i] = getpid();
771 * FUNCTION: Expands the compacted version of the catalog index table into
772 * the fast access memory version.
774 * EXECUTION ENVIRONMENT:
776 * Make_set executes under a process.
783 make_sets(nl_catd catd)
785 struct _catset *cset;
786 char *base = catd->_mem;
787 int n_sets = catd->_hd->_n_sets;
788 int i; /*---- Misc counter(s) used for loops ----*/
789 int j; /*---- Misc counter(s) used for loops ----*/
790 int msgmax; /*---- The maximum number of _messages in a set ----*/
791 char *cmpct_set_ptr; /*---- pointer into the index table ----*/
792 struct _catset cs; /*---- used to look at the sets in the table -*/
795 cmpct_set_ptr = base + sizeof(struct _header);
797 for (i = 0; i < n_sets; i++) {
798 /* loop through each compacted set */
800 cs = *(struct _catset *)cmpct_set_ptr;
801 /* set the _catset ptr to the base of the current
805 (struct _msgptr *)(cmpct_set_ptr + 2 * sizeof(unsigned short));
806 /* set the ms array ptr to the base of
807 * compacted array of _msgptr's */
810 (catd->_sets_expanded) ? &catd->_set[cs._setno] : &catd->_set[i];
813 * If there aren't many holes in the message numbers,
814 * fully expand the compacted message array from the
815 * catalog. Then in catgets(), we'll be able to use
816 * the message number to index directly into the
819 * If there are many holes, leave the message array
820 * compacted. In catgets(), we'll search through it
821 * for the requested message.
824 msgmax = cs._mp[cs._n_msgs - 1]._msgno;
825 num_holes = msgmax - cs._n_msgs;
826 if (!TOO_MANY_HOLES(num_holes, cs._n_msgs)) {
827 cset->_msgs_expanded = TRUE;
828 cset->_n_msgs = msgmax;
830 cset->_msgs_expanded = FALSE;
831 cset->_n_msgs = cs._n_msgs - 1;
835 (struct _msgptr *)rmalloc((1 + cset->_n_msgs) *
836 sizeof(struct _msgptr));
837 if (cset->_mp == NULL)
841 (char **)rmalloc((1 + cset->_n_msgs) * sizeof(char *));
842 if (cset->_msgtxt == NULL)
845 if (cset->_msgs_expanded) {
846 for (j = 0; j < cs._n_msgs; j++) {
847 cset->_mp[cs._mp[j]._msgno] = cs._mp[j];
850 for (j = 0; j < cs._n_msgs; j++) {
851 cset->_mp[j] = cs._mp[j];
855 cset->_setno = cs._setno;
856 /* Superfluous but should have the correct data. Increment
857 * the base of the set pointer. */
860 2 * sizeof(unsigned short) + cs._n_msgs * sizeof(struct _msgptr);
871 * FUNCTION: Opens a catalog file, looking in the language path first (if
872 * there is no slash) and returns a pointer to the file stream.
874 * EXECUTION ENVIRONMENT:
876 * Opencatfile executes under a process.
878 * RETURNS: Returns a pointer to the file stream, and a NULL pointer on
883 open1catfile(char *file)
885 extern char *getenv();
886 char fl[PATH_MAX]; /*---- place to hold full path ----*/
887 char *nlspath; /*---- pointer to the nlspath val ----*/
888 FILE *fp; /*---- file pointer ----*/
889 char cpth[PATH_MAX]; /*---- current value of nlspath ----*/
891 char *fulllang; /* %L language value */
892 char lang[PATH_MAX]; /* %l language value */
893 char *territory; /* %t language value */
894 char *codeset; /* %c language value */
895 char *ptr; /* for decompose of $LANG */
900 char outptr[PATH_MAX];
903 if (strchr(file, '/')) {
904 if ((fp = fopen(file, "r"))) {
905 fcntl(fileno(fp), F_SETFD, 1);
906 /* set the close-on-exec flag for
911 if (!(nlspath = getenv("NLSPATH")))
912 nlspath = PATH_FORMAT;
913 if (!(fulllang = getenv("LANG")))
914 fulllang = DEFAULT_LANG;
915 if (fulllang == DEFAULT_LANG)
916 nlspath = PATH_FORMAT; /* if fullang is C, use the
917 * the default nlspath: */
920 ** LANG is a composite of three fields:
921 ** language_territory.codeset
922 ** and we're going to break it into those
926 strcpy(lang, fulllang);
931 ptr = strchr(lang, '_');
935 ptr = strchr(territory, '.');
941 ptr = strchr(lang, '.');
951 while (*np && *np != ':')
954 if (*np) /*---- iff on a colon then advance --*/
962 while (*ptr != '\0') {
963 while ((*ptr != '\0') && (*ptr != '%')
964 && (nchars < PATH_MAX)) {
965 *(optr++) = *(ptr++);
993 lenstr = strlen(str);
995 if (nchars < PATH_MAX) {
1003 if (nchars >= PATH_MAX) {
1009 strcpy(cpth, outptr);
1010 } else { /*---- iff leading | trailing |
1011 adjacent colons ... --*/
1015 if (valid == 1 && (fp = fopen(cpth, "r"))) {
1016 fcntl(fileno(fp), F_SETFD, 1);
1017 /* set the close-on-exec flag for
1022 if (fp = fopen(file, "r")) {
1023 fcntl(fileno(fp), F_SETFD, 1);
1024 /* set the close-on-exec flag for
1038 * NAME: cat_already_open
1040 * FUNCTION: Checkes to see if a specific cat has already been opened.
1042 * EXECUTION ENVIRONMENT:
1044 * Cat_already_open executes under a process.
1046 * RETURNS: Returns a pointer to the existing CATD if one exists, and
1047 * a NULL pointer if no CATD exists.
1051 cat_already_open(char *cat)
1052 /*---- name of the catalog to be opened ----*/
1054 int i; /*---- Misc counter(s) used for loops ----*/
1056 for (i = 0; i < NL_MAXOPEN && catsopen[i]; i++) {
1057 #ifndef AFS_OSF20_ENV
1058 if (!strcmp(cat, catsopen[i]->_name) && getpid() == catsopen[i]->_pid) {
1060 if (!strcmp(cat, catsopen[i]->_name)) {
1062 return (catsopen[i]);
1070 catclose1(nl_catd catd)
1071 /*---- the catd to be closed ----*/
1076 if (catd == CATD_ERR)
1078 for (i = 0; i < NL_MAXOPEN && catsopen[i]; i++) {
1079 #ifndef AFS_OSF20_ENV
1080 if (catd == catsopen[i] && getpid() == catsopen[i]->_pid)
1082 if (catd == catsopen[i])
1086 if (i == NL_MAXOPEN || catsopen[i] == NULL)
1088 if (catd->_fd == (FILE *) NULL)
1089 /*---- return if this is an extra open or
1090 a bad catalog discriptor ----*/
1092 if (cat_already_open(catd->_name)) {
1093 if (catd->_count == 1) {
1094 cat_hard_close(catd);
1095 return (0); /*--- the last legal clsoe ---*/
1096 } else if (catd->_count > 1) {
1097 catd->_count = catd->_count - 1;
1098 return (0); /*--- a legal close ---*/
1100 return (-1); /*--- an extra illegal close ---*/
1107 cat_hard_close(nl_catd catd)
1108 /*---- the catd to be closed ----*/
1110 int i; /*---- Misc counter(s) used for loops ----*/
1111 int j; /*---- Misc counter ----*/
1113 if (catd == CATD_ERR)
1116 /*______________________________________________________________________
1117 remove any entry for the catalog in the catsopen array
1118 ______________________________________________________________________*/
1120 for (i = 0; i < NL_MAXOPEN && catsopen[i]; i++) {
1121 if (catd == catsopen[i]) {
1122 for (; i < NL_MAXOPEN - 1; i++) {
1123 catsopen[i] = catsopen[i + 1];
1124 catpid[i] = catpid[i + 1];
1131 /*______________________________________________________________________
1132 close the cat and free up the memory
1133 ______________________________________________________________________*/
1134 if (catd->_mem == FALSE) {
1135 for (i = 0; i <= catd->_n_sets; i++) {
1136 if (catd->_set[i]._mp)
1137 free(catd->_set[i]._mp);
1138 /*---- free the _message pointer arrays ----*/
1140 if (catd->_set[i]._msgtxt) {
1141 for (j = 0; j <= catd->_set[i]._n_msgs; j++) {
1142 if (catd->_set[i]._msgtxt[j]) {
1143 /* free(catd->_set[i]._msgtxt[j]);*/
1146 if (catd->_set[i]._msgtxt)
1147 free(catd->_set[i]._msgtxt);
1153 fclose(catd->_fd); /*---- close the ctatlog ----*/
1155 free(catd->_set); /*---- free the sets ----*/
1157 free(catd->_name); /*---- free the name ----*/
1159 free(catd->_hd); /*---- free the header ----*/
1161 free(catd); /*---- free the catd ----*/
1165 _do1_read_msg(nl_catd catd, int setno, int msgno)
1166 /*---- catd: the catd of the catalog to be read from ----*/
1167 /*---- setno: the set number of the message ----*/
1168 /*---- msgno: the msgno of the message ----*/
1170 nl_catd catd1; /*--- catd for different process ----*/
1173 #ifndef AFS_OSF20_ENV
1174 if (getpid() == catd->_pid)
1178 return (_read1_msg(catd, setno, msgno));
1181 * Since our pid is different from the one in
1182 * catd, catd must have come from a catopen()
1183 * in our parent. We need a catd of our own.
1184 * The first time through here, the call to
1185 * catopen() creates a new catd and we try to
1186 * open its message catalog. After that, the
1187 * catopen() just retrieves the catd.
1189 if (((catd1 = catopen1(catd->_name, 0)) != CATD_ERR)
1190 && ((catd1->_fd == NL_FILE_CLOSED && _do1_open(catd1) != CATD_ERR)
1191 || (catd1->_fd != NL_FILE_UNUSED)))
1192 return (_read1_msg(catd1, setno, msgno));
1199 struct _catset *_cat1_get_catset();
1200 static struct _msgptr *_cat1_get_msgptr();
1202 _read1_msg(nl_catd catd, int setno, int msgno)
1204 struct _catset *set; /*--- ptr to set's _catset structure ---*/
1205 struct _msgptr *msg; /*--- ptr to msg's _msgptr structure ---*/
1206 char **msgtxt; /*--- temporary pointer to the message text
1209 set = _cat1_get_catset(catd, setno);
1211 msg = _cat1_get_msgptr(set, msgno);
1213 msgtxt = &set->_msgtxt[msg - set->_mp];
1214 if (1 /*!*msgtxt */ ) {
1215 *msgtxt = (char *)malloc(msg->_msglen + 1);
1219 fseek(catd->_fd, (long)msg->_offset, 0);
1221 ((void *)*msgtxt, (size_t) (msg->_msglen + 1), (size_t) 1,
1233 * NAME: compare_sets
1235 * FUNCTION: Compare function used by bsearch() in _cat_get_catset().
1238 * key - pointer to set number we're searching for
1239 * element - pointer to current _catset structure
1241 * RETURNS: Returns -1, 0, or 1, depending on whether the set number
1242 * is less than, equal to, or greater than the set number of
1243 * the _catset structure.
1248 compare_sets(const void *key, const void *element)
1250 int *setno = (int *)key;
1251 struct _catset *set = (struct _catset *)element;
1253 if (*setno < set->_setno)
1255 if (*setno > set->_setno)
1263 * NAME: _cat_get_catset
1265 * FUNCTION: Find a set in the catd->_set array. Assumes that the
1266 * sets in the array are sorted by increasing set number.
1269 * catd - catalog descripter obtained from catopen()
1270 * setno - message catalogue set number
1272 * RETURNS: Returns a pointer to the set on success.
1273 * On any error, returns NULL.
1278 _cat1_get_catset(nl_catd catd, int setno)
1280 struct _catset *set;
1282 if ((catd == (nl_catd) NULL) || (catd == CATD_ERR))
1283 return (struct _catset *)NULL;
1285 if (catd->_sets_expanded) {
1286 if ((setno < 0) || (setno > catd->_n_sets))
1287 return (struct _catset *)NULL;
1289 set = &catd->_set[setno];
1292 * Catch empty elements in the array. They aren't
1296 if (set->_mp == (struct _msgptr *)NULL)
1297 return (struct _catset *)NULL;
1300 (struct _catset *)bsearch((void *)&setno, catd->_set,
1302 sizeof(struct _catset), compare_sets);
1305 * Since the sets are compacted, there aren't any
1306 * empty elements in the array to check for.
1315 * NAME: compare_msgs
1317 * FUNCTION: Compare function used by bsearch() in _cat_get_msgptr().
1320 * key - pointer to message number we're searching for
1321 * element - pointer to current _msgptr structure
1323 * RETURNS: Returns -1, 0, or 1, depending on whether the message
1324 * number is less than, equal to, or greater than the message
1325 * number of the _msgptr structure.
1330 compare_msgs(const void *key, const void *element)
1332 int *msgno = (int *)key;
1333 struct _msgptr *msg = (struct _msgptr *)element;
1335 if (*msgno < msg->_msgno)
1337 if (*msgno > msg->_msgno)
1344 * NAME: _cat1_get_msgptr
1346 * FUNCTION: Find a message in a set's set->_mp array. Assumes that
1347 * the messages in the array are sorted by increasing
1351 * set - ptr to _catset structure
1352 * msgno - message catalogue message number
1354 * RETURNS: Returns a pointer to the message on success.
1355 * On any error, returns NULL.
1358 static struct _msgptr *
1359 _cat1_get_msgptr(struct _catset *set, int msgno)
1361 struct _msgptr *msg;
1363 if (set == (struct _catset *)NULL)
1364 return (struct _msgptr *)NULL;
1366 if (set->_mp == (struct _msgptr *)NULL) /* empty set */
1367 return (struct _msgptr *)NULL;
1369 if (set->_msgs_expanded) {
1370 if ((msgno < 0) || (msgno > set->_n_msgs))
1371 return (struct _msgptr *)NULL;
1373 msg = &set->_mp[msgno];
1376 * Catch empty elements in the array. They aren't
1381 return (struct _msgptr *)NULL;
1384 (struct _msgptr *)bsearch((void *)&msgno, set->_mp,
1386 sizeof(struct _msgptr), compare_msgs);
1389 * Since the messages are compacted, there aren't any
1390 * empty elements in the array to check for.
1398 catgets1(nl_catd catd, int setno, int msgno, char *def)
1399 /*---- catd: the catd to get the message from ----*/
1400 /*---- setno: the set number of the message ----*/
1401 /*---- msgno: the message number of the message ----*/
1402 /*---- def: the default string to be returned ----*/
1405 char *_do_read_msg();
1409 if (catd == NULL || catd == CATD_ERR || catd->_magic != CAT_MAGIC
1410 || catd->_fd == NL_FILE_UNUSED) {
1413 if (catd->_fd == NL_FILE_CLOSED) {
1414 catd = _do1_open(catd);
1415 if (catd == CATD_ERR)
1419 if (catd->_mem) { /*---- for mapped files ----*/
1420 if (setno <= catd->_hd->_setmax) {
1421 if (msgno < catd->_set[setno]._n_msgs) {
1422 if (catd->_set[setno]._mp[msgno]._offset) {
1423 return (catd->_mem +
1424 catd->_set[setno]._mp[msgno]._offset);
1429 } else { /*---- for unmapped files ----*/
1430 m = _do1_read_msg(catd, setno, msgno);
1440 #define FACILITY_CODE_MASK 0xF0000000
1441 #define FACILITY_CODE_SHIFT 28
1443 #define COMPONENT_CODE_MASK 0x0FFFF000
1444 #define COMPONENT_CODE_SHIFT 12
1446 #define STATUS_CODE_MASK 0x00000FFF
1447 #define STATUS_CODE_SHIFT 0
1449 #define NO_MESSAGE "THIS IS NOT A MESSAGE"
1452 * The system-dependant location for the catalog files is defined in sysconf.h
1453 * RPC_DEFAULT_NLSPATH should be defined in sysconf.h. Otherwise we use
1454 * /usr/afs/etc/C/%s.cat
1457 #ifndef RPC_NLS_FORMAT
1458 #define RPC_NLS_FORMAT "%s.cat"
1462 dce1_error_inq_text(afs_uint32 status_to_convert,
1463 char *error_text, int *status)
1465 unsigned short facility_code;
1466 unsigned short component_code;
1467 unsigned short status_code;
1468 unsigned short i, failed = 0;
1470 char component_name[4];
1471 char *facility_name;
1472 char filename_prefix[7];
1473 char nls_filename[11];
1474 char alt_filename[80];
1476 #if defined(AFS_64BITPOINTER_ENV)
1481 static char *facility_names[] = {
1487 * set up output status for future error returns
1489 if (status != NULL) {
1493 * check for ok input status
1495 if (status_to_convert == 0) {
1496 if (status != NULL) {
1499 strcpy((char *)error_text, "successful completion");
1504 * extract the component, facility and status codes
1507 (status_to_convert & FACILITY_CODE_MASK) >> FACILITY_CODE_SHIFT;
1509 (status_to_convert & COMPONENT_CODE_MASK) >> COMPONENT_CODE_SHIFT;
1510 status_code = (status_to_convert & STATUS_CODE_MASK) >> STATUS_CODE_SHIFT;
1513 * see if this is a recognized facility
1515 if (facility_code == 0
1516 || facility_code > sizeof(facility_names) / sizeof(char *)) {
1517 sprintf((char *)error_text, "status %08x (unknown facility)",
1521 facility_name = facility_names[facility_code - 1];
1523 * Convert component name from RAD-50 component code. (Mapping is:
1524 * 0 => 'a', ..., 25 => 'z', 26 => '{', 27 => '0', ..., 36 => '9'.)
1526 component_name[3] = 0;
1527 component_name[2] = component_code % 40;
1528 component_code /= 40;
1529 component_name[1] = component_code % 40;
1530 component_name[0] = component_code / 40;
1531 for (i = 0; i < 3; i++) {
1532 component_name[i] += (component_name[i] <= 26) ? 'a' : ('0' - 27);
1534 sprintf(filename_prefix, "%3s%3s", facility_name, component_name);
1535 sprintf(nls_filename, RPC_NLS_FORMAT, filename_prefix);
1538 * Open the message file
1540 #if defined(AFS_OSF_ENV)
1541 #if defined(AFS_OSF20_ENV)
1542 catd = (nl_catd) catopen(nls_filename, 0);
1544 catd = (nl_catd) catopen1(nls_filename, 0);
1547 #if defined(AFS_64BITPOINTER_ENV)
1548 J = (long)catopen(nls_filename, 0);
1550 J = (int)catopen(nls_filename, 0);
1554 if (catd == (nl_catd) - 1) {
1556 * If we did not succeed in opening message file using NLSPATH,
1557 * try to open the message file in a well-known default area
1560 #ifndef RPC_DEFAULT_NLSPATH
1561 sprintf(alt_filename, "%s/C/%s.cat", AFSDIR_CLIENT_ETC_DIRPATH,
1564 sprintf(alt_filename, RPC_DEFAULT_NLSPATH, filename_prefix);
1567 #if defined(AFS_OSF_ENV)
1568 #if defined(AFS_OSF20_ENV)
1569 catd = (nl_catd) catopen(alt_filename, 0);
1571 catd = (nl_catd) catopen1(alt_filename, 0);
1574 #if defined(AFS_64BITPOINTER_ENV)
1575 J = (long)catopen(alt_filename, 0);
1577 J = (int)catopen(alt_filename, 0);
1581 if (catd == (nl_catd) - 1) {
1582 sprintf((char *)error_text, "status %08x (%s / %s)",
1583 status_to_convert, facility_name, component_name);
1588 * try to get the specified message from the file
1590 #if defined(AFS_OSF_ENV) && !defined(AFS_OSF20_ENV)
1591 message = (char *)catgets1(catd, 1, status_code, NO_MESSAGE);
1593 message = (char *)catgets(catd, 1, status_code, NO_MESSAGE);
1596 * if everything went well, return the resulting message
1598 if (strcmp(message, NO_MESSAGE) != 0) {
1599 sprintf((char *)error_text, "%s (%s / %s)", message, facility_name,
1601 if (status != NULL) {
1607 #if defined(AFS_OSF_ENV) && !defined(AFS_OSF20_ENV)
1614 sprintf((char *)error_text, "status %08x (%s / %s)",
1615 status_to_convert, facility_name, component_name);
1617 #if defined(AFS_OSF_ENV) && !defined(AFS_OSF20_ENV)
1626 icl_DumpKernel(FILE *outFilep, char *setname)
1628 afs_int32 bufferSize = 0;
1631 afs_int32 code, retVal = 0;
1636 afs_int32 dummy, dummy2;
1637 struct logInfo *lip;
1639 /* first, enumerate the logs we're interested in */
1642 /* dump logs for a particular set */
1643 for (i = 0; i < ICL_LOGSPERSET; i++) {
1645 afs_syscall(AFSCALL_ICL, ICL_OP_ENUMLOGSBYSET, (long)setname,
1646 i, (long)tname, sizeof(tname), 0, 0);
1648 if (errno == EBADF) {
1650 continue; /* missing slot, nothing to worry about */
1655 afs_syscall(AFSCALL_ICL, ICL_OP_GETLOGINFO, (long)tname,
1656 (long)&dummy, (long)&dummy2, 0, 0, 0);
1660 if (dummy > bufferSize) /* find biggest log */
1662 lip = (struct logInfo *)malloc(sizeof(struct logInfo));
1663 memset((char *)lip, 0, sizeof(*lip));
1664 lip->nextp = allInfo;
1666 lip->name = (char *)malloc(strlen(tname) + 1);
1667 strcpy(lip->name, tname);
1672 for (i = 0; i < 1000; i++) {
1674 afs_syscall(AFSCALL_ICL, ICL_OP_ENUMLOGS, i, (long)tname,
1675 sizeof(tname), (long)&dummy, 0, 0);
1678 if (dummy > bufferSize) /* find biggest log */
1680 lip = (struct logInfo *)malloc(sizeof(struct logInfo));
1681 memset((char *)lip, 0, sizeof(*lip));
1682 lip->nextp = allInfo;
1684 lip->name = (char *)malloc(strlen(tname) + 1);
1685 strcpy(lip->name, tname);
1689 if (bufferSize == 0)
1691 bufferp = (afs_int32 *) malloc(sizeof(afs_int32) * bufferSize);
1695 fprintf(outFilep, "Found %d logs.\n", i);
1697 /* now print out the contents of each log */
1698 for (lip = allInfo; lip; lip = lip->nextp) {
1699 fprintf(outFilep, "\nContents of log %s:\n", lip->name);
1700 /* read out everything first; gets a more consistent
1703 nwords = 0; /* total words copied out */
1705 /* display all the entries in the log */
1706 if (bufferSize - nwords <= 0)
1707 break; /* filled whole buffer */
1709 afs_syscall(AFSCALL_ICL, ICL_OP_COPYOUT, (long)lip->name,
1710 (long)(bufferp + nwords), bufferSize - nwords,
1713 /* otherwise we've got an error */
1714 fprintf(outFilep, "Returned error %d dumping log.\n", errno);
1717 /* otherwise, we have flags in the high order byte, and
1718 * a length (in words) in the remainder.
1720 if ((code >> 24) & ICL_COPYOUTF_MISSEDSOME)
1721 fprintf(outFilep, "Log wrapped; data missing.\n");
1729 } /* for loop over all cookies */
1731 /* otherwise we should display all of the log entries here.
1732 * Note that a record may end in the middle, in which case
1733 * we should start over with the cookie value of the start
1736 for (ix = 0; ix < nwords;) {
1737 /* start of a record */
1738 rlength = (bufferp[ix] >> 24) & 0xff;
1740 fprintf(outFilep, "Internal error: 0 length record\n");
1744 /* ensure that entire record fits */
1745 if (ix + rlength > nwords) {
1746 /* doesn't fit, adjust cookie and break */
1749 /* print the record */
1750 DisplayRecord(outFilep, &bufferp[ix], rlength);
1753 /* obsolete: read entire buffer first */
1754 i += rlength; /* update cookie value, too */
1756 } /* for loop displaying buffer */
1757 } /* for loop over all logs */
1764 /* clear out log 'name' */
1766 icl_ClearLog(char *name)
1770 code = afs_syscall(AFSCALL_ICL, ICL_OP_CLRLOG, (long)name, 0, 0, 0, 0, 0);
1774 /* clear out set 'name' */
1776 icl_ClearSet(char *name)
1780 code = afs_syscall(AFSCALL_ICL, ICL_OP_CLRSET, (long)name, 0, 0, 0, 0, 0);
1784 /* clear out all logs */
1790 code = afs_syscall(AFSCALL_ICL, ICL_OP_CLRALL, 0, 0, 0, 0, 0, 0);
1794 /* list out all available sets to outFileP */
1796 icl_ListSets(FILE *outFileP)
1803 for (i = 0; i < 1000; i++) {
1805 afs_syscall(AFSCALL_ICL, ICL_OP_ENUMSETS, i, (long)tname,
1806 sizeof(tname), (long)&states, 0, 0);
1809 (void)fprintf(outFileP, "%s %s%s%s\n", tname,
1810 (states & ICL_SETF_ACTIVE) ? "active" : "inactive",
1811 (states & ICL_SETF_FREED) ? " (dormant)" : "",
1812 (states & ICL_SETF_PERSISTENT) ? " persistent" : "");
1818 /* list out all available logs to outFileP */
1820 icl_ListLogs(FILE *outFileP, int int32flg)
1828 for (i = 0; i < 1000; i++) {
1830 afs_syscall(AFSCALL_ICL, ICL_OP_ENUMLOGS, i, (long)tname,
1831 sizeof(tname), (long)&logSize, 0, 0);
1835 /* get more information on the log */
1837 afs_syscall(AFSCALL_ICL, ICL_OP_GETLOGINFO, (long)tname,
1838 (long)&logSize, (long)&allocated, 0, 0, 0);
1841 (void)fprintf(outFileP, "%s : %d kbytes (%s)\n", tname,
1843 allocated ? "allocated" : "unallocated");
1845 (void)fprintf(outFileP, "%s\n", tname);
1851 /* list out all available logs to outFileP */
1853 icl_ListLogsBySet(FILE *outFileP, char *setname, int int32flg)
1861 for (i = 0; i < ICL_LOGSPERSET; i++) {
1863 afs_syscall(AFSCALL_ICL, ICL_OP_ENUMLOGSBYSET, (long)setname, i,
1864 (long)tname, sizeof(tname), 0, 0);
1866 if (errno == EBADF) {
1868 continue; /* missing */
1873 /* get more information on the log */
1875 afs_syscall(AFSCALL_ICL, ICL_OP_GETLOGINFO, (long)tname,
1876 (long)&logSize, (long)&allocated, 0, 0, 0);
1879 (void)fprintf(outFileP, "%s : %d kbytes (%s)\n", tname,
1881 allocated ? "allocated" : "unallocated");
1883 (void)fprintf(outFileP, "%s\n", tname);
1889 /* activate/deactivate/free specified set */
1891 icl_ChangeSetState(char *name, afs_int32 op)
1895 code = afs_syscall(AFSCALL_ICL, ICL_OP_SETSTAT, (long)name, op, 0, 0, 0, 0);
1899 /* activate/deactivate/free all sets */
1901 icl_ChangeAllSetState(afs_int32 op)
1905 code = afs_syscall(AFSCALL_ICL, ICL_OP_SETSTATALL, op, 0, 0, 0, 0, 0);
1909 /* set size if log */
1911 icl_ChangeLogSize(char *name, afs_int32 logSize)
1916 afs_syscall(AFSCALL_ICL, ICL_OP_SETLOGSIZE, (long)name, logSize, 0,
1921 /* get logsize of specified log */
1923 icl_GetLogsize(char *logname, afs_int32 *logSizeP, int *allocatedP)
1927 afs_syscall(AFSCALL_ICL, ICL_OP_GETLOGINFO, (long)logname,
1928 (long)logSizeP, (long)allocatedP, 0, 0, 0);
1932 /* get state of specified set */
1934 icl_GetSetState(char *setname, afs_int32 *stateP)
1938 afs_syscall(AFSCALL_ICL, ICL_OP_GETSETINFO, (long)setname,
1939 (long)stateP, 0, 0, 0, 0);
1944 icl_TailKernel(FILE *outFilep, char *logname, afs_int32 waitTime)
1946 afs_int32 bufferSize = 0;
1947 afs_int32 newBufferSize;
1950 afs_int32 code, retVal = 0;
1956 /* get information about the specified log */
1958 afs_syscall(AFSCALL_ICL, ICL_OP_GETLOGINFO, (long)logname,
1959 (long)&bufferSize, (long)&allocated, 0, 0, 0);
1961 if (errno == ENOENT)
1962 (void)fprintf(stderr, "'%s' not found\n", logname);
1964 (void)fprintf(stderr,
1965 "cannot get information on log '%s' (errno = %d)\n",
1971 (void)fprintf(stderr, "'%s' not allocated\n", logname);
1975 if (bufferSize == 0)
1977 bufferp = (afs_int32 *) malloc(sizeof(afs_int32) * bufferSize);
1979 (void)fprintf(stderr, "cannot allocate %d words for buffer\n",
1984 /* start "infinite" loop */
1986 /* read out all that's currently there */
1987 nwords = 0; /* total words copied out */
1988 i = 0; /* initialize cookie */
1990 /* display all the entries in the log */
1991 if (bufferSize - nwords <= 0)
1992 break; /* filled whole buffer, clear when done */
1994 afs_syscall(AFSCALL_ICL, ICL_OP_COPYOUTCLR, (long)logname,
1995 (long)(bufferp + nwords), bufferSize - nwords,
1998 /* otherwise we've got an error */
1999 fprintf(stderr, "returned error %d dumping log.\n", errno);
2003 /* otherwise, we have flags in the high order byte, and
2004 * a length (in words) in the remainder.
2013 } /* for loop over all cookies */
2015 /* otherwise we should display all of the log entries here.
2016 * Note that a record may end in the middle, in which case
2017 * we should start over with the cookie value of the start
2020 for (ix = 0; ix < nwords;) {
2021 /* start of a record */
2022 rlength = (bufferp[ix] >> 24) & 0xff;
2023 /* ensure that entire record fits */
2024 if (ix + rlength > nwords) {
2025 /* doesn't fit, adjust cookie and break */
2027 fprintf(stderr, "BOGUS: 0 length record\n");
2033 /* print the record */
2034 DisplayRecord(outFilep, &bufferp[ix], rlength);
2036 } /* for loop displaying buffer */
2041 /* see if things have changed */
2043 afs_syscall(AFSCALL_ICL, ICL_OP_GETLOGINFO, (long)logname,
2044 (long)&newBufferSize, (long)&allocated, 0, 0, 0);
2046 if (errno == ENOENT)
2047 (void)fprintf(stderr, "'%s' not found\n", logname);
2049 (void)fprintf(stderr,
2050 "cannot get information on log '%s' (errno = %d)\n",
2057 (void)fprintf(stderr, "'%s' no int32er allocated\n", logname);
2062 if (bufferSize == 0) {
2063 (void)fprintf(stderr, "buffer size has become 0\n");
2067 if (bufferSize != newBufferSize) {
2068 /* have to reallocate a buffer */
2069 bufferSize = newBufferSize;
2071 bufferp = (afs_int32 *) malloc(sizeof(afs_int32) * bufferSize);
2073 (void)fprintf(stderr, "cannot allocate %d words for buffer\n",
2079 } /* infinite loop */
2086 #if !defined(AFS_SGI_ENV)
2088 afs_syscall(long call, long parm0, long parm1, long parm2, long parm3,
2089 long parm4, long parm5, long parm6)
2092 #ifdef AFS_LINUX20_ENV
2093 #if defined AFS_LINUX_64BIT_KERNEL
2095 /* don't want to sign extend it to 64bit, so using ulong */
2096 eparm[0] = (unsigned long)parm3;
2097 eparm[1] = (unsigned long)parm4;
2098 eparm[2] = (unsigned long)parm5;
2099 eparm[3] = (unsigned long)parm6;
2107 /* Linux can only handle 5 arguments in the actual syscall. */
2108 if (call == AFSCALL_ICL) {
2109 rval = proc_afs_syscall(call, parm0, parm1, parm2, eparm, &code);
2111 code = syscall(AFS_SYSCALL, call, parm0, parm1, parm2, eparm);
2113 rval = proc_afs_syscall(call, parm0, parm1, parm2, parm3, &code);
2115 code = syscall(AFS_SYSCALL, call, parm0, parm1, parm2, parm3);
2117 #if defined(AFS_SPARC64_LINUX20_ENV) || defined(AFS_SPARC_LINUX20_ENV)
2118 /* on sparc this function returns none value, so do it myself */
2119 __asm__ __volatile__("mov %o0, %i0; ret; restore");
2122 #ifdef AFS_DARWIN80_ENV
2123 code = ioctl_afs_syscall(call, parm0, parm1, parm2, parm3, parm4, parm5, &rval);
2124 if (!code) code = rval;
2126 #if !defined(AFS_SGI_ENV) && !defined(AFS_AIX32_ENV)
2127 code = syscall(AFS_SYSCALL, call, parm0, parm1, parm2, parm3, parm4);
2129 #if defined(AFS_SGI_ENV)
2130 code = syscall(AFS_ICL, call, parm0, parm1, parm2, parm3, parm4); /* XXX */
2132 code = syscall(AFSCALL_ICL, parm0, parm1, parm2, parm3, parm4);
2136 #endif /* AFS_LINUX20_ENV */
2144 /* init function, called once, under icl_lock */
2151 /* setup signal handler, in user space */
2158 icl_CreateSet(char *name, struct afs_icl_log *baseLogp,
2159 struct afs_icl_log *fatalLogp, struct afs_icl_set **outSetpp)
2161 return icl_CreateSetWithFlags(name, baseLogp, fatalLogp, /*flags */ 0,
2165 /* create a set, given pointers to base and fatal logs, if any.
2166 * Logs are unlocked, but referenced, and *outSetpp is returned
2167 * referenced. Function bumps reference count on logs, since it
2168 * addds references from the new icl_set. When the set is destroyed,
2169 * those references will be released.
2172 icl_CreateSetWithFlags(char *name, struct afs_icl_log *baseLogp,
2173 struct afs_icl_log *fatalLogp, afs_uint32 flags,
2174 struct afs_icl_set **outSetpp)
2176 register struct afs_icl_set *setp;
2178 afs_int32 states = ICL_DEFAULT_SET_STATES;
2183 for (setp = icl_allSets; setp; setp = setp->nextp) {
2184 if (strcmp(setp->name, name) == 0) {
2187 if (flags & ICL_CRSET_FLAG_PERSISTENT) {
2188 setp->states |= ICL_SETF_PERSISTENT;
2194 /* determine initial state */
2195 if (flags & ICL_CRSET_FLAG_DEFAULT_ON)
2196 states = ICL_SETF_ACTIVE;
2197 else if (flags & ICL_CRSET_FLAG_DEFAULT_OFF)
2198 states = ICL_SETF_FREED;
2199 if (flags & ICL_CRSET_FLAG_PERSISTENT)
2200 states |= ICL_SETF_PERSISTENT;
2202 setp = (struct afs_icl_set *)osi_Alloc(sizeof(struct afs_icl_set));
2203 memset((caddr_t) setp, 0, sizeof(*setp));
2205 if (states & ICL_SETF_FREED)
2206 states &= ~ICL_SETF_ACTIVE; /* if freed, can't be active */
2207 setp->states = states;
2209 setp->name = (char *)osi_Alloc(strlen(name) + 1);
2210 strcpy(setp->name, name);
2211 setp->nevents = ICL_DEFAULTEVENTS;
2212 setp->eventFlags = (char *)osi_Alloc(ICL_DEFAULTEVENTS);
2213 for (i = 0; i < ICL_DEFAULTEVENTS; i++)
2214 setp->eventFlags[i] = 0xff; /* default to enabled */
2216 /* update this global info under the icl_lock */
2217 setp->nextp = icl_allSets;
2220 /* set's basic lock is still held, so we can finish init */
2222 setp->logs[0] = baseLogp;
2223 icl_LogHold(baseLogp);
2224 if (!(setp->states & ICL_SETF_FREED))
2225 icl_LogUse(baseLogp); /* log is actually being used */
2228 setp->logs[1] = fatalLogp;
2229 icl_LogHold(fatalLogp);
2230 if (!(setp->states & ICL_SETF_FREED))
2231 icl_LogUse(fatalLogp); /* log is actually being used */
2238 /* function to change event enabling information for a particular set */
2240 icl_SetEnable(struct afs_icl_set *setp, afs_int32 eventID, int setValue)
2244 if (!ICL_EVENTOK(setp, eventID)) {
2247 tp = &setp->eventFlags[ICL_EVENTBYTE(eventID)];
2249 *tp |= ICL_EVENTMASK(eventID);
2251 *tp &= ~(ICL_EVENTMASK(eventID));
2255 /* return indication of whether a particular event ID is enabled
2256 * for tracing. If *getValuep is set to 0, the event is disabled,
2257 * otherwise it is enabled. All events start out enabled by default.
2260 icl_GetEnable(struct afs_icl_set *setp, afs_int32 eventID, int *getValuep)
2262 if (!ICL_EVENTOK(setp, eventID)) {
2265 if (setp->eventFlags[ICL_EVENTBYTE(eventID)] & ICL_EVENTMASK(eventID))
2272 /* hold and release event sets */
2274 icl_SetHold(register struct afs_icl_set *setp)
2280 /* free a set. Called with icl_lock locked */
2282 icl_ZapSet(register struct afs_icl_set *setp)
2284 register struct afs_icl_set **lpp, *tp;
2286 register struct afs_icl_log *tlp;
2288 for (lpp = &icl_allSets, tp = *lpp; tp; lpp = &tp->nextp, tp = *lpp) {
2290 /* found the dude we want to remove */
2292 osi_Free(setp->name, 1 + strlen(setp->name));
2293 osi_Free(setp->eventFlags, ICL_EVENTBYTES(setp->nevents));
2294 for (i = 0; i < ICL_LOGSPERSET; i++) {
2295 if ((tlp = setp->logs[i]))
2298 osi_Free(setp, sizeof(struct afs_icl_set));
2299 break; /* won't find it twice */
2305 /* do the release, watching for deleted entries */
2307 icl_SetRele(register struct afs_icl_set *setp)
2309 if (--setp->refCount == 0 && (setp->states & ICL_SETF_DELETED)) {
2310 icl_ZapSet(setp); /* destroys setp's lock! */
2315 /* free a set entry, dropping its reference count */
2317 icl_SetFree(register struct afs_icl_set *setp)
2319 setp->states |= ICL_SETF_DELETED;
2324 /* find a set by name, returning it held */
2325 struct afs_icl_set *
2326 icl_FindSet(char *name)
2328 register struct afs_icl_set *tp;
2330 for (tp = icl_allSets; tp; tp = tp->nextp) {
2331 if (strcmp(tp->name, name) == 0) {
2332 /* this is the dude we want */
2340 /* zero out all the logs in the set */
2342 icl_ZeroSet(struct afs_icl_set *setp)
2347 struct afs_icl_log *logp;
2349 for (i = 0; i < ICL_LOGSPERSET; i++) {
2350 logp = setp->logs[i];
2353 tcode = icl_ZeroLog(logp);
2355 code = tcode; /* save the last bad one */
2363 icl_EnumerateSets(int (*aproc) (char *, void *, struct afs_icl_set *),
2366 register struct afs_icl_set *tp, *np;
2367 register afs_int32 code;
2370 for (tp = icl_allSets; tp; tp = np) {
2371 tp->refCount++; /* hold this guy */
2372 code = (*aproc) (tp->name, arock, tp);
2373 np = tp->nextp; /* tp may disappear next, but not np */
2374 if (--tp->refCount == 0 && (tp->states & ICL_SETF_DELETED))
2383 icl_AddLogToSet(struct afs_icl_set *setp, struct afs_icl_log *newlogp)
2388 for (i = 0; i < ICL_LOGSPERSET; i++) {
2389 if (!setp->logs[i]) {
2390 setp->logs[i] = newlogp;
2392 icl_LogHold(newlogp);
2393 if (!(setp->states & ICL_SETF_FREED)) {
2394 /* bump up the number of sets using the log */
2395 icl_LogUse(newlogp);
2404 icl_SetSetStat(struct afs_icl_set *setp, int op)
2408 struct afs_icl_log *logp;
2411 case ICL_OP_SS_ACTIVATE: /* activate a log */
2413 * If we are not already active, see if we have released
2414 * our demand that the log be allocated (FREED set). If
2415 * we have, reassert our desire.
2417 if (!(setp->states & ICL_SETF_ACTIVE)) {
2418 if (setp->states & ICL_SETF_FREED) {
2419 /* have to reassert desire for logs */
2420 for (i = 0; i < ICL_LOGSPERSET; i++) {
2421 logp = setp->logs[i];
2428 setp->states &= ~ICL_SETF_FREED;
2430 setp->states |= ICL_SETF_ACTIVE;
2435 case ICL_OP_SS_DEACTIVATE: /* deactivate a log */
2436 /* this doesn't require anything beyond clearing the ACTIVE flag */
2437 setp->states &= ~ICL_SETF_ACTIVE;
2441 case ICL_OP_SS_FREE: /* deassert design for log */
2443 * if we are already in this state, do nothing; otherwise
2444 * deassert desire for log
2446 if (setp->states & ICL_SETF_ACTIVE)
2449 if (!(setp->states & ICL_SETF_FREED)) {
2450 for (i = 0; i < ICL_LOGSPERSET; i++) {
2451 logp = setp->logs[i];
2454 icl_LogFreeUse(logp);
2458 setp->states |= ICL_SETF_FREED;
2471 struct afs_icl_log *afs_icl_allLogs = 0;
2473 /* hold and release logs */
2475 icl_LogHold(register struct afs_icl_log *logp)
2481 /* hold and release logs, called with lock already held */
2483 icl_LogHoldNL(register struct afs_icl_log *logp)
2489 /* keep track of how many sets believe the log itself is allocated */
2491 icl_LogUse(register struct afs_icl_log *logp)
2493 if (logp->setCount == 0) {
2494 /* this is the first set actually using the log -- allocate it */
2495 if (logp->logSize == 0) {
2496 /* we weren't passed in a hint and it wasn't set */
2497 logp->logSize = ICL_DEFAULT_LOGSIZE;
2500 (afs_int32 *) osi_Alloc(sizeof(afs_int32) * logp->logSize);
2506 /* decrement the number of real users of the log, free if possible */
2508 icl_LogFreeUse(register struct afs_icl_log *logp)
2510 if (--logp->setCount == 0) {
2511 /* no more users -- free it (but keep log structure around) */
2512 osi_Free(logp->datap, sizeof(afs_int32) * logp->logSize);
2513 logp->firstUsed = logp->firstFree = 0;
2514 logp->logElements = 0;
2520 /* set the size of the log to 'logSize' */
2522 icl_LogSetSize(register struct afs_icl_log *logp, afs_int32 logSize)
2525 /* nothing to worry about since it's not allocated */
2526 logp->logSize = logSize;
2529 logp->firstUsed = logp->firstFree = 0;
2530 logp->logElements = 0;
2532 /* free and allocate a new one */
2533 osi_Free(logp->datap, sizeof(afs_int32) * logp->logSize);
2534 logp->datap = (afs_int32 *) osi_Alloc(sizeof(afs_int32) * logSize);
2535 logp->logSize = logSize;
2541 /* free a log. Called with icl_lock locked. */
2543 icl_ZapLog(register struct afs_icl_log *logp)
2545 register struct afs_icl_log **lpp, *tp;
2547 for (lpp = &afs_icl_allLogs, tp = *lpp; tp; lpp = &tp->nextp, tp = *lpp) {
2549 /* found the dude we want to remove */
2551 osi_Free(logp->name, 1 + strlen(logp->name));
2552 osi_Free(logp->datap, logp->logSize * sizeof(afs_int32));
2553 osi_Free(logp, sizeof(struct icl_log));
2554 break; /* won't find it twice */
2560 /* do the release, watching for deleted entries */
2562 icl_LogRele(register struct afs_icl_log *logp)
2564 if (--logp->refCount == 0 && (logp->states & ICL_LOGF_DELETED)) {
2565 icl_ZapLog(logp); /* destroys logp's lock! */
2570 /* do the release, watching for deleted entries, log already held */
2572 icl_LogReleNL(register struct afs_icl_log *logp)
2574 if (--logp->refCount == 0 && (logp->states & ICL_LOGF_DELETED)) {
2575 icl_ZapLog(logp); /* destroys logp's lock! */
2580 /* zero out the log */
2582 icl_ZeroLog(register struct afs_icl_log *logp)
2584 logp->firstUsed = logp->firstFree = 0;
2585 logp->logElements = 0;
2589 /* free a log entry, and drop its reference count */
2591 icl_LogFree(register struct afs_icl_log *logp)
2593 logp->states |= ICL_LOGF_DELETED;
2600 icl_EnumerateLogs(int (*aproc)
2601 (char *name, void *arock, struct afs_icl_log * tp),
2604 register struct afs_icl_log *tp;
2605 register afs_int32 code;
2608 for (tp = afs_icl_allLogs; tp; tp = tp->nextp) {
2609 tp->refCount++; /* hold this guy */
2610 code = (*aproc) (tp->name, arock, tp);
2611 if (--tp->refCount == 0)
2620 afs_icl_bulkSetinfo_t *
2621 GetBulkSetInfo(void)
2623 unsigned int infoSize;
2626 sizeof(afs_icl_bulkSetinfo_t) + (ICL_RPC_MAX_SETS -
2627 1) * sizeof(afs_icl_setinfo_t);
2629 setInfo = (afs_icl_bulkSetinfo_t *) malloc(infoSize);
2631 (void)fprintf(stderr,
2632 "Could not allocate the memory for bulk set info structure\n");
2636 memset((char *)setInfo, 0, infoSize);
2641 afs_icl_bulkLoginfo_t *
2642 GetBulkLogInfo(void)
2644 unsigned int infoSize;
2647 sizeof(afs_icl_bulkLoginfo_t) + (ICL_RPC_MAX_LOGS -
2648 1) * sizeof(afs_icl_loginfo_t);
2650 logInfo = (afs_icl_bulkLoginfo_t *) malloc(infoSize);
2652 (void)fprintf(stderr,
2653 "Could not allocate the memory for bulk log info structure\n");
2658 memset((char *)logInfo, 0, infoSize);
2664 DoDump(struct cmd_syndesc *as, void *arock)
2668 afs_int32 waitTime = 10 /* seconds */ ;
2670 FILE *outfp = stdout;
2672 struct cmd_item *itemp;
2674 if (geteuid() != 0) {
2675 printf("fstrace must be run as root\n");
2679 if (as->parms[3].items) {
2680 if (!as->parms[1].items) {
2681 (void)fprintf(stderr, "-sleep can only be used with -follow\n");
2684 waitTime = strtol(as->parms[3].items->data, NULL, 0);
2687 if (as->parms[2].items) {
2688 /* try to open the specified output file */
2689 if ((outfp = fopen(as->parms[2].items->data, "w")) == NULL) {
2690 (void)fprintf(stderr, "Cannot open file '%s' for writing\n",
2691 as->parms[2].items->data);
2695 #ifdef AFS_SGI64_ENV
2696 startTime = time((time_t *) 0);
2698 startTime = time(0);
2700 (void)fprintf(outfp, "AFS Trace Dump -\n\n Date: %s\n",
2703 if (as->parms[0].items) {
2704 for (itemp = as->parms[0].items; itemp; itemp = itemp->next) {
2705 tcode = icl_DumpKernel(outfp, itemp->data);
2707 (void)fprintf(stderr, "Unable to dump set %s (errno = %d)\n",
2708 itemp->data, errno);
2712 } else if (as->parms[1].items) {
2713 logname = as->parms[1].items->data;
2714 code = icl_TailKernel(outfp, logname, waitTime);
2716 (void)fprintf(stderr,
2717 "Error tailing kernel log '%s' (errno = %d)\n",
2721 code = icl_DumpKernel(outfp, NULL);
2723 (void)fprintf(outfp, "\nAFS Trace Dump - %s\n",
2724 code ? "FAILED" : "Completed");
2726 if (outfp != stdout)
2727 (void)fclose(outfp);
2735 struct cmd_syndesc *dumpSyntax;
2738 cmd_CreateSyntax("dump", DoDump, NULL, "dump AFS trace logs");
2739 (void)cmd_AddParm(dumpSyntax, "-set", CMD_LIST, CMD_OPTIONAL, "set_name");
2740 (void)cmd_AddParm(dumpSyntax, "-follow", CMD_SINGLE, CMD_OPTIONAL,
2742 (void)cmd_AddParm(dumpSyntax, "-file", CMD_SINGLE, CMD_OPTIONAL,
2744 (void)cmd_AddParm(dumpSyntax, "-sleep", CMD_SINGLE, CMD_OPTIONAL,
2745 "seconds_between_reads");
2749 DoShowLog(register struct cmd_syndesc *as, void *arock)
2751 afs_int32 retVal = 0;
2756 struct cmd_item *itemp;
2758 if (geteuid() != 0) {
2759 printf("fstrace must be run as root\n");
2762 if (as->parms[2].items)
2765 if (as->parms[0].items) {
2766 /* enumerate logs for the specified sets */
2767 for (itemp = as->parms[0].items; itemp; itemp = itemp->next) {
2768 (void)fprintf(stdout, "Logs for set '%s':\n", itemp->data);
2769 code = icl_ListLogsBySet(stdout, itemp->data, int32flg);
2771 (void)fprintf(stderr,
2772 "Error in enumerating set %s (errno = %d)\n",
2773 itemp->data, errno);
2777 } else if (as->parms[1].items) {
2778 /* print out log information */
2779 for (itemp = as->parms[1].items; itemp; itemp = itemp->next) {
2780 code = icl_GetLogsize(itemp->data, &logSize, &allocated);
2782 (void)fprintf(stdout, "%s : %d kbytes (%s)\n", itemp->data,
2784 allocated ? "allocated" : "unallocated");
2786 (void)fprintf(stderr,
2787 "Could not find log '%s' (errno = %d)\n",
2788 itemp->data, errno);
2794 (void)fprintf(stdout, "Available logs:\n");
2795 code = icl_ListLogs(stdout, int32flg);
2797 (void)fprintf(stderr, "Error in listing logs (errno = %d)\n",
2809 struct cmd_syndesc *showSyntax;
2812 cmd_CreateSyntax("lslog", DoShowLog, NULL,
2813 "list available logs");
2814 (void)cmd_AddParm(showSyntax, "-set", CMD_LIST, CMD_OPTIONAL, "set_name");
2815 (void)cmd_AddParm(showSyntax, "-log", CMD_LIST, CMD_OPTIONAL, "log_name");
2816 (void)cmd_AddParm(showSyntax, "-long", CMD_FLAG, CMD_OPTIONAL, "");
2820 DoShowSet(register struct cmd_syndesc *as, void *arock)
2822 afs_int32 retVal = 0;
2825 struct cmd_item *itemp;
2827 if (geteuid() != 0) {
2828 printf("fstrace must be run as root\n");
2831 if (as->parms[0].items) {
2832 /* print information on the specified sets */
2833 for (itemp = as->parms[0].items; itemp; itemp = itemp->next) {
2834 code = icl_GetSetState(itemp->data, &state);
2836 (void)fprintf(stderr,
2837 "Error getting status on set %s (errno = %d)\n",
2838 itemp->data, errno);
2841 (void)fprintf(stdout, "Set %s: %s%s%s\n", itemp->data,
2842 (state & ICL_SETF_ACTIVE) ? "active" :
2844 (state & ICL_SETF_FREED) ? " (dormant)" : "",
2845 (state & ICL_SETF_PERSISTENT) ? " persistent" :
2850 (void)fprintf(stdout, "Available sets:\n");
2851 code = icl_ListSets(stdout);
2853 (void)fprintf(stderr, "Error in listing sets (errno = %d)\n",
2865 struct cmd_syndesc *showSyntax;
2868 cmd_CreateSyntax("lsset", DoShowSet, NULL,
2869 "list available event sets");
2870 (void)cmd_AddParm(showSyntax, "-set", CMD_LIST, CMD_OPTIONAL, "set_name");
2874 DoClear(register struct cmd_syndesc *as, void *arock)
2876 afs_int32 retVal = 0;
2878 struct cmd_item *itemp;
2880 if (geteuid() != 0) {
2881 printf("fstrace must be run as root\n");
2884 if (as->parms[0].items) {
2885 /* clear logs for the specified sets */
2886 for (itemp = as->parms[0].items; itemp; itemp = itemp->next) {
2887 code = icl_ClearSet(itemp->data);
2889 (void)fprintf(stderr,
2890 "Error in clearing set %s (errno = %d)\n",
2891 itemp->data, errno);
2895 } else if (as->parms[1].items) {
2896 /* clear specified log */
2897 for (itemp = as->parms[0].items; itemp; itemp = itemp->next) {
2898 code = icl_ClearLog(itemp->data);
2900 (void)fprintf(stderr,
2901 "Error in clearing log %s (errno = %d)\n",
2902 itemp->data, errno);
2907 /* clear all logs */
2908 code = icl_ClearAll();
2910 (void)fprintf(stderr, "Error in clearing logs (errno = %d)\n",
2922 struct cmd_syndesc *clearSyntax;
2925 cmd_CreateSyntax("clear", DoClear, NULL,
2926 "clear logs by logname or by event set");
2927 (void)cmd_AddParm(clearSyntax, "-set", CMD_LIST, CMD_OPTIONAL,
2929 (void)cmd_AddParm(clearSyntax, "-log", CMD_LIST, CMD_OPTIONAL,
2934 DoSet(register struct cmd_syndesc *as, void *arock)
2936 afs_int32 retVal = 0;
2941 struct cmd_item *itemp;
2943 if (geteuid() != 0) {
2944 printf("fstrace must be run as root\n");
2947 if (as->parms[1].items) {
2948 op = ICL_OP_SS_ACTIVATE;
2949 operation = "active";
2950 } else if (as->parms[2].items) {
2951 op = ICL_OP_SS_DEACTIVATE;
2952 operation = "inactive";
2953 } else if (as->parms[3].items) {
2954 op = ICL_OP_SS_DEACTIVATE;
2955 operation = "inactive";
2958 /* assume active" */
2959 op = ICL_OP_SS_ACTIVATE;
2960 operation = "active";
2963 if (as->parms[0].items) {
2964 /* activate specified sets */
2965 for (itemp = as->parms[0].items; itemp; itemp = itemp->next) {
2966 code = icl_ChangeSetState(itemp->data, op);
2968 (void)fprintf(stderr,
2969 "cannot set state of %s to %s (errno = %d)\n",
2970 itemp->data, operation, errno);
2972 } else if (doFree) {
2973 /* try to make it dormant as well */
2974 code = icl_ChangeSetState(itemp->data, ICL_OP_SS_FREE);
2976 (void)fprintf(stderr,
2977 "cannot set state of %s to dormant (errno = %d)\n",
2978 itemp->data, errno);
2985 code = icl_ChangeAllSetState(op);
2987 (void)fprintf(stderr,
2988 "cannot set the state of all sets to %s (errno = %d)\n",
2991 } else if (doFree) {
2992 /* try to make it dormant as well */
2993 code = icl_ChangeAllSetState(ICL_OP_SS_FREE);
2995 (void)fprintf(stderr,
2996 "cannot set the state of all sets to dormant (errno = %d)\n",
3009 struct cmd_syndesc *setSyntax;
3012 cmd_CreateSyntax("setset", DoSet, NULL,
3013 "set state of event sets");
3014 (void)cmd_AddParm(setSyntax, "-set", CMD_LIST, CMD_OPTIONAL, "set_name");
3015 (void)cmd_AddParm(setSyntax, "-active", CMD_FLAG, CMD_OPTIONAL, "");
3016 (void)cmd_AddParm(setSyntax, "-inactive", CMD_FLAG, CMD_OPTIONAL, "");
3017 (void)cmd_AddParm(setSyntax, "-dormant", CMD_FLAG, CMD_OPTIONAL, "");
3021 DoResize(register struct cmd_syndesc *as, void *arock)
3023 afs_int32 retVal = 0;
3025 afs_int32 bufferSize;
3026 struct cmd_item *itemp;
3028 if (geteuid() != 0) {
3029 printf("fstrace must be run as root\n");
3032 /* get buffer size */
3033 bufferSize = atoi(as->parms[1].items->data);
3034 bufferSize *= BUFFER_MULTIPLIER;
3035 if (bufferSize == 0)
3036 bufferSize = ICL_DEFAULT_LOGSIZE;
3038 /* set the size of the specified logs */
3039 if ((itemp = as->parms[0].items)) {
3040 for (; itemp; itemp = itemp->next) {
3041 code = icl_ChangeLogSize(itemp->data, bufferSize);
3043 (void)fprintf(stderr,
3044 "Error in changing log %s buffer size (errno = %d)\n",
3045 itemp->data, errno);
3050 /* Use the only current support log, "cmfx" */
3051 code = icl_ChangeLogSize("cmfx", bufferSize);
3053 (void)fprintf(stderr,
3054 "Error in changing log cmfx buffer size (errno = %d)\n",
3066 struct cmd_syndesc *setsizeSyntax;
3069 cmd_CreateSyntax("setlog", DoResize, NULL,
3070 "set the size of a log");
3071 (void)cmd_AddParm(setsizeSyntax, "-log", CMD_LIST, CMD_OPTIONAL,
3073 (void)cmd_AddParm(setsizeSyntax, "-buffersize", CMD_SINGLE, CMD_REQUIRED,
3074 "1-kilobyte_units");
3077 #include "AFS_component_version_number.c"
3080 main(int argc, char *argv[])
3082 setlocale(LC_ALL, "");
3083 #ifdef AFS_SGI62_ENV
3084 set_kernel_sizeof_long();
3087 /* set up user interface then dispatch */
3095 return (cmd_Dispatch(argc, argv));
3098 #include "AFS_component_version_number.c"
3101 main(int argc, char *argv[])
3103 printf("fstrace is NOT supported for this OS\n");