tools/llvm: Do not build with symbols
[minix3.git] / external / bsd / nvi / dist / ip / ip_main.c
blob96ab53a4604b1a5deafcb350910d325d74174e7a
1 /* $NetBSD: ip_main.c,v 1.2 2013/11/22 15:52:05 christos Exp $ */
2 /*-
3 * Copyright (c) 1996
4 * Keith Bostic. All rights reserved.
6 * See the LICENSE file for redistribution information.
7 */
9 #include "config.h"
11 #ifndef lint
12 static const char sccsid[] = "Id: ip_main.c,v 8.24 2001/07/29 19:07:30 skimo Exp (Berkeley) Date: 2001/07/29 19:07:30 ";
13 #endif /* not lint */
15 #include <sys/types.h>
16 #include <sys/queue.h>
18 #include <bitstring.h>
19 #include <ctype.h>
20 #include <errno.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <unistd.h>
26 #include <sys/uio.h>
28 #include "../common/common.h"
29 #include "../ipc/ip.h"
31 GS *__global_list; /* GLOBAL: List of screens. */
33 static void ip_func_std __P((WIN *));
34 static IP_PRIVATE *ip_init __P((WIN *wp, int i_fd, int o_fd, int, int argc, char *argv[]));
35 static void perr __P((char *, char *));
36 static int get_fds __P((char *ip_arg, int *i_fd, int *o_fd));
37 static int get_connection __P((WIN *wp, int main_ifd, int main_ofd,
38 int *i_fd, int *o_fd, int *, int can_pass));
39 static void *run_editor __P((void * vp));
42 * ip_main --
43 * This is the main loop for the vi-as-library editor.
45 int
46 main(int argc, char **argv)
48 IP_PRIVATE *ipp;
49 char *ip_arg;
50 char **p_av, **t_av;
51 GS *gp;
52 WIN *wp;
53 int i_fd, o_fd, t_fd, main_ifd, main_ofd;
55 /* Create and initialize the global structure. */
56 __global_list = gp = gs_init(argv[0]);
59 * Strip out any arguments that vi isn't going to understand. There's
60 * no way to portably call getopt twice, so arguments parsed here must
61 * be removed from the argument list.
63 ip_arg = NULL;
64 for (p_av = t_av = argv;;) {
65 if (*t_av == NULL) {
66 *p_av = NULL;
67 break;
69 if (!strcmp(*t_av, "--")) {
70 while ((*p_av++ = *t_av++) != NULL);
71 break;
73 if (!memcmp(*t_av, "-I", sizeof("-I") - 1)) {
74 if (t_av[0][2] != '\0') {
75 ip_arg = t_av[0] + 2;
76 ++t_av;
77 --argc;
78 continue;
80 else if (t_av[1] != NULL) {
81 ip_arg = t_av[1];
82 t_av += 2;
83 argc -= 2;
84 continue;
87 *p_av++ = *t_av++;
90 if (get_fds(ip_arg, &main_ifd, &main_ofd))
91 return 1;
93 wp = NULL;
95 while (get_connection(wp, main_ifd, main_ofd, &i_fd, &o_fd, &t_fd, 1) == 0) {
96 /* Create new window */
97 wp = gs_new_win(gp);
99 /* Create and partially initialize the IP structure. */
100 if ((ipp = ip_init(wp, i_fd, o_fd, t_fd, argc, argv)) == NULL)
101 return (1);
103 gp->run(wp, run_editor, (void *)wp);
106 /* Clean out the global structure. */
107 gs_end(gp);
109 /* Free the global and IP private areas. */
110 #if defined(DEBUG) || defined(PURIFY) || defined(LIBRARY)
111 free(gp);
112 #endif
113 exit (0);
116 static void *
117 run_editor(void * vp)
119 GS *gp;
120 IP_PRIVATE *ipp;
121 WIN *wp;
122 EVENT ev;
123 int rval;
124 IP_BUF ipb;
126 wp = (WIN *) vp;
127 gp = wp->gp;
128 ipp = wp->ip_private;
130 /* Add the terminal type to the global structure. */
131 if ((OG_D_STR(gp, GO_TERM) =
132 OG_STR(gp, GO_TERM) = strdup("ip_curses")) == NULL)
133 perr(gp->progname, NULL);
136 * Figure out how big the screen is -- read events until we get
137 * the rows and columns.
139 for (;;) {
140 if (ip_wevent(wp, NULL, &ev, 0, 0))
141 return NULL;
142 if (ev.e_event == E_WRESIZE)
143 break;
144 if (ev.e_event == E_EOF || ev.e_event == E_ERR ||
145 ev.e_event == E_SIGHUP || ev.e_event == E_SIGTERM)
146 return NULL;
147 if (ev.e_event == E_IPCOMMAND && ev.e_ipcom == VI_QUIT)
148 return NULL;
151 /* Run ex/vi. */
152 rval = editor(wp, ipp->argc, ipp->argv);
154 /* Clean up the screen. */
155 (void)ip_quit(wp);
157 /* Send the quit message. */
158 ipb.code = SI_QUIT;
159 (void)vi_send(ipp->o_fd, NULL, &ipb);
161 /* Give the screen a couple of seconds to deal with it. */
162 sleep(2);
164 /* Remove window; correct place ? */
165 win_end(wp);
167 #if defined(DEBUG) || defined(PURIFY) || defined(LIBRARY)
168 free(ipp);
169 #endif
170 return NULL;
174 * ip_init --
175 * Create and partially initialize the GS structure.
177 static IP_PRIVATE *
178 ip_init(WIN *wp, int i_fd, int o_fd, int t_fd, int argc, char *argv[])
180 IP_PRIVATE *ipp;
182 /* Allocate the IP private structure. */
183 CALLOC_NOMSG(NULL, ipp, IP_PRIVATE *, 1, sizeof(IP_PRIVATE));
184 if (ipp == NULL)
185 perr(wp->gp->progname, NULL);
186 wp->ip_private = ipp;
188 ipp->i_fd = i_fd;
189 ipp->o_fd = o_fd;
190 ipp->t_fd = t_fd;
192 ipp->argc = argc;
193 ipp->argv = argv;
195 /* Initialize the list of ip functions. */
196 ip_func_std(wp);
198 return (ipp);
201 static int
202 get_fds(char *ip_arg, int *i_fd, int *o_fd)
204 char *ep;
207 * Crack ip_arg -- it's of the form #.#, where the first number is the
208 * file descriptor from the screen, the second is the file descriptor
209 * to the screen.
211 if (!ip_arg || !isdigit((unsigned char)ip_arg[0]))
212 goto usage;
213 *i_fd = strtol(ip_arg, &ep, 10);
214 if (ep[0] != '.' || !isdigit((unsigned char)ep[1]))
215 goto usage;
216 *o_fd = strtol(++ep, &ep, 10);
217 if (ep[0] != '\0') {
218 usage: ip_usage();
219 return 1;
222 return 0;
225 static int
226 get_connection(WIN *wp, int main_ifd, int main_ofd,
227 int *i_fd, int *o_fd, int *t_fd, int can_pass)
229 *t_fd = -1;
231 if (!can_pass) {
232 if (wp == NULL) { /* First call */
233 *i_fd = main_ifd;
234 *o_fd = main_ofd;
235 } else {
236 return 1;
238 } else {
239 struct msghdr mh;
240 IPCMSGHDR ch;
241 char dummy;
242 struct iovec iov;
244 mh.msg_namelen = 0;
245 mh.msg_iovlen = 1;
246 mh.msg_iov = &iov;
247 mh.msg_controllen = sizeof(ch);
248 mh.msg_control = (void *)&ch;
250 iov.iov_len = 1;
251 iov.iov_base = &dummy;
253 if (recvmsg(main_ifd, &mh, 0) != 1)
254 return 1;
255 *i_fd = *(int *)CMSG_DATA(&ch.header);
256 if (recvmsg(*i_fd, &mh, 0) != 1)
257 return 1;
258 *o_fd = *(int *)CMSG_DATA(&ch.header);
259 if (dummy == 'F') {
260 if (recvmsg(*i_fd, &mh, 0) != 1)
261 return 1;
262 *t_fd = *(int *)CMSG_DATA(&ch.header);
266 return 0;
270 * ip_func_std --
271 * Initialize the standard ip functions.
273 static void
274 ip_func_std(WIN *wp)
276 GS *gp;
278 gp = wp->gp;
280 gp->scr_addstr = ip_addstr;
281 gp->scr_waddstr = ip_waddstr;
282 gp->scr_attr = ip_attr;
283 gp->scr_baud = ip_baud;
284 gp->scr_bell = ip_bell;
285 gp->scr_busy = ip_busy;
286 gp->scr_child = ip_child;
287 gp->scr_clrtoeol = ip_clrtoeol;
288 gp->scr_cursor = ip_cursor;
289 gp->scr_deleteln = ip_deleteln;
290 gp->scr_discard = ip_discard;
291 gp->scr_event = ip_event;
292 gp->scr_ex_adjust = ip_ex_adjust;
293 gp->scr_fmap = ip_fmap;
294 gp->scr_insertln = ip_insertln;
295 gp->scr_keyval = ip_keyval;
296 gp->scr_move = ip_move;
297 wp->scr_msg = ip_msg;
298 gp->scr_optchange = ip_optchange;
299 gp->scr_refresh = ip_refresh;
300 gp->scr_rename = ip_rename;
301 gp->scr_reply = ip_reply;
302 gp->scr_screen = ip_screen;
303 gp->scr_split = ip_split;
304 gp->scr_suspend = ip_suspend;
305 gp->scr_usage = ip_usage;
309 * perr --
310 * Print system error.
312 static void
313 perr(char *name, char *msg)
315 (void)fprintf(stderr, "%s:", name);
316 if (msg != NULL)
317 (void)fprintf(stderr, "%s:", msg);
318 (void)fprintf(stderr, "%s\n", strerror(errno));
319 exit(1);