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