1*6a54128fSAndroid Build Coastguard Worker /*
2*6a54128fSAndroid Build Coastguard Worker * Copyright 1987, 1988 by MIT Student Information Processing Board
3*6a54128fSAndroid Build Coastguard Worker *
4*6a54128fSAndroid Build Coastguard Worker * Permission to use, copy, modify, and distribute this software and
5*6a54128fSAndroid Build Coastguard Worker * its documentation for any purpose is hereby granted, provided that
6*6a54128fSAndroid Build Coastguard Worker * the names of M.I.T. and the M.I.T. S.I.P.B. not be used in
7*6a54128fSAndroid Build Coastguard Worker * advertising or publicity pertaining to distribution of the software
8*6a54128fSAndroid Build Coastguard Worker * without specific, written prior permission. M.I.T. and the
9*6a54128fSAndroid Build Coastguard Worker * M.I.T. S.I.P.B. make no representations about the suitability of
10*6a54128fSAndroid Build Coastguard Worker * this software for any purpose. It is provided "as is" without
11*6a54128fSAndroid Build Coastguard Worker * express or implied warranty.
12*6a54128fSAndroid Build Coastguard Worker */
13*6a54128fSAndroid Build Coastguard Worker
14*6a54128fSAndroid Build Coastguard Worker #include "config.h"
15*6a54128fSAndroid Build Coastguard Worker #ifdef HAVE_UNISTD_H
16*6a54128fSAndroid Build Coastguard Worker #include <unistd.h>
17*6a54128fSAndroid Build Coastguard Worker #endif
18*6a54128fSAndroid Build Coastguard Worker #ifdef HAVE_STDLIB_H
19*6a54128fSAndroid Build Coastguard Worker #include <stdlib.h>
20*6a54128fSAndroid Build Coastguard Worker #endif
21*6a54128fSAndroid Build Coastguard Worker #ifdef HAVE_ERRNO_H
22*6a54128fSAndroid Build Coastguard Worker #include <errno.h>
23*6a54128fSAndroid Build Coastguard Worker #endif
24*6a54128fSAndroid Build Coastguard Worker #include <fcntl.h>
25*6a54128fSAndroid Build Coastguard Worker #include <sys/param.h>
26*6a54128fSAndroid Build Coastguard Worker #include <sys/types.h>
27*6a54128fSAndroid Build Coastguard Worker #include <sys/file.h>
28*6a54128fSAndroid Build Coastguard Worker #ifdef NEED_SYS_FCNTL_H
29*6a54128fSAndroid Build Coastguard Worker /* just for O_* */
30*6a54128fSAndroid Build Coastguard Worker #include <sys/fcntl.h>
31*6a54128fSAndroid Build Coastguard Worker #endif
32*6a54128fSAndroid Build Coastguard Worker #ifdef HAVE_SYS_WAIT_H
33*6a54128fSAndroid Build Coastguard Worker #include <sys/wait.h>
34*6a54128fSAndroid Build Coastguard Worker #endif
35*6a54128fSAndroid Build Coastguard Worker #include "ss_internal.h"
36*6a54128fSAndroid Build Coastguard Worker
ss_help(int argc,char const * const * argv,int sci_idx,pointer info_ptr)37*6a54128fSAndroid Build Coastguard Worker void ss_help(int argc, char const * const *argv, int sci_idx, pointer info_ptr)
38*6a54128fSAndroid Build Coastguard Worker {
39*6a54128fSAndroid Build Coastguard Worker char *buffer;
40*6a54128fSAndroid Build Coastguard Worker char const *request_name;
41*6a54128fSAndroid Build Coastguard Worker int code;
42*6a54128fSAndroid Build Coastguard Worker int fd, child;
43*6a54128fSAndroid Build Coastguard Worker register int idx;
44*6a54128fSAndroid Build Coastguard Worker register ss_data *info;
45*6a54128fSAndroid Build Coastguard Worker
46*6a54128fSAndroid Build Coastguard Worker request_name = ss_current_request(sci_idx, &code);
47*6a54128fSAndroid Build Coastguard Worker if (code != 0) {
48*6a54128fSAndroid Build Coastguard Worker ss_perror(sci_idx, code, "");
49*6a54128fSAndroid Build Coastguard Worker return; /* no ss_abort_line, if invalid invocation */
50*6a54128fSAndroid Build Coastguard Worker }
51*6a54128fSAndroid Build Coastguard Worker if (argc == 1) {
52*6a54128fSAndroid Build Coastguard Worker ss_list_requests(argc, argv, sci_idx, info_ptr);
53*6a54128fSAndroid Build Coastguard Worker return;
54*6a54128fSAndroid Build Coastguard Worker }
55*6a54128fSAndroid Build Coastguard Worker else if (argc != 2) {
56*6a54128fSAndroid Build Coastguard Worker /* should do something better than this */
57*6a54128fSAndroid Build Coastguard Worker buffer = malloc(80+2*strlen(request_name));
58*6a54128fSAndroid Build Coastguard Worker if (!buffer) {
59*6a54128fSAndroid Build Coastguard Worker ss_perror(sci_idx, 0,
60*6a54128fSAndroid Build Coastguard Worker "couldn't allocate memory to print usage message");
61*6a54128fSAndroid Build Coastguard Worker return;
62*6a54128fSAndroid Build Coastguard Worker }
63*6a54128fSAndroid Build Coastguard Worker sprintf(buffer, "usage:\n\t%s [topic|command]\nor\t%s\n",
64*6a54128fSAndroid Build Coastguard Worker request_name, request_name);
65*6a54128fSAndroid Build Coastguard Worker ss_perror(sci_idx, 0, buffer);
66*6a54128fSAndroid Build Coastguard Worker free(buffer);
67*6a54128fSAndroid Build Coastguard Worker return;
68*6a54128fSAndroid Build Coastguard Worker }
69*6a54128fSAndroid Build Coastguard Worker info = ss_info(sci_idx);
70*6a54128fSAndroid Build Coastguard Worker if (info->info_dirs == (char **)NULL) {
71*6a54128fSAndroid Build Coastguard Worker ss_perror(sci_idx, SS_ET_NO_INFO_DIR, (char *)NULL);
72*6a54128fSAndroid Build Coastguard Worker return;
73*6a54128fSAndroid Build Coastguard Worker }
74*6a54128fSAndroid Build Coastguard Worker if (info->info_dirs[0] == (char *)NULL) {
75*6a54128fSAndroid Build Coastguard Worker ss_perror(sci_idx, SS_ET_NO_INFO_DIR, (char *)NULL);
76*6a54128fSAndroid Build Coastguard Worker return;
77*6a54128fSAndroid Build Coastguard Worker }
78*6a54128fSAndroid Build Coastguard Worker for (fd = -1, idx = 0; info->info_dirs[idx] != (char *)NULL; idx++) {
79*6a54128fSAndroid Build Coastguard Worker buffer = malloc(strlen (info->info_dirs[idx]) + 1 +
80*6a54128fSAndroid Build Coastguard Worker strlen (argv[1]) + 6);
81*6a54128fSAndroid Build Coastguard Worker if (!buffer) {
82*6a54128fSAndroid Build Coastguard Worker ss_perror(sci_idx, 0,
83*6a54128fSAndroid Build Coastguard Worker "couldn't allocate memory for help filename");
84*6a54128fSAndroid Build Coastguard Worker return;
85*6a54128fSAndroid Build Coastguard Worker }
86*6a54128fSAndroid Build Coastguard Worker (void) strcpy(buffer, info->info_dirs[idx]);
87*6a54128fSAndroid Build Coastguard Worker (void) strcat(buffer, "/");
88*6a54128fSAndroid Build Coastguard Worker (void) strcat(buffer, argv[1]);
89*6a54128fSAndroid Build Coastguard Worker (void) strcat(buffer, ".info");
90*6a54128fSAndroid Build Coastguard Worker fd = open(buffer, O_RDONLY);
91*6a54128fSAndroid Build Coastguard Worker free(buffer);
92*6a54128fSAndroid Build Coastguard Worker if (fd >= 0)
93*6a54128fSAndroid Build Coastguard Worker break;
94*6a54128fSAndroid Build Coastguard Worker }
95*6a54128fSAndroid Build Coastguard Worker if (fd < 0) {
96*6a54128fSAndroid Build Coastguard Worker #define MSG "No info found for "
97*6a54128fSAndroid Build Coastguard Worker char *buf = malloc(strlen (MSG) + strlen (argv[1]) + 1);
98*6a54128fSAndroid Build Coastguard Worker if (!buf) {
99*6a54128fSAndroid Build Coastguard Worker ss_perror(sci_idx, 0,
100*6a54128fSAndroid Build Coastguard Worker "couldn't allocate memory to print error message");
101*6a54128fSAndroid Build Coastguard Worker return;
102*6a54128fSAndroid Build Coastguard Worker }
103*6a54128fSAndroid Build Coastguard Worker strcpy(buf, MSG);
104*6a54128fSAndroid Build Coastguard Worker strcat(buf, argv[1]);
105*6a54128fSAndroid Build Coastguard Worker ss_perror(sci_idx, 0, buf);
106*6a54128fSAndroid Build Coastguard Worker free(buf);
107*6a54128fSAndroid Build Coastguard Worker return;
108*6a54128fSAndroid Build Coastguard Worker }
109*6a54128fSAndroid Build Coastguard Worker switch (child = fork()) {
110*6a54128fSAndroid Build Coastguard Worker case -1:
111*6a54128fSAndroid Build Coastguard Worker ss_perror(sci_idx, errno, "Can't fork for pager");
112*6a54128fSAndroid Build Coastguard Worker (void) close(fd);
113*6a54128fSAndroid Build Coastguard Worker return;
114*6a54128fSAndroid Build Coastguard Worker case 0:
115*6a54128fSAndroid Build Coastguard Worker (void) dup2(fd, 0); /* put file on stdin */
116*6a54128fSAndroid Build Coastguard Worker ss_page_stdin();
117*6a54128fSAndroid Build Coastguard Worker default:
118*6a54128fSAndroid Build Coastguard Worker (void) close(fd); /* what can we do if it fails? */
119*6a54128fSAndroid Build Coastguard Worker while (wait(NULL) != child) {
120*6a54128fSAndroid Build Coastguard Worker /* do nothing if wrong pid */
121*6a54128fSAndroid Build Coastguard Worker };
122*6a54128fSAndroid Build Coastguard Worker }
123*6a54128fSAndroid Build Coastguard Worker }
124*6a54128fSAndroid Build Coastguard Worker
125*6a54128fSAndroid Build Coastguard Worker #ifndef HAVE_DIRENT_H
126*6a54128fSAndroid Build Coastguard Worker #include <sys/dir.h>
127*6a54128fSAndroid Build Coastguard Worker #else
128*6a54128fSAndroid Build Coastguard Worker #include <dirent.h>
129*6a54128fSAndroid Build Coastguard Worker #endif
130*6a54128fSAndroid Build Coastguard Worker
ss_add_info_dir(int sci_idx,char * info_dir,int * code_ptr)131*6a54128fSAndroid Build Coastguard Worker void ss_add_info_dir(int sci_idx, char *info_dir, int *code_ptr)
132*6a54128fSAndroid Build Coastguard Worker {
133*6a54128fSAndroid Build Coastguard Worker register ss_data *info;
134*6a54128fSAndroid Build Coastguard Worker DIR *d;
135*6a54128fSAndroid Build Coastguard Worker int n_dirs;
136*6a54128fSAndroid Build Coastguard Worker register char **dirs;
137*6a54128fSAndroid Build Coastguard Worker
138*6a54128fSAndroid Build Coastguard Worker info = ss_info(sci_idx);
139*6a54128fSAndroid Build Coastguard Worker if (info_dir == NULL || *info_dir == '\0') {
140*6a54128fSAndroid Build Coastguard Worker *code_ptr = SS_ET_NO_INFO_DIR;
141*6a54128fSAndroid Build Coastguard Worker return;
142*6a54128fSAndroid Build Coastguard Worker }
143*6a54128fSAndroid Build Coastguard Worker if ((d = opendir(info_dir)) == (DIR *)NULL) {
144*6a54128fSAndroid Build Coastguard Worker *code_ptr = errno;
145*6a54128fSAndroid Build Coastguard Worker return;
146*6a54128fSAndroid Build Coastguard Worker }
147*6a54128fSAndroid Build Coastguard Worker closedir(d);
148*6a54128fSAndroid Build Coastguard Worker dirs = info->info_dirs;
149*6a54128fSAndroid Build Coastguard Worker for (n_dirs = 0; dirs[n_dirs] != (char *)NULL; n_dirs++)
150*6a54128fSAndroid Build Coastguard Worker ; /* get number of non-NULL dir entries */
151*6a54128fSAndroid Build Coastguard Worker dirs = (char **)realloc((char *)dirs,
152*6a54128fSAndroid Build Coastguard Worker (unsigned)(n_dirs + 2)*sizeof(char *));
153*6a54128fSAndroid Build Coastguard Worker if (dirs == (char **)NULL) {
154*6a54128fSAndroid Build Coastguard Worker *code_ptr = ENOMEM;
155*6a54128fSAndroid Build Coastguard Worker return;
156*6a54128fSAndroid Build Coastguard Worker }
157*6a54128fSAndroid Build Coastguard Worker info->info_dirs = dirs;
158*6a54128fSAndroid Build Coastguard Worker dirs[n_dirs + 1] = (char *)NULL;
159*6a54128fSAndroid Build Coastguard Worker dirs[n_dirs] = malloc((unsigned)strlen(info_dir)+1);
160*6a54128fSAndroid Build Coastguard Worker if (dirs[n_dirs] == (char *)NULL) {
161*6a54128fSAndroid Build Coastguard Worker *code_ptr = ENOMEM;
162*6a54128fSAndroid Build Coastguard Worker return;
163*6a54128fSAndroid Build Coastguard Worker }
164*6a54128fSAndroid Build Coastguard Worker strcpy(dirs[n_dirs], info_dir);
165*6a54128fSAndroid Build Coastguard Worker *code_ptr = 0;
166*6a54128fSAndroid Build Coastguard Worker }
167*6a54128fSAndroid Build Coastguard Worker
ss_delete_info_dir(int sci_idx,char * info_dir,int * code_ptr)168*6a54128fSAndroid Build Coastguard Worker void ss_delete_info_dir(int sci_idx, char *info_dir, int *code_ptr)
169*6a54128fSAndroid Build Coastguard Worker {
170*6a54128fSAndroid Build Coastguard Worker register char **i_d;
171*6a54128fSAndroid Build Coastguard Worker register char **info_dirs;
172*6a54128fSAndroid Build Coastguard Worker
173*6a54128fSAndroid Build Coastguard Worker info_dirs = ss_info(sci_idx)->info_dirs;
174*6a54128fSAndroid Build Coastguard Worker for (i_d = info_dirs; *i_d; i_d++) {
175*6a54128fSAndroid Build Coastguard Worker if (!strcmp(*i_d, info_dir)) {
176*6a54128fSAndroid Build Coastguard Worker while (*i_d) {
177*6a54128fSAndroid Build Coastguard Worker *i_d = *(i_d+1);
178*6a54128fSAndroid Build Coastguard Worker i_d++;
179*6a54128fSAndroid Build Coastguard Worker }
180*6a54128fSAndroid Build Coastguard Worker *code_ptr = 0;
181*6a54128fSAndroid Build Coastguard Worker return;
182*6a54128fSAndroid Build Coastguard Worker }
183*6a54128fSAndroid Build Coastguard Worker }
184*6a54128fSAndroid Build Coastguard Worker *code_ptr = SS_ET_NO_INFO_DIR;
185*6a54128fSAndroid Build Coastguard Worker }
186