1 /*
   2  * Copyright 1995-2002 Sun Microsystems, Inc.  All rights reserved.
   3  * Use is subject to license terms.
   4  */
   5 
   6 #pragma ident   "%Z%%M% %I%     %E% SMI"
   7 
   8 /*
   9  * Test client for kwarnd.  This program is not shipped on the binary
  10  * release. This code was taken and modified from gssdtest.c
  11  */
  12 
  13 #include <stdio.h>
  14 #include <strings.h>
  15 #include <ctype.h>
  16 #include <stdlib.h>
  17 #include "kwarnd.h"
  18 #include <rpc/rpc.h>
  19 
  20 #define LOOP_COUNTER  100
  21 
  22 #define OCTAL_MACRO "%03.3o."
  23 #define MALLOC(n) malloc(n)
  24 #define CALLOC(n, s) calloc((n), (s))
  25 #define FREE(x, n) free(x)
  26 
  27 static void instructs(void);
  28 static void usage(void);
  29 static int parse_input_line(char *, int *, char ***);
  30 extern uid_t getuid(void);
  31 
  32 static void _kwarnd_add_warning(int, char **);
  33 static void _kwarnd_del_warning(int, char **);
  34 
  35 static int do_kwarndtest(char *buf);
  36 
  37 extern OM_UINT32 kwarn_add_warning();
  38 extern OM_UINT32 kwarn_del_warning();
  39 
  40 static int read_line(char *buf, int size)
  41 {
  42         int len;
  43 
  44         /* read the next line. If cntl-d, return with zero char count */
  45         printf(gettext("\n> "));
  46 
  47         if (fgets(buf, size, stdin) == NULL)
  48                 return (0);
  49 
  50         len = strlen(buf);
  51         buf[--len] = '\0';
  52         return (len);
  53 }
  54 
  55 int
  56 main()
  57 {
  58         char buf[512];
  59         int len, ret;
  60 
  61         /* Print out usage and instructions to start off the session */
  62 
  63         instructs();
  64         usage();
  65 
  66         /*
  67          * Loop, repeatedly calling parse_input_line() to get the
  68          * next line and parse it into argc and argv. Act on the
  69          * arguements found on the line.
  70          */
  71 
  72         do {
  73                 len = read_line(buf, 512);
  74                 if (len)
  75                         ret = do_kwarndtest(buf);
  76         } while (len && !ret);
  77 
  78         return (0);
  79 }
  80 
  81 static int
  82 do_kwarndtest(char *buf)
  83 {
  84         int argc;
  85         char **argv, **argv_array;
  86 
  87         char *cmd;
  88 
  89         argv = 0;
  90 
  91         if (parse_input_line(buf, &argc, &argv) == 0) {
  92                 printf(gettext("\n"));
  93                 return (1);
  94         }
  95 
  96         if (argc == 0) {
  97                 usage();
  98                 /*LINTED*/
  99                 FREE(argv_array, (argc+1)*sizeof (char *));
 100                 return (0);
 101         }
 102 
 103         /*
 104          * remember argv_array address, which is memory calloc'd by
 105          * parse_input_line, so it can be free'd at the end of the loop.
 106          */
 107 
 108         argv_array = argv;
 109 
 110         cmd = argv[0];
 111 
 112         argc--;
 113         argv++;
 114 
 115         if (strcmp(cmd, "kwarn_add_warning") == 0 ||
 116             strcmp(cmd, "add") == 0) {
 117                 _kwarnd_add_warning(argc, argv);
 118         } else if (strcmp(cmd, "kwarn_del_warning") == 0 ||
 119                 strcmp(cmd, "delete") == 0) {
 120                 _kwarnd_del_warning(argc, argv);
 121         } else if (strcmp(cmd, "exit") == 0) {
 122                 printf(gettext("\n"));
 123                 FREE(argv_array, (argc+2) * sizeof (char *));
 124                 return (1);
 125         } else
 126                 usage();
 127 
 128         /* free argv array */
 129 
 130         FREE(argv_array, (argc+2) * sizeof (char *));
 131         return (0);
 132 }
 133 
 134 static void
 135 _kwarnd_add_warning(int argc, char **argv)
 136 {
 137         OM_UINT32 status;
 138         time_t  exptime;
 139         time_t  now;
 140 
 141         /* set up the arguments specified in the input parameters */
 142 
 143         if (argc == 0) {
 144                 usage();
 145                 return;
 146         }
 147 
 148         if (argc != 2) {
 149                 usage();
 150                 return;
 151         }
 152 
 153         time(&now);
 154         exptime = atol(argv[1]);
 155         exptime = now + exptime;
 156 
 157         status = kwarn_add_warning(argv[0], exptime);
 158 
 159         if (status == 0) {
 160                 printf(gettext("\nadd of credential\n\n"));
 161                 printf(gettext("warning message successful for \"%s\"\n\n"),
 162                         argv[0]);
 163         } else {
 164                 printf(gettext("server ret err (octal) %o (%s)\n"),
 165                         status, gettext("add warning error"));
 166         }
 167 
 168         return;
 169 
 170 }
 171 
 172 static void
 173 _kwarnd_del_warning(int argc, char **argv)
 174 {
 175         OM_UINT32 status;
 176 
 177         if (argc != 1) {
 178                 usage();
 179                 return;
 180         }
 181 
 182         status = kwarn_del_warning(argv[0]);
 183 
 184         if (status == 0) {
 185                 printf(gettext("delete of principal warning message"
 186                                 "for %s successful"),
 187                         argv[0]);
 188         } else {
 189                 printf(gettext("delete of principal %s unsuccessful\n\n"),
 190                         argv[0]);
 191         }
 192 }
 193 
 194 static void
 195 instructs(void)
 196 {
 197         fprintf(stderr,
 198                 gettext(
 199 "\nThis program will test kwarnd.  kwarnd must be running as root. Enter\n"
 200 "the desired command and the principal to be added/deleted. If adding a\n"
 201 "principal, also include the expiration time in seconds.\n"));
 202 }
 203 
 204 static void
 205 usage(void)
 206 {
 207         fprintf(stderr,
 208                 gettext(
 209                 "\nusage:\t[kwarn_add_warning | add] (principal) (exptime)\n"
 210                 "\t[kwarn_del_warning | delete] (principal)\n"
 211                 "\texit\n\n"));
 212 }
 213 
 214 /* Copied from parse_argv(), then modified */
 215 
 216 static int
 217 parse_input_line(char *input_line, int *argc, char ***argv)
 218 {
 219         const char nil = '\0';
 220         char *chptr;
 221         int chr_cnt;
 222         int arg_cnt = 0;
 223         int ch_was_space = 1;
 224         int ch_is_space;
 225 
 226         chr_cnt = strlen(input_line);
 227 
 228         /* Count the arguments in the input_line string */
 229 
 230         *argc = 1;
 231 
 232         for (chptr = &input_line[0]; *chptr != nil; chptr++) {
 233                 ch_is_space = isspace(*chptr);
 234                 if (ch_is_space && !ch_was_space) {
 235                         (*argc)++;
 236                 }
 237                 ch_was_space = ch_is_space;
 238         }
 239 
 240         if (ch_was_space) {
 241                 (*argc)--;
 242         }       /* minus trailing spaces */
 243 
 244         /* Now that we know how many args calloc the argv array */
 245 
 246         *argv = (char **)CALLOC((*argc)+1, sizeof (char *));
 247         chptr = (char *)(&input_line[0]);
 248 
 249         for (ch_was_space = 1; *chptr != nil; chptr++) {
 250                 ch_is_space = isspace(*chptr);
 251                 if (ch_is_space) {
 252                         *chptr = nil;   /* replace each space with nil  */
 253                 } else if (ch_was_space) {      /* begining of word? */
 254                         (*argv)[arg_cnt++] = chptr;     /* new argument ? */
 255                 }
 256 
 257                 ch_was_space = ch_is_space;
 258         }
 259 
 260         return (chr_cnt);
 261 }