home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume23 / tua / part04 < prev    next >
Text File  |  1991-09-23  |  46KB  |  1,587 lines

  1. Newsgroups: comp.sources.misc
  2. From: piggy@idea.sublink.org (Lele Gaifas)
  3. Subject:  v23i010:  tua - The Uucp Analyzer, Part04/05
  4. Message-ID: <1991Sep22.203540.23061@sparky.imd.sterling.com>
  5. X-Md4-Signature: 1cd1408d38e27a6eada787142c3de802
  6. Date: Sun, 22 Sep 1991 20:35:40 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: piggy@idea.sublink.org (Lele Gaifas)
  10. Posting-number: Volume 23, Issue 10
  11. Archive-name: tua/part04
  12. Environment: Xenix, SYSV
  13.  
  14. ---- Cut Here and feed the following to sh ----
  15. # This is part 04 of a multipart archive
  16. # ============= getopt.c ==============
  17. if test -f 'getopt.c' -a X"$1" != X"-c"; then
  18.     echo 'x - skipping getopt.c (File already exists)'
  19. else
  20. echo 'x - extracting getopt.c (Text)'
  21. sed 's/^X//' << 'SHAR_EOF' > 'getopt.c' &&
  22. /* Getopt for GNU.
  23. X   Copyright (C) 1987, 1989 Free Software Foundation, Inc.
  24. X
  25. X   This program is free software; you can redistribute it and/or modify
  26. X   it under the terms of the GNU General Public License as published by
  27. X   the Free Software Foundation; either version 1, or (at your option)
  28. X   any later version.
  29. X
  30. X   This program is distributed in the hope that it will be useful,
  31. X   but WITHOUT ANY WARRANTY; without even the implied warranty of
  32. X   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  33. X   GNU General Public License for more details.
  34. X
  35. X   You should have received a copy of the GNU General Public License
  36. X   along with this program; if not, write to the Free Software
  37. X   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  38. X
  39. #ifdef __STDC__
  40. #define CONST const
  41. #else
  42. #define CONST
  43. #endif
  44. X
  45. /* This version of `getopt' appears to the caller like standard Unix `getopt'
  46. X   but it behaves differently for the user, since it allows the user
  47. X   to intersperse the options with the other arguments.
  48. X
  49. X   As `getopt' works, it permutes the elements of `argv' so that,
  50. X   when it is done, all the options precede everything else.  Thus
  51. X   all application programs are extended to handle flexible argument order.
  52. X
  53. X   Setting the environment variable _POSIX_OPTION_ORDER disables permutation.
  54. X   Then the behavior is completely standard.
  55. X
  56. X   GNU application programs can use a third alternative mode in which
  57. X   they can distinguish the relative order of options and other arguments.  */
  58. X
  59. #include <stdio.h>
  60. X
  61. /* If compiled with GNU C, use the built-in alloca */
  62. #ifdef __GNUC__
  63. #define alloca __builtin_alloca
  64. #else /* not __GNUC__ */
  65. #ifdef sparc
  66. #include <alloca.h>
  67. #else
  68. char *alloca ();
  69. #endif
  70. #endif /* not __GNUC__ */
  71. X
  72. #ifdef USG
  73. #define bcopy(s, d, l) memcpy((d), (s), (l))
  74. #define index strchr
  75. #endif
  76. X
  77. char *getenv ();
  78. char *index ();
  79. char *malloc ();
  80. X
  81. /* For communication from `getopt' to the caller.
  82. X   When `getopt' finds an option that takes an argument,
  83. X   the argument value is returned here.
  84. X   Also, when `ordering' is RETURN_IN_ORDER,
  85. X   each non-option ARGV-element is returned here.  */
  86. X
  87. char *optarg = 0;
  88. X
  89. /* Index in ARGV of the next element to be scanned.
  90. X   This is used for communication to and from the caller
  91. X   and for communication between successive calls to `getopt'.
  92. X
  93. X   On entry to `getopt', zero means this is the first call; initialize.
  94. X
  95. X   When `getopt' returns EOF, this is the index of the first of the
  96. X   non-option elements that the caller should itself scan.
  97. X
  98. X   Otherwise, `optind' communicates from one call to the next
  99. X   how much of ARGV has been scanned so far.  */
  100. X
  101. int optind = 0;
  102. X
  103. /* The next char to be scanned in the option-element
  104. X   in which the last option character we returned was found.
  105. X   This allows us to pick up the scan where we left off.
  106. X
  107. X   If this is zero, or a null string, it means resume the scan
  108. X   by advancing to the next ARGV-element.  */
  109. X
  110. static char *nextchar;
  111. X
  112. /* Callers store zero here to inhibit the error message
  113. X   for unrecognized options.  */
  114. X
  115. int opterr = 1;
  116. X
  117. /* Describe how to deal with options that follow non-option ARGV-elements.
  118. X
  119. X   If the caller did not specify anything,
  120. X   the default is REQUIRE_ORDER if the environment variable
  121. X   _POSIX_OPTION_ORDER is defined, PERMUTE otherwise.
  122. X
  123. X   REQUIRE_ORDER means don't recognize them as options.
  124. X   Stop option processing when the first non-option is seen.
  125. X   This is what Unix does.
  126. X
  127. X   PERMUTE is the default.  We permute the contents of ARGV as we scan,
  128. X   so that eventually all the options are at the end.  This allows options
  129. X   to be given in any order, even with programs that were not written to
  130. X   expect this.
  131. X
  132. X   RETURN_IN_ORDER is an option available to programs that were written
  133. X   to expect options and other ARGV-elements in any order and that care about
  134. X   the ordering of the two.  We describe each non-option ARGV-element
  135. X   as if it were the argument of an option with character code one.
  136. X   Using `-' as the first character of the list of option characters
  137. X   requests this mode of operation.
  138. X
  139. X   The special argument `--' forces an end of option-scanning regardless
  140. X   of the value of `ordering'.  In the case of RETURN_IN_ORDER, only
  141. X   `--' can cause `getopt' to return EOF with `optind' != ARGC.  */
  142. X
  143. static enum { REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER } ordering;
  144. X
  145. /* Describe the long-named options requested by the application.
  146. X   _GETOPT_LONG_OPTIONS is a vector of `struct option' terminated by an
  147. X   element containing a name which is zero.
  148. X   The field `has_arg' is 1 if the option takes an argument, 
  149. X   2 if it takes an optional argument.  */
  150. X
  151. struct option
  152. {
  153. X  char *name;
  154. X  int has_arg;
  155. X  int *flag;
  156. X  int val;
  157. };
  158. X
  159. CONST struct option *_getopt_long_options;
  160. X
  161. int _getopt_long_only = 0;
  162. X
  163. /* Index in _GETOPT_LONG_OPTIONS of the long-named option actually found.
  164. X   Only valid when a long-named option was found. */
  165. X
  166. int option_index;
  167. X
  168. /* Handle permutation of arguments.  */
  169. X
  170. /* Describe the part of ARGV that contains non-options that have
  171. X   been skipped.  `first_nonopt' is the index in ARGV of the first of them;
  172. X   `last_nonopt' is the index after the last of them.  */
  173. X
  174. static int first_nonopt;
  175. static int last_nonopt;
  176. X
  177. /* Exchange two adjacent subsequences of ARGV.
  178. X   One subsequence is elements [first_nonopt,last_nonopt)
  179. X    which contains all the non-options that have been skipped so far.
  180. X   The other is elements [last_nonopt,optind), which contains all
  181. X    the options processed since those non-options were skipped.
  182. X
  183. X   `first_nonopt' and `last_nonopt' are relocated so that they describe
  184. X    the new indices of the non-options in ARGV after they are moved.  */
  185. X
  186. static void
  187. exchange (argv)
  188. X     char **argv;
  189. {
  190. X  int nonopts_size
  191. X    = (last_nonopt - first_nonopt) * sizeof (char *);
  192. X  char **temp = (char **) alloca (nonopts_size);
  193. X
  194. X  /* Interchange the two blocks of data in argv.  */
  195. X
  196. X  bcopy (&argv[first_nonopt], temp, nonopts_size);
  197. X  bcopy (&argv[last_nonopt], &argv[first_nonopt],
  198. X     (optind - last_nonopt) * sizeof (char *));
  199. X  bcopy (temp, &argv[first_nonopt + optind - last_nonopt],
  200. X     nonopts_size);
  201. X
  202. X  /* Update records for the slots the non-options now occupy.  */
  203. X
  204. X  first_nonopt += (optind - last_nonopt);
  205. X  last_nonopt = optind;
  206. }
  207. X
  208. /* Scan elements of ARGV (whose length is ARGC) for option characters
  209. X   given in OPTSTRING.
  210. X
  211. X   If an element of ARGV starts with '-', and is not exactly "-" or "--",
  212. X   then it is an option element.  The characters of this element
  213. X   (aside from the initial '-') are option characters.  If `getopt'
  214. X   is called repeatedly, it returns successively each of the option characters
  215. X   from each of the option elements.
  216. X
  217. X   If `getopt' finds another option character, it returns that character,
  218. X   updating `optind' and `nextchar' so that the next call to `getopt' can
  219. X   resume the scan with the following option character or ARGV-element.
  220. X
  221. X   If there are no more option characters, `getopt' returns `EOF'.
  222. X   Then `optind' is the index in ARGV of the first ARGV-element
  223. X   that is not an option.  (The ARGV-elements have been permuted
  224. X   so that those that are not options now come last.)
  225. X
  226. X   OPTSTRING is a string containing the legitimate option characters.
  227. X   If an option character is seen that is not listed in OPTSTRING,
  228. X   return '?' after printing an error message.  If you set `opterr' to
  229. X   zero, the error message is suppressed but we still return '?'.
  230. X
  231. X   If a char in OPTSTRING is followed by a colon, that means it wants an arg,
  232. X   so the following text in the same ARGV-element, or the text of the following
  233. X   ARGV-element, is returned in `optarg'.  Two colons mean an option that
  234. X   wants an optional arg; if there is text in the current ARGV-element,
  235. X   it is returned in `optarg', otherwise `optarg' is set to zero.
  236. X
  237. X   If OPTSTRING starts with `-', it requests a different method of handling the
  238. X   non-option ARGV-elements.  See the comments about RETURN_IN_ORDER, above.
  239. X
  240. X   Long-named options begin with `+' instead of `-'.
  241. X   Their names may be abbreviated as long as the abbreviation is unique
  242. X   or is an exact match for some defined option.  If they have an
  243. X   argument, it follows the option name in the same ARGV-element, separated
  244. X   from the option name by a `=', or else the in next ARGV-element.
  245. X   `getopt' returns 0 when it finds a long-named option.  */
  246. X
  247. int
  248. getopt (argc, argv, optstring)
  249. X     int argc;
  250. X     char **argv;
  251. X     CONST char *optstring;
  252. {
  253. X  optarg = 0;
  254. X
  255. X  /* Initialize the internal data when the first call is made.
  256. X     Start processing options with ARGV-element 1 (since ARGV-element 0
  257. X     is the program name); the sequence of previously skipped
  258. X     non-option ARGV-elements is empty.  */
  259. X
  260. X  if (optind == 0)
  261. X    {
  262. X      first_nonopt = last_nonopt = optind = 1;
  263. X
  264. X      nextchar = 0;
  265. X
  266. X      /* Determine how to handle the ordering of options and nonoptions.  */
  267. X
  268. X      if (optstring[0] == '-')
  269. X    ordering = RETURN_IN_ORDER;
  270. X      else if (getenv ("_POSIX_OPTION_ORDER") != 0)
  271. X    ordering = REQUIRE_ORDER;
  272. X      else
  273. X    ordering = PERMUTE;
  274. X    }
  275. X
  276. X  if (nextchar == 0 || *nextchar == 0)
  277. X    {
  278. X      if (ordering == PERMUTE)
  279. X    {
  280. X      /* If we have just processed some options following some non-options,
  281. X         exchange them so that the options come first.  */
  282. X
  283. X      if (first_nonopt != last_nonopt && last_nonopt != optind)
  284. X        exchange (argv);
  285. X      else if (last_nonopt != optind)
  286. X        first_nonopt = optind;
  287. X
  288. X      /* Now skip any additional non-options
  289. X         and extend the range of non-options previously skipped.  */
  290. X
  291. X      while (optind < argc
  292. X         && (argv[optind][0] != '-'
  293. X             || argv[optind][1] == 0)
  294. X         && (_getopt_long_options == 0
  295. X             || argv[optind][0] != '+'
  296. X             || argv[optind][1] == 0))
  297. X        optind++;
  298. X      last_nonopt = optind;
  299. X    }
  300. X
  301. X      /* Special ARGV-element `--' means premature end of options.
  302. X     Skip it like a null option,
  303. X     then exchange with previous non-options as if it were an option,
  304. X     then skip everything else like a non-option.  */
  305. X
  306. X      if (optind != argc && !strcmp (argv[optind], "--"))
  307. X    {
  308. X      optind++;
  309. X
  310. X      if (first_nonopt != last_nonopt && last_nonopt != optind)
  311. X        exchange (argv);
  312. X      else if (first_nonopt == last_nonopt)
  313. X        first_nonopt = optind;
  314. X      last_nonopt = argc;
  315. X
  316. X      optind = argc;
  317. X    }
  318. X
  319. X      /* If we have done all the ARGV-elements, stop the scan
  320. X     and back over any non-options that we skipped and permuted.  */
  321. X
  322. X      if (optind == argc)
  323. X    {
  324. X      /* Set the next-arg-index to point at the non-options
  325. X         that we previously skipped, so the caller will digest them.  */
  326. X      if (first_nonopt != last_nonopt)
  327. X        optind = first_nonopt;
  328. X      return EOF;
  329. X    }
  330. X     
  331. X      /* If we have come to a non-option and did not permute it,
  332. X     either stop the scan or describe it to the caller and pass it by.  */
  333. X
  334. X      if ((argv[optind][0] != '-' || argv[optind][1] == 0)
  335. X      && (_getopt_long_options == 0
  336. X          || argv[optind][0] != '+' || argv[optind][1] == 0))
  337. X    {
  338. X      if (ordering == REQUIRE_ORDER)
  339. X        return EOF;
  340. X      optarg = argv[optind++];
  341. X      return 1;
  342. X    }
  343. X
  344. X      /* We have found another option-ARGV-element.
  345. X     Start decoding its characters.  */
  346. X
  347. X      nextchar = argv[optind] + 1;
  348. X    }
  349. X
  350. X  if (_getopt_long_options != 0
  351. X      && (argv[optind][0] == '+'
  352. X      || (_getopt_long_only && argv[optind][0] == '-'))
  353. X      )
  354. X    {
  355. X      CONST struct option *p;
  356. X      char *s = nextchar;
  357. X      int exact = 0;
  358. X      int ambig = 0;
  359. X      CONST struct option *pfound = 0;
  360. X      int indfound;
  361. X
  362. X      while (*s && *s != '=') s++;
  363. X
  364. X      /* Test all options for either exact match or abbreviated matches.  */
  365. X      for (p = _getopt_long_options, option_index = 0; p->name; 
  366. X       p++, option_index++)
  367. X    if (!strncmp (p->name, nextchar, s - nextchar))
  368. X      {
  369. X        if (s - nextchar == strlen (p->name))
  370. X          {
  371. X        /* Exact match found.  */
  372. X        pfound = p;
  373. X        indfound = option_index;
  374. X        exact = 1;
  375. X        break;
  376. X          }
  377. X        else if (pfound == 0)
  378. X          {
  379. X        /* First nonexact match found.  */
  380. X        pfound = p;
  381. X        indfound = option_index;
  382. X          }
  383. X        else
  384. X          /* Second nonexact match found.  */
  385. X          ambig = 1;
  386. X      }
  387. X
  388. X      if (ambig && !exact)
  389. X    {
  390. X      fprintf (stderr, "%s: option `%s' is ambiguous\n",
  391. X           argv[0], argv[optind]);
  392. X      nextchar += strlen (nextchar);               
  393. X      return '?';
  394. X    }
  395. X
  396. X      if (pfound != 0)
  397. X    {
  398. X      option_index = indfound;
  399. X      optind++;
  400. X      if (*s)
  401. X        {
  402. X          if (pfound->has_arg > 0)
  403. X        optarg = s + 1;
  404. X          else
  405. X        {
  406. X          fprintf (stderr,
  407. X               "%s: option `%c%s' doesn't allow an argument\n",
  408. X               argv[0], argv[optind - 1][0], pfound->name);
  409. X          nextchar += strlen (nextchar);               
  410. X          return '?';
  411. X        }
  412. X        }
  413. X      else if (pfound->has_arg == 1)
  414. X        {
  415. X          if (optind < argc)
  416. X        optarg = argv[optind++];
  417. X          else
  418. X        {
  419. X          fprintf (stderr, "%s: option `%s' requires an argument\n",
  420. X               argv[0], argv[optind - 1]);
  421. X          nextchar += strlen (nextchar);           
  422. X          return '?';
  423. X        }
  424. X        }
  425. X      nextchar += strlen (nextchar);
  426. X      if (pfound->flag)
  427. X        *(pfound->flag) = pfound->val;
  428. X      return 0;
  429. X    }
  430. X      /* Can't find it as a long option.  If this is getopt_long_only,
  431. X     and the option starts with '-' and is a valid short
  432. X     option, then interpret it as a short option.  Otherwise it's
  433. X     an error.  */
  434. X      if (_getopt_long_only == 0 || argv[optind][0] == '+' ||
  435. X      index (optstring, *nextchar) == 0)
  436. X    {
  437. X      if (opterr != 0)
  438. X        fprintf (stderr, "%s: unrecognized option `%c%s'\n",
  439. X             argv[0], argv[optind][0], nextchar);
  440. X      nextchar += strlen (nextchar);           
  441. X      return '?';
  442. X    }
  443. X    }
  444. X  /* Look at and handle the next option-character.  */
  445. X
  446. X  {
  447. X    char c = *nextchar++;
  448. X    char *temp = index (optstring, c);
  449. X
  450. X    /* Increment `optind' when we start to process its last character.  */
  451. X    if (*nextchar == 0)
  452. X      optind++;
  453. X
  454. X    if (temp == 0 || c == ':')
  455. X      {
  456. X    if (opterr != 0)
  457. X      {
  458. X        if (c < 040 || c >= 0177)
  459. X          fprintf (stderr, "%s: unrecognized option, character code 0%o\n",
  460. X               argv[0], c);
  461. X        else
  462. X          fprintf (stderr, "%s: unrecognized option `-%c'\n",
  463. X               argv[0], c);
  464. X      }
  465. X    return '?';
  466. X      }
  467. X    if (temp[1] == ':')
  468. X      {
  469. X    if (temp[2] == ':')
  470. X      {
  471. X        /* This is an option that accepts an argument optionally.  */
  472. X        if (*nextchar != 0)
  473. X          {
  474. X            optarg = nextchar;
  475. X        optind++;
  476. X          }
  477. X        else
  478. X          optarg = 0;
  479. X        nextchar = 0;
  480. X      }
  481. X    else
  482. X      {
  483. X        /* This is an option that requires an argument.  */
  484. X        if (*nextchar != 0)
  485. X          {
  486. X        optarg = nextchar;
  487. X        /* If we end this ARGV-element by taking the rest as an arg,
  488. X           we must advance to the next element now.  */
  489. X        optind++;
  490. X          }
  491. X        else if (optind == argc)
  492. X          {
  493. X        if (opterr != 0)
  494. X          fprintf (stderr, "%s: option `-%c' requires an argument\n",
  495. X               argv[0], c);
  496. X        c = '?';
  497. X          }
  498. X        else
  499. X          /* We already incremented `optind' once;
  500. X         increment it again when taking next ARGV-elt as argument.  */
  501. X          optarg = argv[optind++];
  502. X        nextchar = 0;
  503. X      }
  504. X      }
  505. X    return c;
  506. X  }
  507. }
  508. X
  509. #ifdef TEST
  510. X
  511. /* Compile with -DTEST to make an executable for use in testing
  512. X   the above definition of `getopt'.  */
  513. X
  514. int
  515. main (argc, argv)
  516. X     int argc;
  517. X     char **argv;
  518. {
  519. X  char c;
  520. X  int digit_optind = 0;
  521. X
  522. X  while (1)
  523. X    {
  524. X      int this_option_optind = optind;
  525. X      if ((c = getopt (argc, argv, "abc:d:0123456789")) == EOF)
  526. X    break;
  527. X
  528. X      switch (c)
  529. X    {
  530. X    case '0':
  531. X    case '1':
  532. X    case '2':
  533. X    case '3':
  534. X    case '4':
  535. X    case '5':
  536. X    case '6':
  537. X    case '7':
  538. X    case '8':
  539. X    case '9':
  540. X      if (digit_optind != 0 && digit_optind != this_option_optind)
  541. X        printf ("digits occur in two different argv-elements.\n");
  542. X      digit_optind = this_option_optind;
  543. X      printf ("option %c\n", c);
  544. X      break;
  545. X
  546. X    case 'a':
  547. X      printf ("option a\n");
  548. X      break;
  549. X
  550. X    case 'b':
  551. X      printf ("option b\n");
  552. X      break;
  553. X
  554. X    case 'c':
  555. X      printf ("option c with value `%s'\n", optarg);
  556. X      break;
  557. X
  558. X    case '?':
  559. X      break;
  560. X
  561. X    default:
  562. X      printf ("?? getopt returned character code 0%o ??\n", c);
  563. X    }
  564. X    }
  565. X
  566. X  if (optind < argc)
  567. X    {
  568. X      printf ("non-option ARGV-elements: ");
  569. X      while (optind < argc)
  570. X    printf ("%s ", argv[optind++]);
  571. X      printf ("\n");
  572. X    }
  573. X
  574. X  return 0;
  575. }
  576. X
  577. #endif /* TEST */
  578. SHAR_EOF
  579. chmod 0444 getopt.c ||
  580. echo 'restore of getopt.c failed'
  581. Wc_c="`wc -c < 'getopt.c'`"
  582. test 16005 -eq "$Wc_c" ||
  583.     echo 'getopt.c: original size 16005, current size' "$Wc_c"
  584. fi
  585. # ============= getopt1.c ==============
  586. if test -f 'getopt1.c' -a X"$1" != X"-c"; then
  587.     echo 'x - skipping getopt1.c (File already exists)'
  588. else
  589. echo 'x - extracting getopt1.c (Text)'
  590. sed 's/^X//' << 'SHAR_EOF' > 'getopt1.c' &&
  591. /* Getopt for GNU.
  592. X   Copyright (C) 1987, 1989 Free Software Foundation, Inc.
  593. X
  594. X   This program is free software; you can redistribute it and/or modify
  595. X   it under the terms of the GNU General Public License as published by
  596. X   the Free Software Foundation; either version 1, or (at your option)
  597. X   any later version.
  598. X
  599. X   This program is distributed in the hope that it will be useful,
  600. X   but WITHOUT ANY WARRANTY; without even the implied warranty of
  601. X   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  602. X   GNU General Public License for more details.
  603. X
  604. X   You should have received a copy of the GNU General Public License
  605. X   along with this program; if not, write to the Free Software
  606. X   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  607. X
  608. #include "getopt.h"
  609. X
  610. #ifdef __STDC__
  611. #define CONST const
  612. #else
  613. #define CONST
  614. #endif
  615. X
  616. int
  617. getopt_long (argc, argv, options, long_options, opt_index)
  618. X     int argc;
  619. X     char **argv;
  620. X     CONST char *options;
  621. X     CONST struct option *long_options;
  622. X     int *opt_index;
  623. {
  624. X  int val;
  625. X
  626. X  _getopt_long_options = long_options;
  627. X  val = getopt (argc, argv, options);
  628. X  if (val == 0)
  629. X    *opt_index = option_index;
  630. X  return val;
  631. }
  632. X
  633. /* Like getopt_long, but '-' as well as '+' can indicate a long option.
  634. X   If an option that starts with '-' doesn't match a long option,
  635. X   but does match a short option, it is parsed as a short option
  636. X   instead. */
  637. X
  638. int getopt_long_only (argc, argv, options, long_options, opt_index)
  639. X     int argc;
  640. X     char **argv;
  641. X     CONST char *options;
  642. X     CONST struct option *long_options;
  643. X     int *opt_index;
  644. {
  645. X  int val;
  646. X
  647. X  _getopt_long_options = long_options;
  648. X  _getopt_long_only = 1;
  649. X  val = getopt (argc, argv, options);
  650. X  if (val == 0)
  651. X    *opt_index = option_index;
  652. X  return val;
  653. }
  654. X     
  655. X
  656. #ifdef TEST
  657. X
  658. #include <stdio.h>
  659. X
  660. int
  661. main (argc, argv)
  662. X     int argc;
  663. X     char **argv;
  664. {
  665. X  char c;
  666. X  int digit_optind = 0;
  667. X
  668. X  while (1)
  669. X    {
  670. X      int this_option_optind = optind;
  671. X      char *name = '\0';
  672. X      int option_index = 0;
  673. X      static struct option long_options[]
  674. X    = {{ "add", 1, 0, 0 },
  675. X       { "append", 0, 0, 0 },
  676. X       { "delete", 1, 0, 0 },
  677. X       { "verbose", 0, 0, 0 },
  678. X       { "create", 0, 0, 0 },
  679. X       { "file", 1, 0, 0 },
  680. X       { 0, 0, 0, 0}};
  681. X
  682. X      c = getopt_long (argc, argv, "abc:d:0123456789",
  683. X               long_options, &option_index);
  684. X      if (c == EOF)
  685. X    break;
  686. X    switch (c)
  687. X      {
  688. X      case 0:
  689. X        printf ("option %s", (long_options[option_index]).name);
  690. X        if (optarg)
  691. X          printf (" with arg %s", optarg);
  692. X        printf ("\n");
  693. X        break;
  694. X
  695. X      case '0':
  696. X      case '1':
  697. X      case '2':
  698. X      case '3':
  699. X      case '4':
  700. X      case '5':
  701. X      case '6':
  702. X      case '7':
  703. X      case '8':
  704. X      case '9':
  705. X        if (digit_optind != 0 && digit_optind != this_option_optind)
  706. X          printf ("digits occur in two different argv-elements.\n");
  707. X        digit_optind = this_option_optind;
  708. X        printf ("option %c\n", c);
  709. X        break;
  710. X
  711. X      case 'a':
  712. X        printf ("option a\n");
  713. X        break;
  714. X
  715. X      case 'b':
  716. X        printf ("option b\n");
  717. X        break;
  718. X
  719. X      case 'c':
  720. X        printf ("option c with value `%s'\n", optarg);
  721. X        break;
  722. X
  723. X      case '?':
  724. X        break;
  725. X
  726. X      default:
  727. X        printf ("?? getopt returned character code 0%o ??\n", c);
  728. X      }
  729. X    }
  730. X
  731. X  if (optind < argc)
  732. X    {
  733. X      printf ("non-option ARGV-elements: ");
  734. X      while (optind < argc)
  735. X    printf ("%s ", argv[optind++]);
  736. X      printf ("\n");
  737. X    }
  738. X
  739. X  return 0;
  740. }
  741. X
  742. #endif /* TEST */
  743. SHAR_EOF
  744. chmod 0444 getopt1.c ||
  745. echo 'restore of getopt1.c failed'
  746. Wc_c="`wc -c < 'getopt1.c'`"
  747. test 3378 -eq "$Wc_c" ||
  748.     echo 'getopt1.c: original size 3378, current size' "$Wc_c"
  749. fi
  750. # ============= getopt.h ==============
  751. if test -f 'getopt.h' -a X"$1" != X"-c"; then
  752.     echo 'x - skipping getopt.h (File already exists)'
  753. else
  754. echo 'x - extracting getopt.h (Text)'
  755. sed 's/^X//' << 'SHAR_EOF' > 'getopt.h' &&
  756. /* declarations for getopt
  757. X   Copyright (C) 1989 Free Software Foundation, Inc.
  758. X
  759. X   This program is free software; you can redistribute it and/or modify
  760. X   it under the terms of the GNU General Public License as published by
  761. X   the Free Software Foundation; either version 1, or (at your option)
  762. X   any later version.
  763. X
  764. X   This program is distributed in the hope that it will be useful,
  765. X   but WITHOUT ANY WARRANTY; without even the implied warranty of
  766. X   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  767. X   GNU General Public License for more details.
  768. X
  769. X   You should have received a copy of the GNU General Public License
  770. X   along with this program; if not, write to the Free Software
  771. X   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  772. X
  773. /* For communication from `getopt' to the caller.
  774. X   When `getopt' finds an option that takes an argument,
  775. X   the argument value is returned here.
  776. X   Also, when `ordering' is RETURN_IN_ORDER,
  777. X   each non-option ARGV-element is returned here.  */
  778. X
  779. extern char *optarg;
  780. X
  781. /* Index in ARGV of the next element to be scanned.
  782. X   This is used for communication to and from the caller
  783. X   and for communication between successive calls to `getopt'.
  784. X
  785. X   On entry to `getopt', zero means this is the first call; initialize.
  786. X
  787. X   When `getopt' returns EOF, this is the index of the first of the
  788. X   non-option elements that the caller should itself scan.
  789. X
  790. X   Otherwise, `optind' communicates from one call to the next
  791. X   how much of ARGV has been scanned so far.  */
  792. X
  793. extern int optind;
  794. X
  795. /* Callers store zero here to inhibit the error message `getopt' prints
  796. X   for unrecognized options.  */
  797. X
  798. extern int opterr;
  799. X
  800. /* Describe the long-named options requested by the application.
  801. X   _GETOPT_LONG_OPTIONS is a vector of `struct option' terminated by an
  802. X   element containing a name which is zero.
  803. X   The field `has_arg' is:
  804. X   0 if the option does not take an argument,
  805. X   1 if the option requires an argument,
  806. X   2 if the option takes an optional argument.
  807. X   If the field `flag' is nonzero, it points to a variable that is set to
  808. X   the value given in the field `val' when the option is found, but
  809. X   left unchanged if the option is not found.  */
  810. X
  811. struct option
  812. {
  813. X  char *name;
  814. X  int has_arg;
  815. X  int *flag;
  816. X  int val;
  817. };
  818. X
  819. #ifdef __STDC__
  820. extern const struct option *_getopt_long_options;
  821. #else
  822. extern struct option *_getopt_long_options;
  823. #endif
  824. X
  825. /* If nonzero, tell getopt that '-' means a long option.
  826. X   Set by getopt_long_only.  */
  827. extern int _getopt_long_only;
  828. X
  829. /* The index in GETOPT_LONG_OPTIONS of the long-named option found.
  830. X   Only valid when a long-named option has been found by the most
  831. X   recent call to `getopt'.  */
  832. X
  833. extern int option_index;
  834. X
  835. #ifdef __STDC__
  836. int getopt (int argc, char **argv, const char *shortopts);
  837. int getopt_long (int argc, char **argv, const char *shortopts,
  838. X         const struct option *longopts, int *longind);
  839. int getopt_long_only (int argc, char **argv, const char *shortopts,
  840. X              const struct option *longopts, int *longind);
  841. void envopt(int *pargc, char ***pargv, char *optstr);
  842. #else
  843. int getopt ();
  844. int getopt_long ();
  845. int getopt_long_only ();
  846. void envopt();
  847. #endif
  848. SHAR_EOF
  849. chmod 0444 getopt.h ||
  850. echo 'restore of getopt.h failed'
  851. Wc_c="`wc -c < 'getopt.h'`"
  852. test 3161 -eq "$Wc_c" ||
  853.     echo 'getopt.h: original size 3161, current size' "$Wc_c"
  854. fi
  855. # ============= patchlevel.h ==============
  856. if test -f 'patchlevel.h' -a X"$1" != X"-c"; then
  857.     echo 'x - skipping patchlevel.h (File already exists)'
  858. else
  859. echo 'x - extracting patchlevel.h (Text)'
  860. sed 's/^X//' << 'SHAR_EOF' > 'patchlevel.h' &&
  861. /* $Id: patchlevel.h,v 3.3 1991/09/01 14:03:43 piggy Rel $
  862. X * Release and patchlevel string.
  863. X *
  864. X *   Copyright (C) 1991  Lele Gaifax (piggy@idea.sublink.org)
  865. X *
  866. X *   This program is free software; you can redistribute it and/or modify
  867. X *   it under the terms of the GNU General Public License as published by
  868. X *   the Free Software Foundation; either version 1, or (at your option)
  869. X *   any later version.
  870. X *
  871. X *   This program is distributed in the hope that it will be useful,
  872. X *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  873. X *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  874. X *   GNU General Public License for more details.
  875. X *
  876. X *   You should have received a copy of the GNU General Public License
  877. X *   along with this program; if not, write to the Free Software
  878. X *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  879. X */
  880. X
  881. #define RELEASE "3.3"
  882. SHAR_EOF
  883. chmod 0444 patchlevel.h ||
  884. echo 'restore of patchlevel.h failed'
  885. Wc_c="`wc -c < 'patchlevel.h'`"
  886. test 892 -eq "$Wc_c" ||
  887.     echo 'patchlevel.h: original size 892, current size' "$Wc_c"
  888. fi
  889. # ============= tua.man ==============
  890. if test -f 'tua.man' -a X"$1" != X"-c"; then
  891.     echo 'x - skipping tua.man (File already exists)'
  892. else
  893. echo 'x - extracting tua.man (Text)'
  894. sed 's/^X//' << 'SHAR_EOF' > 'tua.man' &&
  895. ''' $Header: /usr/src/piggy/tua/RCS/tua.man,v 3.3 1991/09/01 14:03:45 piggy Rel $
  896. ''' 
  897. '''  Copyright (C) 1991  Lele Gaifax (piggy@idea.sublink.org)
  898. '''
  899. '''  This program is free software; you can redistribute it and/or modify
  900. '''  it under the terms of the GNU General Public License as published by
  901. '''  the Free Software Foundation; either version 1, or (at your option)
  902. '''  any later version.
  903. '''
  904. '''  This program is distributed in the hope that it will be useful,
  905. '''  but WITHOUT ANY WARRANTY; without even the implied warranty of
  906. '''  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  907. '''  GNU General Public License for more details.
  908. '''
  909. '''  You should have received a copy of the GNU General Public License
  910. '''  along with this program; if not, write to the Free Software
  911. '''  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  912. '''
  913. ''' The next definitions are from Larry Wall's perl manual pages.
  914. .de Sh
  915. .br
  916. .ne 5
  917. .PP
  918. \fB\\$1\fR
  919. .PP
  920. ..
  921. .de Sp
  922. .if t .sp .5v
  923. .if n .sp
  924. ..
  925. .de Ip
  926. .br
  927. .ie \\n.$>=3 .ne \\$3
  928. .el .ne 3
  929. .IP "\\$1" \\$2
  930. ..
  931. '''
  932. '''     Set up \*(-- to give an unbreakable dash;
  933. '''     string Tr holds user defined translation string.
  934. '''     Bell System Logo is used as a dummy character.
  935. '''
  936. .tr \(*W-|\(bv\*(Tr
  937. .ie n \{\
  938. .ds -- \(*W-
  939. .if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
  940. .if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
  941. .ds L" ""
  942. .ds R" ""
  943. .ds L' '
  944. .ds R' '
  945. 'br\}
  946. .el\{\
  947. .ds -- \(em\|
  948. .tr \*(Tr
  949. .ds L" ``
  950. .ds R" ''
  951. .ds L' `
  952. .ds R' '
  953. 'br\}
  954. .TH TUA 1L "1 September 1991" "Release 3.3" "LOCAL USER COMMANDS"
  955. .SH NAME
  956. TUA \- The Uucp Analyzer
  957. .SH SYNOPSIS
  958. .B tua
  959. [ option ]
  960. .SH DESCRIPTION
  961. .LP
  962. The purpose of the
  963. .I TUA
  964. utility is to produce a readable and complete analysis of the
  965. .IR HoneyDanbeer
  966. UUCP connections.
  967. This manual page describes the 
  968. .I TUA
  969. command line options and shortly explains its output.
  970. .SH OPTIONS
  971. To specify any of the options, you can use either the short form or the
  972. more mnemonic long form. In the latter case, you can abbreviate the name
  973. as long as it is unique. For more information on the long format, please
  974. refer to the
  975. .IR "GNU getopt"
  976. package description.
  977. .sp 1
  978. .TP 0.5i
  979. .B \-S, +no-sys-rep
  980. Do not print the
  981. .BR "per System report" .
  982. The default is to print it out.
  983. .TP 0.5i
  984. .B \-U, +no-user-rep
  985. Do not print the
  986. .BR "per User report" .
  987. The default is to print it out.
  988. .TP 0.5i
  989. .B \-D, +no-daily-rep
  990. Do not print the
  991. .BR "Daily report" .
  992. The default is to print it out.
  993. .TP 0.5i
  994. .B \-C, +command-lists
  995. Show also the command lists. It is off by default because it makes TUA very
  996. hungry of memory.
  997. .TP 0.5i
  998. .BI "\-O, +only-system " SYSTEM
  999. Consider just system
  1000. .I SYSTEM
  1001. in the reports. You can specify more than one of this option, so you can have
  1002. TUA consider just those systems.
  1003. .TP 0.5i
  1004. .B \-m, +no-monthly-act
  1005. Do not output the last 12 months activity summary.
  1006. .TP 0.5i
  1007. .B \-h, +no-history
  1008. Do not output the history at the end of the reports.
  1009. .TP 0.5i
  1010. .B \-c, +separate-com
  1011. Separate command lists from the other data. So there will be two tables
  1012. with the header
  1013. .I "By System" ,
  1014. the first containing only the amounts and the timing of each transfer,
  1015. the second with all the commands invoked by each System. You must specify
  1016. also the
  1017. .B \-C
  1018. option to make it works.
  1019. .TP 0.5i
  1020. .BI "\-k, +kill-system " SYSTEM
  1021. Eliminate each reference to
  1022. .I SYSTEM
  1023. from the reports. Neither the transfer table nor the
  1024. .I SYSTEM
  1025. command list will be printed.
  1026. .TP 0.5i
  1027. .BI "\-K, +kill-user " USER
  1028. Like
  1029. .B \-k
  1030. , but it applies to the user called
  1031. .I USER .
  1032. .TP 0.5i
  1033. .B \-H, +update-hist
  1034. Update the
  1035. .I history
  1036. database (see the FILES section below) with the new values. You must have
  1037. the
  1038. .B uucp
  1039. write permission.
  1040. .TP 0.5i
  1041. .B \-0, +reset-hist
  1042. Reset the
  1043. .I history
  1044. database, deleting any systems in it. Then put in the database the
  1045. analysis since the last
  1046. .I uuclean .
  1047. You have to specify also
  1048. .B \-H
  1049. to make this option do his job.
  1050. .TP 0.5i
  1051. .B \-y, +no-hourly-chart
  1052. Do not display the hourly activity chart.
  1053. .TP 0.5i
  1054. .BI "-z, +chart-size " SIZE
  1055. Set the size of the hourly activity chart to
  1056. .I SIZE
  1057. rows. The greater is this number, the smaller is the scale. By default it
  1058. is set to 10.
  1059. .TP 0.5i
  1060. .B \-o, +chart-only
  1061. Display only the hourly activity chart. Since with this options
  1062. .I TUA
  1063. reads only 
  1064. .BR .Admin/xferstats ,
  1065. it is faster.
  1066. .TP 0.5i
  1067. .B \-v, +verbose
  1068. Print, on standard error, what is going on. While
  1069. .I TUA
  1070. reads the various logs, it displays a counter of the loaded lines.
  1071. .TP 0.5i
  1072. .BI "\-p, +prefix-path " PATH
  1073. By default,
  1074. .I TUA
  1075. looks for uucp data in 
  1076. .BR "/usr/spool/uucp/"
  1077. and in the relative subdirectory. For debugging purpose, this option lets you
  1078. change this directory, so that
  1079. .I TUA
  1080. looks for the data in the specified
  1081. .I PATH.
  1082. Below this point
  1083. .I TUA
  1084. needs a hierarchy like the standard one (see FILES below).
  1085. .TP 0.5i
  1086. .B \-i, +help
  1087. Show a summary and a description of all the options.
  1088. .SH OUTPUT
  1089. All reports are printed on the standard output, so you can easily
  1090. redirect them wherever you want. Assuming, unless otherwise stated,
  1091. that you do not explicity request to disable some of the reports
  1092. (eg. when you do not specify
  1093. any command line option), here is a short description of what you get.
  1094. .Sh "By System"
  1095. With this report, you get all the information relative to all the 
  1096. nodes that talk with your machine but those which didn't sent or received
  1097. something. The data are divided in 
  1098. .I inbound
  1099. and
  1100. .I outbound.
  1101. For each system, displayed in alphabetical order, you have the total 
  1102. count of the files transferred, with the relative 
  1103. bytes and times, as well as an average transfer rate (ATP). 
  1104. If
  1105. .B \+commands-lists
  1106. was specified, next there is
  1107. the list of the commands invoked by that node, or directed to it. If a
  1108. command is preceeded by a number between brackets, that number indicates how 
  1109. many times that command was invoked.
  1110. .Sh "By User"
  1111. This report is similar to the previous one, but it shows, in
  1112. alphabetical order for each local user, all the commands the user invoked, 
  1113. and the transfers he caused.
  1114. .Sh "By Day"
  1115. This report summarize the per day activity on the local machine. It doesn't
  1116. depend on the destinations and on the users.
  1117. .Sh "SUMMARY by System"
  1118. It shows a summary of the activity of each system, and the number of calls
  1119. (inbound and outbound) for it. Please note that sometimes
  1120. .I TUA
  1121. fails in calculating the exact number of calls, because of the misleading 
  1122. log of uucico. Note also that the "total connection time" always differs from
  1123. the sum of the trasmissions times, because it takes care also of the various
  1124. uucp dead time. In fact, it is calculated from the difference between
  1125. the time in which the nodes are really connected (ie. at the end of dial 
  1126. phase, when the modem answers) and the time in which the link is dropped, 
  1127. due to the the end of the conversation as well as to any error.
  1128. Then comes the time of the last connection with that system.
  1129. There is also the subdivision of the connection time based on the phone
  1130. costs, ie "day", "evening", "night". This is completely configurable,
  1131. so if your telephone company uses a different hourly division you can
  1132. adjust it (see
  1133. .BR config.h
  1134. and
  1135. .BR phonesw.c .)
  1136. .Sh "SUMMARY by System (table format)"
  1137. Substancially, this report summarizes some of the previous informations in a
  1138. tabular form. Nothing new...
  1139. .Sh "and since ..."
  1140. This is the historical data maintained by
  1141. .I TUA.
  1142. It looks like the previous table, but it includes the history
  1143. of the system, incrementally.
  1144. .Sh "Last 12 Months Activity"
  1145. This table shows the activity of the local machine during the last 12 months.
  1146. Only the transferred amounts are computed.
  1147. .br
  1148. The months are displayed in a manner so that the last column contains the
  1149. current one, so it is very readable (of course, it is a matter of opinions!)
  1150. .Sh "Hourly Activity (per communication port)"
  1151. This chart shows the uucp hourly load for each used communication port. 
  1152. Each hour is divided in 20 minutes slices. 
  1153. .Sh "Global Hourly Activity"
  1154. The same as the previous chart, but it reports the sums of all the ports.
  1155. .SH HISTORY
  1156. .I TUA
  1157. maintains a database with the history of each system and of the activity
  1158. in each of the last 12 months
  1159. activities. It is usually located in
  1160. .BR /usr/spool/uucp/.Admin/tua.history
  1161. and it is actually an ASCII file. It is up to you to update it or not, because
  1162. probably you will like to run
  1163. .I TUA
  1164. simply to have a notion of what is going on. To make it working correctly, 
  1165. you have to run
  1166. .I TUA
  1167. with the option 
  1168. .BR +update-hist 
  1169. just before you run uuclean. So probably you will have to modify that
  1170. script including in it a line like
  1171. .nf
  1172. X
  1173. X        tua +update-hist {whatever options you like} | mail lele
  1174. X
  1175. .fi
  1176. before it cleans up the uucp logs.
  1177. .SH BUGS
  1178. Since HDB\-Uucp doesn't put a complete datestamp in its logs, but omits
  1179. the year, it may be possible that
  1180. .IR TUA
  1181. fails to compute the various times in the first analysis of the year.
  1182. This is in my opinion its major weakness. For this silliness,
  1183. .IR TUA
  1184. cannot correctly handle logs that cover several years. There is little
  1185. that I can do to correct the situation; I tried to adjust the year
  1186. when the to\-be\-parsed date refers obviously to the previous year,
  1187. but this is just a work\-around...
  1188. .PP
  1189. There is a limit: if your system spent more than 9999 hours
  1190. linked with someone (or the sum exceed that value), the reports will be
  1191. garbaged...
  1192. .SH DISCLAIMER
  1193. .I TUA
  1194. is
  1195. .BR free ,
  1196. and it is redistribuitable under the terms of the GNU
  1197. General Public License. You can find a copy of it in the file
  1198. .BR COPYING
  1199. in the distribution package.
  1200. I reject any responsability about it. It is simple and safe, but
  1201. I did not try it under all the possible conditions and environments, so if it
  1202. causes you some trouble, I'll be sad for a while, but that's it. However, 
  1203. I will try to correct any bugs you will tell me.
  1204. .PP
  1205. And 
  1206. .BR please,
  1207. forgive my poor english, but I put my soul in it...
  1208. .SH AUTHOR
  1209. Lele Gaifas, Idea Informatica, Rovereto (TN) - Italy
  1210. .br
  1211. ( piggy@idea.sublink.org )
  1212. .SH FILES
  1213. X .../.Log/uucico/*       uucico's logs
  1214. X .../.Log/uucp/*         uucp's logs
  1215. X .../.Log/uux/*          uux's logs
  1216. X .../.Log/uuxqt/*        uuxqt's logs
  1217. X .../.Admin/xferstat     Transfer stats
  1218. X .../.Admin/tua.history  TUA's system history
  1219. .SH BUGS REPORT TO
  1220. Lele Gaifas, piggy@idea.sublink.org
  1221. .SH ACKNOLEDGMENT
  1222. I want to thank expecially Marco Lorenzini 
  1223. (marlor@gear.sublink.org) for his help in debugging the previous 
  1224. releases of
  1225. .I TUA
  1226. on the SCO Unix architecture, and for his suggestions on the layout of
  1227. the reports. And to the "omnipresent" Paolo Ventafridda 
  1228. (venta@i2ack.sublink.org) for his support and interest, and several
  1229. other people that encouraged me to add more and more functionality, or
  1230. that let me scan their huge logs.
  1231. .br
  1232. Thanks also to all the people that, with their PD or GPL software, helped
  1233. me indirectly with ideas or examples.
  1234. SHAR_EOF
  1235. chmod 0444 tua.man ||
  1236. echo 'restore of tua.man failed'
  1237. Wc_c="`wc -c < 'tua.man'`"
  1238. test 10875 -eq "$Wc_c" ||
  1239.     echo 'tua.man: original size 10875, current size' "$Wc_c"
  1240. fi
  1241. # ============= porttree.c ==============
  1242. if test -f 'porttree.c' -a X"$1" != X"-c"; then
  1243.     echo 'x - skipping porttree.c (File already exists)'
  1244. else
  1245. echo 'x - extracting porttree.c (Text)'
  1246. sed 's/^X//' << 'SHAR_EOF' > 'porttree.c' &&
  1247. /* $Id: porttree.c,v 3.3 1991/09/01 14:03:49 piggy Rel $
  1248. X * Port tree management
  1249. X *
  1250. X *   Copyright (C) 1991  Lele Gaifax (piggy@idea.sublink.org)
  1251. X *
  1252. X *   This program is free software; you can redistribute it and/or modify
  1253. X *   it under the terms of the GNU General Public License as published by
  1254. X *   the Free Software Foundation; either version 1, or (at your option)
  1255. X *   any later version.
  1256. X *
  1257. X *   This program is distributed in the hope that it will be useful,
  1258. X *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  1259. X *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  1260. X *   GNU General Public License for more details.
  1261. X *
  1262. X *   You should have received a copy of the GNU General Public License
  1263. X *   along with this program; if not, write to the Free Software
  1264. X *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  1265. X *
  1266. X * SYNOPSIS:
  1267. X * int InsertPort(char * port)
  1268. X *    Look for port in the tree. If it is already there, return a pointer
  1269. X *    to its info. Otherwise make a new entry and initialize it.
  1270. X *
  1271. X * void EnquiryPort(void (*funct)(portact_t port))
  1272. X *    For each node in the tree, process it through funct.
  1273. X *
  1274. X * void KillPort(char * port)
  1275. X *    Do not show that port in any report.
  1276. X *
  1277. X */
  1278. X
  1279. #include <stdio.h>
  1280. #include "mem.h"
  1281. #include <string.h>
  1282. #include "hdbstat.h"
  1283. X
  1284. typedef struct porttree
  1285. {
  1286. X  portact_t Node;
  1287. X  struct porttree *L;
  1288. X  struct porttree *R;
  1289. } porttree_t;
  1290. X
  1291. #define TNULL    (porttree_t *) NULL
  1292. X
  1293. static FlistHead PortFlist =
  1294. {
  1295. X  0, 0, 0
  1296. };
  1297. X
  1298. static porttree_t *Root = TNULL;
  1299. X
  1300. static portact_t *
  1301. PortTree (tree, port)
  1302. X     porttree_t **tree;
  1303. X     char *port;
  1304. {
  1305. X  int cmpres;
  1306. X
  1307. X  if (*tree == TNULL)
  1308. X    {
  1309. X      register portact_t *sr;
  1310. X      int idx;
  1311. X
  1312. X      if (PortFlist.size == 0)
  1313. X    MemInit (&PortFlist, sizeof (porttree_t), 5, 5);
  1314. X      *tree = (porttree_t *) new (&PortFlist);
  1315. X      (*tree)->L = (*tree)->R = TNULL;
  1316. X      sr = &((*tree)->Node);
  1317. X      sr->Port = strdup (port);
  1318. X      sr->Killed = FALSE;
  1319. X      for (idx = 0; idx < TIMESLICES; idx++)
  1320. X    sr->Activity[idx] = 0.0;
  1321. X      return (&(*tree)->Node);
  1322. X    }
  1323. X  else if ((cmpres = strcmp (port, (*tree)->Node.Port)) < 0)
  1324. X    return PortTree (&(*tree)->L, port);
  1325. X  else if (cmpres > 0)
  1326. X    return PortTree (&(*tree)->R, port);
  1327. X  else
  1328. X    return (&(*tree)->Node);
  1329. }
  1330. X
  1331. portact_t *
  1332. InsertPort (port)
  1333. X     char *port;
  1334. {
  1335. X  return PortTree (&Root, port);
  1336. }
  1337. X
  1338. void
  1339. KillPort (port)
  1340. X     char *port;
  1341. {
  1342. X  PortTree (&Root, port)->Killed = TRUE;
  1343. }
  1344. X
  1345. static void
  1346. ProcPortTree (tree, funct)
  1347. X     porttree_t *tree;
  1348. X     void (*funct) ();
  1349. {
  1350. X  if (tree != TNULL)
  1351. X    {
  1352. X      ProcPortTree (tree->L, funct);
  1353. X      if (!(tree->Node.Killed))
  1354. X    (*funct) (tree->Node);
  1355. X      ProcPortTree (tree->R, funct);
  1356. X    }
  1357. }
  1358. X
  1359. void
  1360. EnquiryPort (funct)
  1361. X     void (*funct) ();
  1362. {
  1363. X  ProcPortTree (Root, funct);
  1364. }
  1365. SHAR_EOF
  1366. chmod 0444 porttree.c ||
  1367. echo 'restore of porttree.c failed'
  1368. Wc_c="`wc -c < 'porttree.c'`"
  1369. test 2763 -eq "$Wc_c" ||
  1370.     echo 'porttree.c: original size 2763, current size' "$Wc_c"
  1371. fi
  1372. # ============= phonesw.c ==============
  1373. if test -f 'phonesw.c' -a X"$1" != X"-c"; then
  1374.     echo 'x - skipping phonesw.c (File already exists)'
  1375. else
  1376. echo 'x - extracting phonesw.c (Text)'
  1377. sed 's/^X//' << 'SHAR_EOF' > 'phonesw.c' &&
  1378. /* $Id: phonesw.c,v 3.3 1991/09/01 14:03:52 piggy Rel $
  1379. X * Return an index based on the day, hour and minute we are working
  1380. X *
  1381. X *   Copyright (C) 1991  Lele Gaifax (piggy@idea.sublink.org)
  1382. X *
  1383. X *   This program is free software; you can redistribute it and/or modify
  1384. X *   it under the terms of the GNU General Public License as published by
  1385. X *   the Free Software Foundation; either version 1, or (at your option)
  1386. X *   any later version.
  1387. X *
  1388. X *   This program is distributed in the hope that it will be useful,
  1389. X *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  1390. X *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  1391. X *   GNU General Public License for more details.
  1392. X *
  1393. X *   You should have received a copy of the GNU General Public License
  1394. X *   along with this program; if not, write to the Free Software
  1395. X *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  1396. X *
  1397. X * SYNOPSIS:
  1398. X * int  GetPhonePrice(int day, int hour, int minute)
  1399. X *      Return an index in PHONE_PRICING_TB_NAMES, calculated from day, hour,
  1400. X *      minute.
  1401. X *
  1402. X * NOTE: Probably you'll need to customize this function for your country.
  1403. X *       Please, include your code, if any, between ifdefs, as I did, and
  1404. X *       send me the diffs, so I can keep this file up to date ;-)
  1405. X */
  1406. X
  1407. #include "hdbstat.h"
  1408. X
  1409. /*
  1410. X * ITALY
  1411. X */
  1412. #ifdef ITALY
  1413. X
  1414. #define PEAK_TIME       0
  1415. #define NORMAL_TIME     1
  1416. #define EVENING_TIME    2
  1417. #define NIGHT_TIME      3
  1418. X
  1419. char *PhoneCategoryNames[] =
  1420. {
  1421. X  "Peak Time   ",        /* 8:30am to 1pm */
  1422. X  "Normal Time ",        /* 8am to 8:30am, 1pm to 6:30pm */
  1423. X  "Evening Time",        /* 6:30pm to 10pm */
  1424. X  "Night Time  "        /* 10pm to 8 am */
  1425. };
  1426. X
  1427. /*
  1428. X * This function get the Day of the Week, the Hour, and the Minute, and
  1429. X * return an integer indicating in which timebelt we are.
  1430. X */
  1431. X
  1432. int
  1433. GetPhonePrice (day, hour, min)
  1434. X     int day, hour, min;
  1435. X
  1436. {
  1437. X  int retvalue;
  1438. X  
  1439. X  switch (day)
  1440. X    {
  1441. X    case 0:            /* Sunday */
  1442. X      retvalue = ((hour < 8 || hour >= 22) ? NIGHT_TIME : EVENING_TIME);
  1443. X      break;
  1444. X
  1445. X    case 1:
  1446. X    case 2:
  1447. X    case 3:
  1448. X    case 4:
  1449. X    case 5:
  1450. X      if (hour < 8 || hour >= 22)
  1451. X    retvalue = NIGHT_TIME;
  1452. X      else if (hour > 18 || (hour == 18 && min >= 30))
  1453. X    retvalue = EVENING_TIME;
  1454. X      else if ((hour > 8 && hour < 13) || (hour == 8 && min >= 30))
  1455. X    retvalue = PEAK_TIME;
  1456. X      else retvalue = NORMAL_TIME;
  1457. X      break;
  1458. X      
  1459. X    case 6:            /* Saturday */
  1460. X      if (hour < 8 || hour >= 22)
  1461. X    retvalue = NIGHT_TIME;
  1462. X      else if (hour >= 8 && hour < 13)
  1463. X    retvalue = PEAK_TIME;
  1464. X      else retvalue = EVENING_TIME;
  1465. X      break;
  1466. X    }
  1467. X  return retvalue;
  1468. }
  1469. X
  1470. #undef PEAK_TIME
  1471. #undef NORMAL_TIME
  1472. #undef EVENING_TIME
  1473. #undef NIGHT_TIME
  1474. #endif /* ifdef ITALY */
  1475. X
  1476. /*
  1477. X * UNITED KINGDOM
  1478. X */
  1479. #ifdef UK
  1480. X
  1481. #define    UK_PEAK        0
  1482. #define    UK_NORMAL    1
  1483. #define    UK_CHEAP    2
  1484. X
  1485. char *PhoneCategoryNames[] =
  1486. {
  1487. X  "Peak Rate   ",        /* UK_PEAK    9:00am to 1pm */
  1488. X  "Normal Rate ",        /* UK_NORMAL    8am to 9.00am, 1pm to 6:00pm */
  1489. X  "Cheap Rate  "        /* UK_CHEAP    6pm to 8 am */
  1490. };
  1491. X
  1492. /*
  1493. X * This function get the Day of the Week, the Hour, and the Minute, and
  1494. X * return an integer indicating in which timebelt we are.
  1495. X */
  1496. X
  1497. int
  1498. GetPhonePrice (day, hour, min)
  1499. X     int day, hour, min;
  1500. X
  1501. {
  1502. X  int retvalue;
  1503. X  
  1504. X  switch (day)
  1505. X    {
  1506. X    case 0:            /* Sunday */
  1507. X    case 6:            /* Saturday */
  1508. X      retvalue = UK_CHEAP;
  1509. X      break;
  1510. X
  1511. X    case 1:
  1512. X    case 2:
  1513. X    case 3:
  1514. X    case 4:
  1515. X    case 5:
  1516. X      if (hour < 8 || hour >= 18)
  1517. X    retvalue = UK_CHEAP;
  1518. X      else if (hour >= 9 && hour < 13)
  1519. X    retvalue = UK_PEAK;
  1520. X      else
  1521. X    retvalue = UK_NORMAL;
  1522. X      break;
  1523. X    }
  1524. X  return retvalue;
  1525. }
  1526. X
  1527. #undef    UK_PEAK    
  1528. #undef    UK_NORMAL
  1529. #undef    UK_CHEAP
  1530. X
  1531. #endif /* ifdef UK */
  1532. X
  1533. SHAR_EOF
  1534. chmod 0444 phonesw.c ||
  1535. echo 'restore of phonesw.c failed'
  1536. Wc_c="`wc -c < 'phonesw.c'`"
  1537. test 3619 -eq "$Wc_c" ||
  1538.     echo 'phonesw.c: original size 3619, current size' "$Wc_c"
  1539. fi
  1540. # ============= gethostn.c ==============
  1541. if test -f 'gethostn.c' -a X"$1" != X"-c"; then
  1542.     echo 'x - skipping gethostn.c (File already exists)'
  1543. else
  1544. echo 'x - extracting gethostn.c (Text)'
  1545. sed 's/^X//' << 'SHAR_EOF' > 'gethostn.c' &&
  1546. /*
  1547. X * From Cnews as of 1 Jan 91
  1548. X *
  1549. X * Uglix gethostname simulation
  1550. X */
  1551. X
  1552. #include <sys/types.h>
  1553. #include <sys/utsname.h>
  1554. X
  1555. #define min(a, b) ((a) < (b)? (a): (b))
  1556. X
  1557. int
  1558. gethostname (buf, size)
  1559. X     char *buf;
  1560. X     int size;
  1561. {
  1562. X  struct utsname ugnm;
  1563. X  char *strncpy ();
  1564. X
  1565. X  if (uname (&ugnm) < 0)
  1566. X    return -1;
  1567. X  (void) strncpy (buf, ugnm.nodename, min (sizeof ugnm.nodename, size));
  1568. X  return 0;
  1569. }
  1570. SHAR_EOF
  1571. chmod 0444 gethostn.c ||
  1572. echo 'restore of gethostn.c failed'
  1573. Wc_c="`wc -c < 'gethostn.c'`"
  1574. test 394 -eq "$Wc_c" ||
  1575.     echo 'gethostn.c: original size 394, current size' "$Wc_c"
  1576. fi
  1577. true || echo 'restore of tua.1l failed'
  1578. echo End of part 4, continue with part 5
  1579. exit 0
  1580. exit 0 # Just in case...
  1581. -- 
  1582. Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
  1583. Sterling Software, IMD           UUCP:     uunet!sparky!kent
  1584. Phone:    (402) 291-8300         FAX:      (402) 291-4362
  1585. Please send comp.sources.misc-related mail to kent@uunet.uu.net.
  1586.