Home | History | Annotate | Line # | Download | only in ipc
      1 /*	$NetBSD: ip_send.c,v 1.3 2014/01/26 21:43:45 christos Exp $	*/
      2 /*-
      3  * Copyright (c) 1996
      4  *	Keith Bostic.  All rights reserved.
      5  *
      6  * See the LICENSE file for redistribution information.
      7  */
      8 
      9 #include "config.h"
     10 
     11 #include <sys/cdefs.h>
     12 #if 0
     13 #ifndef lint
     14 static const char sccsid[] = "Id: ip_send.c,v 8.10 2001/06/25 15:19:25 skimo Exp  (Berkeley) Date: 2001/06/25 15:19:25 ";
     15 #endif /* not lint */
     16 #else
     17 __RCSID("$NetBSD: ip_send.c,v 1.3 2014/01/26 21:43:45 christos Exp $");
     18 #endif
     19 
     20 #include <sys/types.h>
     21 #include <sys/queue.h>
     22 
     23 #include <bitstring.h>
     24 #include <stdio.h>
     25 #include <stdlib.h>
     26 #include <string.h>
     27 #include <unistd.h>
     28 
     29 #include "../common/common.h"
     30 #include "ip.h"
     31 
     32 /*
     33  * vi_send --
     34  *	Construct and send an IP buffer.
     35  *
     36  * PUBLIC: int vi_send __P((int, const char *, IP_BUF *));
     37  */
     38 int
     39 vi_send(int ofd, const char *fmt, IP_BUF *ipbp)
     40 {
     41 	static char *bp;
     42 	static size_t blen;
     43 	size_t off;
     44 	u_int32_t ilen;
     45 	size_t nlen;
     46 	int n, nw;
     47 	char *p;
     48 
     49 	/*
     50 	 * Have not created the channel to vi yet?  -- RAZ
     51 	 *
     52 	 * XXX
     53 	 * How is that possible!?!?
     54 	 *
     55 	 * We'll soon find out.
     56 	 */
     57 	if (ofd == 0) {
     58 		fprintf(stderr, "No channel\n");
     59 		abort();
     60 	}
     61 
     62 	if (blen == 0 && (bp = malloc(blen = 512)) == NULL)
     63 		return (1);
     64 
     65 	p = bp;
     66 	nlen = 0;
     67 	*p++ = ipbp->code;
     68 	nlen += IPO_CODE_LEN;
     69 
     70 	if (fmt != NULL)
     71 		for (; *fmt != '\0'; ++fmt)
     72 			switch (*fmt) {
     73 			case '1':				/* Value #1. */
     74 				ilen = htonl(ipbp->val1);
     75 				goto value;
     76 			case '2':				/* Value #2. */
     77 				ilen = htonl(ipbp->val2);
     78 				goto value;
     79 			case '3':				/* Value #3. */
     80 				ilen = htonl(ipbp->val3);
     81 value:				nlen += IPO_INT_LEN;
     82 				if (nlen >= blen) {
     83 					blen = blen * 2 + nlen;
     84 					off = p - bp;
     85 					if ((bp = realloc(bp, blen)) == NULL)
     86 						return (1);
     87 					p = bp + off;
     88 				}
     89 				memcpy(p, &ilen, IPO_INT_LEN);
     90 				p += IPO_INT_LEN;
     91 				break;
     92 			case 'a':				/* String #1. */
     93 			case 'b':				/* String #2. */
     94 				ilen = *fmt == 'a' ? ipbp->len1 : ipbp->len2;
     95 				nlen += IPO_INT_LEN + ilen;
     96 				if (nlen >= blen) {
     97 					blen = blen * 2 + nlen;
     98 					off = p - bp;
     99 					if ((bp = realloc(bp, blen)) == NULL)
    100 						return (1);
    101 					p = bp + off;
    102 				}
    103 				ilen = htonl(ilen);
    104 				memcpy(p, &ilen, IPO_INT_LEN);
    105 				p += IPO_INT_LEN;
    106 				if (*fmt == 'a') {
    107 					memcpy(p, ipbp->str1, ipbp->len1);
    108 					p += ipbp->len1;
    109 				} else {
    110 					memcpy(p, ipbp->str2, ipbp->len2);
    111 					p += ipbp->len2;
    112 				}
    113 				break;
    114 			}
    115 	for (n = p - bp, p = bp; n > 0; n -= nw, p += nw)
    116 		if ((nw = write(ofd, p, n)) < 0)
    117 			return (1);
    118 	return (0);
    119 }
    120