This commit was manufactured by cvs2svn to create tag
[krb5.git] / src / util / ss / help.c
1 /*
2  * Copyright 1987, 1988 by MIT Student Information Processing Board
3  *
4  * For copyright info, see copyright.h.
5  */
6
7 #include <sys/param.h>
8 #include <sys/types.h>
9 #include <sys/file.h>
10 #include <fcntl.h>      /* just for O_* */
11 #include <sys/wait.h>
12 #include "ss_internal.h"
13 #include "copyright.h"
14
15 extern int errno;
16
17 void ss_help (argc, argv, sci_idx, info_ptr)
18     int argc;
19     char const * const *argv;
20     int sci_idx;
21     pointer info_ptr;
22 {
23     char buffer[MAXPATHLEN];
24     char const *request_name;
25     int code;
26     int fd, child;
27     register int idx;
28     register ss_data *info;
29
30     request_name = ss_current_request(sci_idx, &code);
31     if (code != 0) {
32         ss_perror(sci_idx, code, "");
33         return;         /* no ss_abort_line, if invalid invocation */
34     }
35     if (argc == 1) {
36         ss_list_requests(argc, argv, sci_idx, info_ptr);
37         return;
38     }
39     else if (argc != 2) {
40         /* should do something better than this */
41         sprintf(buffer, "usage:\n\t%s [topic|command]\nor\t%s\n",
42                 request_name, request_name);
43         ss_perror(sci_idx, 0, buffer);
44         return;
45     }
46     info = ss_info(sci_idx);
47     if (info->info_dirs == (char **)NULL) {
48         ss_perror(sci_idx, SS_ET_NO_INFO_DIR, (char *)NULL);
49         return;
50     }
51     if (info->info_dirs[0] == (char *)NULL) {
52         ss_perror(sci_idx, SS_ET_NO_INFO_DIR, (char *)NULL);
53         return;
54     }
55     for (idx = 0; info->info_dirs[idx] != (char *)NULL; idx++) {
56         (void) strncpy(buffer, info->info_dirs[idx], sizeof(buffer) - 1);
57         buffer[sizeof(buffer) - 1] = '\0';
58         (void) strncat(buffer, "/", sizeof(buffer) - 1 - strlen(buffer));
59         (void) strncat(buffer, argv[1], sizeof(buffer) - 1 - strlen(buffer));
60         (void) strncat(buffer, ".info", sizeof(buffer) - 1 - strlen(buffer));
61         if ((fd = open(&buffer[0], O_RDONLY)) >= 0) goto got_it;
62     }
63     if ((fd = open(&buffer[0], O_RDONLY)) < 0) {
64         char buf[MAXPATHLEN];
65         strncpy(buf, "No info found for ", sizeof(buf) - 1);
66         buf[sizeof(buf) - 1] = '\0';
67         strncat(buf, argv[1], sizeof(buf) - 1 - strlen(buf));
68         ss_perror(sci_idx, 0, buf);
69         return;
70     }
71 got_it:
72     switch (child = fork()) {
73     case -1:
74         ss_perror(sci_idx, errno, "Can't fork for pager");
75         return;
76     case 0:
77         (void) dup2(fd, 0); /* put file on stdin */
78         ss_page_stdin();
79     default:
80         (void) close(fd); /* what can we do if it fails? */
81 #ifdef WAIT_USES_INT
82         while (wait((int *)NULL) != child) {
83 #else
84         while (wait((union wait *)NULL) != child) {
85 #endif
86             /* do nothing if wrong pid */
87         };
88     }
89 }
90
91 #ifndef USE_DIRENT_H
92 #include <sys/dir.h>
93 #else
94 #include <dirent.h>
95 #endif
96
97 void ss_add_info_dir(sci_idx, info_dir, code_ptr)
98     int sci_idx;
99     char *info_dir;
100     int *code_ptr;
101 {
102     register ss_data *info;
103     DIR *d;
104     int n_dirs;
105     register char **dirs;
106
107     info = ss_info(sci_idx);
108     if (info_dir == NULL && *info_dir) {
109         *code_ptr = SS_ET_NO_INFO_DIR;
110         return;
111     }
112     if ((d = opendir(info_dir)) == (DIR *)NULL) {
113         *code_ptr = errno;
114         return;
115     }
116     closedir(d);
117     dirs = info->info_dirs;
118     for (n_dirs = 0; dirs[n_dirs] != (char *)NULL; n_dirs++)
119         ;               /* get number of non-NULL dir entries */
120     dirs = (char **)realloc((char *)dirs,
121                             (unsigned)(n_dirs + 2)*sizeof(char *));
122     if (dirs == (char **)NULL) {
123         info->info_dirs = (char **)NULL;
124         *code_ptr = errno;
125         return;
126     }
127     info->info_dirs = dirs;
128     dirs[n_dirs + 1] = (char *)NULL;
129     dirs[n_dirs] = malloc((unsigned)strlen(info_dir)+1);
130     strcpy(dirs[n_dirs], info_dir);
131     *code_ptr = 0;
132 }
133
134 void ss_delete_info_dir(sci_idx, info_dir, code_ptr)
135     int sci_idx;
136     char *info_dir;
137     int *code_ptr;
138 {
139     register char **i_d;
140     register char **info_dirs;
141
142     info_dirs = ss_info(sci_idx)->info_dirs;
143     for (i_d = info_dirs; *i_d; i_d++) {
144         if (!strcmp(*i_d, info_dir)) {
145             while (*i_d) {
146                 *i_d = *(i_d+1);
147                 i_d++;
148             }
149             *code_ptr = 0;
150             return;
151         }
152     }
153     *code_ptr = SS_ET_NO_INFO_DIR;
154 }