[24319] | 1 | /* $Id: sendrecv.c 3956 2010-01-05 20:56:56Z zacheiss $ |
---|
[23095] | 2 | * |
---|
| 3 | * socket layer for update_server |
---|
| 4 | * |
---|
| 5 | * Copyright (C) 1997-1998 by the Massachusetts Institute of Technology |
---|
| 6 | * For copying and distribution information, please see the file |
---|
| 7 | * <mit-copyright.h>. |
---|
| 8 | */ |
---|
| 9 | |
---|
| 10 | #include <mit-copyright.h> |
---|
| 11 | #include <moira.h> |
---|
| 12 | |
---|
| 13 | #include <sys/types.h> |
---|
| 14 | #include <sys/uio.h> |
---|
| 15 | |
---|
| 16 | #include <errno.h> |
---|
| 17 | #include <stdlib.h> |
---|
| 18 | #include <unistd.h> |
---|
| 19 | |
---|
[24319] | 20 | RCSID("$HeadURL: svn+ssh://svn.mit.edu/moira/trunk/moira/update/sendrecv.c $ $Id: sendrecv.c 3956 2010-01-05 20:56:56Z zacheiss $"); |
---|
[23095] | 21 | |
---|
| 22 | #define putlong(cp, l) { ((unsigned char *)cp)[0] = l >> 24; ((unsigned char *)cp)[1] = l >> 16; ((unsigned char *)cp)[2] = l >> 8; ((unsigned char *)cp)[3] = l; } |
---|
| 23 | #define getlong(cp, l) l = ((((unsigned char *)cp)[0] * 256 + ((unsigned char *)cp)[1]) * 256 + ((unsigned char *)cp)[2]) * 256 + ((unsigned char *)cp)[3] |
---|
| 24 | |
---|
| 25 | extern void fail(int conn, int err, char *msg); |
---|
| 26 | |
---|
| 27 | int send_int(int conn, long data) |
---|
| 28 | { |
---|
| 29 | char buf[8]; |
---|
| 30 | |
---|
| 31 | putlong(buf, 4); |
---|
| 32 | putlong((buf + 4), data); |
---|
| 33 | if (write(conn, buf, 8) == 8) |
---|
| 34 | return 0; |
---|
| 35 | else |
---|
| 36 | { |
---|
| 37 | fail(conn, errno, "sending integer"); |
---|
| 38 | return errno; |
---|
| 39 | } |
---|
| 40 | } |
---|
| 41 | |
---|
| 42 | int recv_int(int conn, long *data) |
---|
| 43 | { |
---|
| 44 | char buf[8]; |
---|
| 45 | int len; |
---|
| 46 | |
---|
| 47 | len = read(conn, buf, 8); |
---|
| 48 | if (len == -1) |
---|
| 49 | { |
---|
| 50 | fail(conn, errno, "reading integer"); |
---|
| 51 | return errno; |
---|
| 52 | } |
---|
| 53 | else if (len < 8) |
---|
| 54 | { |
---|
| 55 | fail(conn, 0, "remote connection closed while reading integer"); |
---|
| 56 | return EIO; |
---|
| 57 | } |
---|
| 58 | getlong((buf + 4), *data); |
---|
| 59 | return 0; |
---|
| 60 | } |
---|
| 61 | |
---|
| 62 | |
---|
| 63 | int send_string(int conn, char *buf, size_t len) |
---|
| 64 | { |
---|
| 65 | char fulllen[4], stringlen[4]; |
---|
| 66 | struct iovec iov[3]; |
---|
| 67 | |
---|
| 68 | putlong(fulllen, (len + 4)); |
---|
| 69 | putlong(stringlen, len); |
---|
| 70 | iov[0].iov_base = fulllen; |
---|
| 71 | iov[0].iov_len = 4; |
---|
| 72 | iov[1].iov_base = stringlen; |
---|
| 73 | iov[1].iov_len = 4; |
---|
| 74 | iov[2].iov_base = buf; |
---|
| 75 | iov[2].iov_len = len; |
---|
| 76 | |
---|
| 77 | if (writev(conn, iov, 3) == -1) |
---|
| 78 | { |
---|
| 79 | fail(conn, errno, "sending string"); |
---|
| 80 | return errno; |
---|
| 81 | } |
---|
| 82 | else |
---|
| 83 | return 0; |
---|
| 84 | } |
---|
| 85 | |
---|
| 86 | int recv_string(int conn, char **buf, size_t *len) |
---|
| 87 | { |
---|
| 88 | char tmp[4]; |
---|
| 89 | int size, more; |
---|
| 90 | |
---|
| 91 | size = read(conn, tmp, 4); |
---|
| 92 | if (size == -1) |
---|
| 93 | { |
---|
| 94 | fail(conn, errno, "reading string"); |
---|
| 95 | return errno; |
---|
| 96 | } |
---|
| 97 | else if (size < 4) |
---|
| 98 | { |
---|
| 99 | fail(conn, 0, "remote connection closed while reading string"); |
---|
| 100 | return EIO; |
---|
| 101 | } |
---|
| 102 | |
---|
| 103 | size = read(conn, tmp, 4); |
---|
| 104 | if (size == -1) |
---|
| 105 | { |
---|
| 106 | fail(conn, errno, "reading string"); |
---|
| 107 | return errno; |
---|
| 108 | } |
---|
| 109 | else if (size < 4) |
---|
| 110 | { |
---|
| 111 | fail(conn, 0, "remote connection closed while reading string"); |
---|
| 112 | return EIO; |
---|
| 113 | } |
---|
| 114 | getlong(tmp, *len); |
---|
| 115 | |
---|
| 116 | *buf = malloc(*len); |
---|
| 117 | if (!*buf) |
---|
| 118 | { |
---|
| 119 | fail(conn, ENOMEM, "reading string"); |
---|
| 120 | return ENOMEM; |
---|
| 121 | } |
---|
| 122 | for (size = 0; size < *len; size += more) |
---|
| 123 | { |
---|
| 124 | more = read(conn, *buf + size, *len - size); |
---|
| 125 | if (!more) |
---|
| 126 | break; |
---|
| 127 | } |
---|
| 128 | |
---|
| 129 | if (size != *len) |
---|
| 130 | { |
---|
| 131 | free(buf); |
---|
| 132 | fail(conn, errno, "reading string"); |
---|
| 133 | return errno; |
---|
| 134 | } |
---|
| 135 | |
---|
| 136 | return 0; |
---|
| 137 | } |
---|