blob: 5a17164c2e678ef49e8532af685f00d33c247827 [file] [log] [blame]
Theodore Ts'o3839e651997-04-26 13:21:57 +00001/*
2 * Copyright 1987, 1988 by MIT Student Information Processing Board
3 *
4 * For copyright info, see copyright.h.
5 */
6
Theodore Ts'o50e1e101997-04-26 13:58:21 +00007#ifdef HAVE_UNISTD_H
Theodore Ts'of3db3561997-04-26 13:34:30 +00008#include <unistd.h>
9#endif
Theodore Ts'o50e1e101997-04-26 13:58:21 +000010#ifdef HAVE_STDLIB_H
Theodore Ts'of3db3561997-04-26 13:34:30 +000011#include <stdlib.h>
12#endif
Theodore Ts'o19c78dc1997-04-29 16:17:09 +000013#ifdef HAVE_ERRNO_H
14#include <errno.h>
15#else
16extern int errno;
17#endif
Theodore Ts'o50e1e101997-04-26 13:58:21 +000018#include <fcntl.h>
Theodore Ts'o3839e651997-04-26 13:21:57 +000019#include <sys/param.h>
20#include <sys/types.h>
21#include <sys/file.h>
22#ifdef NEED_SYS_FCNTL_H
23/* just for O_* */
24#include <sys/fcntl.h>
25#endif
26#include <sys/wait.h>
27#include "ss_internal.h"
28#include "copyright.h"
29
Theodore Ts'o3839e651997-04-26 13:21:57 +000030void ss_help (argc, argv, sci_idx, info_ptr)
31 int argc;
32 char const * const *argv;
33 int sci_idx;
34 pointer info_ptr;
35{
Theodore Ts'o50e1e101997-04-26 13:58:21 +000036 char *buffer;
Theodore Ts'o3839e651997-04-26 13:21:57 +000037 char const *request_name;
38 int code;
39 int fd, child;
40 register int idx;
41 register ss_data *info;
42
43 request_name = ss_current_request(sci_idx, &code);
44 if (code != 0) {
45 ss_perror(sci_idx, code, "");
46 return; /* no ss_abort_line, if invalid invocation */
47 }
48 if (argc == 1) {
49 ss_list_requests(argc, argv, sci_idx, info_ptr);
50 return;
51 }
52 else if (argc != 2) {
53 /* should do something better than this */
Theodore Ts'o50e1e101997-04-26 13:58:21 +000054 buffer = malloc(80+2*strlen(request_name));
55 if (!buffer) {
56 ss_perror(sci_idx, 0,
57 "couldn't allocate memory to print usage message");
58 return;
59 }
Theodore Ts'o3839e651997-04-26 13:21:57 +000060 sprintf(buffer, "usage:\n\t%s [topic|command]\nor\t%s\n",
61 request_name, request_name);
62 ss_perror(sci_idx, 0, buffer);
Theodore Ts'o50e1e101997-04-26 13:58:21 +000063 free(buffer);
Theodore Ts'o3839e651997-04-26 13:21:57 +000064 return;
65 }
66 info = ss_info(sci_idx);
67 if (info->info_dirs == (char **)NULL) {
68 ss_perror(sci_idx, SS_ET_NO_INFO_DIR, (char *)NULL);
69 return;
70 }
71 if (info->info_dirs[0] == (char *)NULL) {
72 ss_perror(sci_idx, SS_ET_NO_INFO_DIR, (char *)NULL);
73 return;
74 }
Theodore Ts'o50e1e101997-04-26 13:58:21 +000075 for (fd = -1, idx = 0; info->info_dirs[idx] != (char *)NULL; idx++) {
76 buffer = malloc(strlen (info->info_dirs[idx]) + 1 +
77 strlen (argv[1]) + 6);
78 if (!buffer) {
79 ss_perror(sci_idx, 0,
80 "couldn't allocate memory for help filename");
81 return;
82 }
Theodore Ts'o3839e651997-04-26 13:21:57 +000083 (void) strcpy(buffer, info->info_dirs[idx]);
84 (void) strcat(buffer, "/");
85 (void) strcat(buffer, argv[1]);
86 (void) strcat(buffer, ".info");
Theodore Ts'o50e1e101997-04-26 13:58:21 +000087 fd = open(buffer, O_RDONLY);
88 free(buffer);
89 if (fd >= 0)
90 break;
Theodore Ts'o3839e651997-04-26 13:21:57 +000091 }
Theodore Ts'o50e1e101997-04-26 13:58:21 +000092 if (fd < 0) {
93#define MSG "No info found for "
94 char *buf = malloc(strlen (MSG) + strlen (argv[1]) + 1);
95 strcpy(buf, MSG);
Theodore Ts'o3839e651997-04-26 13:21:57 +000096 strcat(buf, argv[1]);
97 ss_perror(sci_idx, 0, buf);
Theodore Ts'o50e1e101997-04-26 13:58:21 +000098 free(buf);
Theodore Ts'o3839e651997-04-26 13:21:57 +000099 return;
100 }
Theodore Ts'o3839e651997-04-26 13:21:57 +0000101 switch (child = fork()) {
102 case -1:
103 ss_perror(sci_idx, errno, "Can't fork for pager");
104 return;
105 case 0:
106 (void) dup2(fd, 0); /* put file on stdin */
107 ss_page_stdin();
108 default:
109 (void) close(fd); /* what can we do if it fails? */
Theodore Ts'of3db3561997-04-26 13:34:30 +0000110 while (wait(0) != child) {
Theodore Ts'o3839e651997-04-26 13:21:57 +0000111 /* do nothing if wrong pid */
112 };
113 }
114}
115
Theodore Ts'o50e1e101997-04-26 13:58:21 +0000116#ifndef HAVE_DIRENT_H
Theodore Ts'o3839e651997-04-26 13:21:57 +0000117#include <sys/dir.h>
118#else
119#include <dirent.h>
120#endif
121
122void ss_add_info_dir(sci_idx, info_dir, code_ptr)
123 int sci_idx;
124 char *info_dir;
125 int *code_ptr;
126{
127 register ss_data *info;
128 DIR *d;
129 int n_dirs;
130 register char **dirs;
131
132 info = ss_info(sci_idx);
133 if (info_dir == NULL && *info_dir) {
134 *code_ptr = SS_ET_NO_INFO_DIR;
135 return;
136 }
137 if ((d = opendir(info_dir)) == (DIR *)NULL) {
138 *code_ptr = errno;
139 return;
140 }
141 closedir(d);
142 dirs = info->info_dirs;
143 for (n_dirs = 0; dirs[n_dirs] != (char *)NULL; n_dirs++)
144 ; /* get number of non-NULL dir entries */
145 dirs = (char **)realloc((char *)dirs,
146 (unsigned)(n_dirs + 2)*sizeof(char *));
147 if (dirs == (char **)NULL) {
148 info->info_dirs = (char **)NULL;
149 *code_ptr = errno;
150 return;
151 }
152 info->info_dirs = dirs;
153 dirs[n_dirs + 1] = (char *)NULL;
154 dirs[n_dirs] = malloc((unsigned)strlen(info_dir)+1);
155 strcpy(dirs[n_dirs], info_dir);
156 *code_ptr = 0;
157}
158
159void ss_delete_info_dir(sci_idx, info_dir, code_ptr)
160 int sci_idx;
161 char *info_dir;
162 int *code_ptr;
163{
164 register char **i_d;
165 register char **info_dirs;
166
167 info_dirs = ss_info(sci_idx)->info_dirs;
168 for (i_d = info_dirs; *i_d; i_d++) {
169 if (!strcmp(*i_d, info_dir)) {
170 while (*i_d) {
171 *i_d = *(i_d+1);
172 i_d++;
173 }
174 *code_ptr = 0;
175 return;
176 }
177 }
178 *code_ptr = SS_ET_NO_INFO_DIR;
179}