2 * FILE: $Header: /home/egg/src/RCS/genlib.c,v 1.6 1999/02/28 20:05:18 ghn Exp $
3 * PURPOSE: General library
9 * Revision 1.6 1999/02/28 20:05:18 ghn
10 * Version 5.1: Changed dquad2sockaddr interface to support ip/mm mask,
11 * created hl2dquad to translate host-long to dotted quad, and modified
12 * sockaddr2dquad to use this.
14 * Revision 1.5 1998/12/31 22:07:56 ghn
15 * Rev 5 code: includes multi-reg support, HTML, etc.
17 * Revision 1.4 1998/08/03 20:43:35 kelvin
18 * File byte-order independence.
20 * Revision 1.3 1998/08/01 18:51:25 ghn
21 * Added John's byte-order-independence changes.
23 * Revision 1.2 1998/08/01 17:07:29 ghn
24 * Casting fixes from John plus better parsing.
26 * Revision 1.1 1998/07/21 11:38:15 ghn
29 * Copyright 1998 - Greg Nelson
35 #include <sys/types.h>
36 #include <sys/socket.h>
37 #include <sys/utsname.h>
41 int32 getzulutime(struct timeval *ztv) {
45 gettimeofday(ztv, NULL);
48 gettimeofday(&ttv, NULL);
53 /* Get time difference (tv1-tv2) in msec. Only works if less than 24
55 int32 deltams(struct timeval *tv1, struct timeval *tv2) {
56 return (tv1->tv_sec - tv2->tv_sec) * 1000L +
57 (tv1->tv_usec - tv2->tv_usec) / 1000L;
60 /* Look up an EGG id. If we can't get it from environment, do a nutty
61 thing using CRC of uname block, which should be pretty unique. */
64 struct utsname utsname;
66 if ((idstr = getenv("EGGID")) != NULL) {
70 return BlockCRC16((byte *)(&utsname), sizeof(struct utsname));
74 char *Packetize(EggCarton *src) {
80 pktsize = (7 * sizeof(uint16)) + sizeof(trial) + /* Header */
81 sizeof(char) + /* ...including pad byte for trialsz */
82 (src->hdr.numrec * (sizeof(uint32) + /* Trial data */
83 src->hdr.samp_rec * sizeof(trial))) +
84 sizeof(uint32); /* CRC and terminator */
85 rbuf = pktP = (char *) malloc(pktsize);
87 /* Assemble header fields into data packet. */
89 packShort(src->hdr.type = DATA_PACKET);
90 packShort(src->hdr.pktsize = pktsize);
91 packShort(src->hdr.eggid);
92 packShort(src->hdr.samp_rec);
93 packShort(src->hdr.sec_rec);
94 packShort(src->hdr.rec_pkt);
95 packByte(0); /* Pad byte in case we want to expand trialsz */
96 packByte(src->hdr.trialsz);
97 packShort(src->hdr.numrec);
99 /* Append data records to packet. */
101 for (rec = 0; rec < src->hdr.numrec; rec++) {
102 packLong(src->records[rec].timestamp);
103 packBytes(&(src->records[rec].trials), src->hdr.samp_rec);
105 /* Get CRC, pack into base(32,32,64) notation, and add tag byte (0xFF) */
106 lbuf = BlockCRC16((byte *) rbuf, pktP - rbuf);
107 lbuf = ((lbuf & 0xF800) << 13) |
108 ((lbuf & 0x07C0) << 10) |
109 ((lbuf & 0x003F) << 8) |
112 if ((pktP - rbuf) != pktsize) {
113 fprintf(stderr, "Length mismatch assembling packet. Computed: %d, actually packed: %d.\n",
114 pktsize, pktP - rbuf);
119 int32 Unpacketize(EggCarton *dst, char *src) {
123 uint32 lbuf, filecrc;
125 /* Unpack the portable header into a host-order and aligned
128 unpackShort(dst->hdr.type);
129 unpackShort(dst->hdr.pktsize);
130 unpackShort(dst->hdr.eggid);
131 unpackShort(dst->hdr.samp_rec);
132 unpackShort(dst->hdr.sec_rec);
133 unpackShort(dst->hdr.rec_pkt);
134 unpackByte(pad); /* Pad in case we later grow trialsz */
135 unpackByte(dst->hdr.trialsz);
136 unpackShort(dst->hdr.numrec);
138 if (dst->hdr.type != DATA_PACKET) {
140 fprintf(stderr, "Invalid header type 0x%04X in packet read from file.\n", dst->hdr.type);
145 /* Unpack the data records from the file packet. */
147 for (rec = 0; rec < dst->hdr.numrec; rec++) {
148 unpackLong(dst->records[rec].timestamp);
149 /* Assumes sizeof(trial) = 1 */
150 unpackBytes(&(dst->records[rec].trials), dst->hdr.samp_rec);
153 /* Compute the CRC, reassemble into record terminator,
154 and compare with terminator in file. */
156 lbuf = BlockCRC16((byte *) src, pktP - src);
157 lbuf = ((lbuf & 0xF800) << 13) |
158 ((lbuf & 0x07C0) << 10) |
159 ((lbuf & 0x003F) << 8) |
164 if (lbuf != filecrc) {
166 fprintf(stderr, "Bad CRC in packet read from file. Read 0x%08lX, computed 0x%08lX.\n", filecrc, lbuf);
171 if (dst->hdr.pktsize != (pktP - src)) {
173 fprintf(stderr, "Length mismatch decoding packet. Header: %d, length decoded: %d.\n",
174 dst->hdr.pktsize, pktP - src);
179 /* One final little tweak. Since we included a pad byte to allow
180 for growth in trialsz, hdr.pktsize will include it. Subtract
181 one to hide the existence of the pad in the file from the
182 caller. In all probability the caller isn't going to look at
183 pktsize, but you can't be too careful. */
190 void Parse(char *input, int *argc, char *argv[]) {
195 tp = strtok(input, " \t\n");
196 while (tp != NULL && *argc < MAX_PARSE) {
199 tp = strtok(NULL, " \t\n");
203 char *mallocpy(char *input) {
206 res = (char *)malloc(1+strlen(input));
207 if (res) strcpy(res, input);
211 void dquad2sockaddr(struct sockaddr_in *sinp, int16 *mask, char *dquad) {
216 loser = mallocpy(dquad);
218 tp = strtok(loser, ".");
219 for (qcount = 0, saddr = 0; qcount < 4 && tp != NULL; qcount++) {
220 saddr = (saddr << 8) | (atoi(tp) & 0xFF);
221 tp = strtok(NULL, ".");
225 strcpy(loser, dquad);
226 tp = strtok(loser, "/");
228 tp = strtok(NULL, "/");
229 if (tp) *mask = atoi(tp);
234 sinp->sin_family = AF_INET;
235 sinp->sin_port = 0; /* To be filled in later */
236 sinp->sin_addr.s_addr = htonl(saddr);
239 char *sockaddr2dquad(struct sockaddr_in *sinp) {
242 saddr = ntohl(sinp->sin_addr.s_addr);
243 return hl2dquad(saddr);
246 char *hl2dquad(long addr) {
247 static char resout[16];
249 sprintf(resout, "%ld.%ld.%ld.%ld",
250 (addr >> 24) & 0xFF, (addr >> 16) & 0xFF,
251 (addr >> 8) & 0xFF, addr & 0xFF);