1 /* $NetBSD: ip_main.c,v 1.2 2013/11/22 15:52:05 christos Exp $ */
4 * Keith Bostic. All rights reserved.
6 * See the LICENSE file for redistribution information.
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 ";
15 #include <sys/types.h>
16 #include <sys/queue.h>
18 #include <bitstring.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
));
43 * This is the main loop for the vi-as-library editor.
46 main(int argc
, char **argv
)
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.
64 for (p_av
= t_av
= argv
;;) {
69 if (!strcmp(*t_av
, "--")) {
70 while ((*p_av
++ = *t_av
++) != NULL
);
73 if (!memcmp(*t_av
, "-I", sizeof("-I") - 1)) {
74 if (t_av
[0][2] != '\0') {
80 else if (t_av
[1] != NULL
) {
90 if (get_fds(ip_arg
, &main_ifd
, &main_ofd
))
95 while (get_connection(wp
, main_ifd
, main_ofd
, &i_fd
, &o_fd
, &t_fd
, 1) == 0) {
96 /* Create new window */
99 /* Create and partially initialize the IP structure. */
100 if ((ipp
= ip_init(wp
, i_fd
, o_fd
, t_fd
, argc
, argv
)) == NULL
)
103 gp
->run(wp
, run_editor
, (void *)wp
);
106 /* Clean out the global structure. */
109 /* Free the global and IP private areas. */
110 #if defined(DEBUG) || defined(PURIFY) || defined(LIBRARY)
117 run_editor(void * vp
)
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.
140 if (ip_wevent(wp
, NULL
, &ev
, 0, 0))
142 if (ev
.e_event
== E_WRESIZE
)
144 if (ev
.e_event
== E_EOF
|| ev
.e_event
== E_ERR
||
145 ev
.e_event
== E_SIGHUP
|| ev
.e_event
== E_SIGTERM
)
147 if (ev
.e_event
== E_IPCOMMAND
&& ev
.e_ipcom
== VI_QUIT
)
152 rval
= editor(wp
, ipp
->argc
, ipp
->argv
);
154 /* Clean up the screen. */
157 /* Send the quit message. */
159 (void)vi_send(ipp
->o_fd
, NULL
, &ipb
);
161 /* Give the screen a couple of seconds to deal with it. */
164 /* Remove window; correct place ? */
167 #if defined(DEBUG) || defined(PURIFY) || defined(LIBRARY)
175 * Create and partially initialize the GS structure.
178 ip_init(WIN
*wp
, int i_fd
, int o_fd
, int t_fd
, int argc
, char *argv
[])
182 /* Allocate the IP private structure. */
183 CALLOC_NOMSG(NULL
, ipp
, IP_PRIVATE
*, 1, sizeof(IP_PRIVATE
));
185 perr(wp
->gp
->progname
, NULL
);
186 wp
->ip_private
= ipp
;
195 /* Initialize the list of ip functions. */
202 get_fds(char *ip_arg
, int *i_fd
, int *o_fd
)
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
211 if (!ip_arg
|| !isdigit((unsigned char)ip_arg
[0]))
213 *i_fd
= strtol(ip_arg
, &ep
, 10);
214 if (ep
[0] != '.' || !isdigit((unsigned char)ep
[1]))
216 *o_fd
= strtol(++ep
, &ep
, 10);
226 get_connection(WIN
*wp
, int main_ifd
, int main_ofd
,
227 int *i_fd
, int *o_fd
, int *t_fd
, int can_pass
)
232 if (wp
== NULL
) { /* First call */
247 mh
.msg_controllen
= sizeof(ch
);
248 mh
.msg_control
= (void *)&ch
;
251 iov
.iov_base
= &dummy
;
253 if (recvmsg(main_ifd
, &mh
, 0) != 1)
255 *i_fd
= *(int *)CMSG_DATA(&ch
.header
);
256 if (recvmsg(*i_fd
, &mh
, 0) != 1)
258 *o_fd
= *(int *)CMSG_DATA(&ch
.header
);
260 if (recvmsg(*i_fd
, &mh
, 0) != 1)
262 *t_fd
= *(int *)CMSG_DATA(&ch
.header
);
271 * Initialize the standard ip functions.
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
;
310 * Print system error.
313 perr(char *name
, char *msg
)
315 (void)fprintf(stderr
, "%s:", name
);
317 (void)fprintf(stderr
, "%s:", msg
);
318 (void)fprintf(stderr
, "%s\n", strerror(errno
));