BSD 4_4 release
[unix-history] / usr / src / usr.sbin / timed / timed / readmsg.c
index f0441c5..3e8f4d2 100644 (file)
@@ -1,49 +1,73 @@
-/*
- * Copyright (c) 1983 Regents of the University of California.
- * All rights reserved.  The Berkeley software License Agreement
- * specifies the terms and conditions for redistribution.
+/*-
+ * Copyright (c) 1985, 1993
+ *     The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)readmsg.c  2.6 (Berkeley) %G%";
-#endif not lint
+static char sccsid[] = "@(#)readmsg.c  8.1 (Berkeley) 6/6/93";
+#endif /* not lint */
+
+#ifdef sgi
+#ident "$Revision: 1.17 $"
+#endif
 
 #include "globals.h"
 
 #include "globals.h"
-#include <protocols/timed.h>
 
 extern char *tsptype[];
 
 /*
  * LOOKAT checks if the message is of the requested type and comes from
 
 extern char *tsptype[];
 
 /*
  * LOOKAT checks if the message is of the requested type and comes from
- * the right machine, returning 1 in case of affirmative answer 
+ * the right machine, returning 1 in case of affirmative answer
  */
  */
-
 #define LOOKAT(msg, mtype, mfrom, netp, froms) \
 #define LOOKAT(msg, mtype, mfrom, netp, froms) \
-       (((((mtype) == TSP_ANY) || ((mtype) == (msg).tsp_type)) && \
-       (((mfrom) == NULL) || (strcmp((mfrom), (msg).tsp_name) == 0)) && \
-       (((netp) == NULL) || \
-       (((netp)->mask & (froms).sin_addr.s_addr) == (netp)->net))) \
-       ? 1 : 0)
-
-#define ISTOUTOFF(rtime, rtout) \
-       (((rtime).tv_sec > (rtout).tv_sec || \
-           ((rtime).tv_sec == (rtout).tv_sec && \
-               (rtime).tv_usec >= (rtout).tv_usec)) \
-       ? 1 : 0)
+       (((mtype) == TSP_ANY || (mtype) == (msg).tsp_type) &&           \
+        ((mfrom) == 0 || !strcmp((mfrom), (msg).tsp_name)) &&          \
+        ((netp) == 0 ||                                                \
+         ((netp)->mask & (froms).sin_addr.s_addr) == (netp)->net.s_addr))
 
 struct timeval rtime, rwait, rtout;
 struct tsp msgin;
 static struct tsplist {
        struct tsp info;
 
 struct timeval rtime, rwait, rtout;
 struct tsp msgin;
 static struct tsplist {
        struct tsp info;
+       struct timeval when;
        struct sockaddr_in addr;
        struct tsplist *p;
 } msgslist;
 struct sockaddr_in from;
 struct netinfo *fromnet;
        struct sockaddr_in addr;
        struct tsplist *p;
 } msgslist;
 struct sockaddr_in from;
 struct netinfo *fromnet;
+struct timeval from_when;
 
 /*
 
 /*
- * `readmsg' returns message `type' sent by `machfrom' if it finds it 
- * either in the receive queue, or in a linked list of previously received 
+ * `readmsg' returns message `type' sent by `machfrom' if it finds it
+ * either in the receive queue, or in a linked list of previously received
  * messages that it maintains.
  * Otherwise it waits to see if the appropriate message arrives within
  * `intvl' seconds. If not, it returns NULL.
  * messages that it maintains.
  * Otherwise it waits to see if the appropriate message arrives within
  * `intvl' seconds. If not, it returns NULL.
@@ -51,32 +75,39 @@ struct netinfo *fromnet;
 
 struct tsp *
 readmsg(type, machfrom, intvl, netfrom)
 
 struct tsp *
 readmsg(type, machfrom, intvl, netfrom)
-
-int type;
-char *machfrom;
-struct timeval *intvl;
-struct netinfo *netfrom;
+       int type;
+       char *machfrom;
+       struct timeval *intvl;
+       struct netinfo *netfrom;
 {
        int length;
        fd_set ready;
 {
        int length;
        fd_set ready;
-       struct tsp *ret = NULL;
        static struct tsplist *head = &msgslist;
        static struct tsplist *tail = &msgslist;
        static struct tsplist *head = &msgslist;
        static struct tsplist *tail = &msgslist;
-       int inet_netof();
-       int bytenetorder(), bytehostorder();
+       static int msgcnt = 0;
        struct tsplist *prev;
        register struct netinfo *ntp;
        register struct tsplist *ptr;
 
        if (trace) {
        struct tsplist *prev;
        register struct netinfo *ntp;
        register struct tsplist *ptr;
 
        if (trace) {
-               fprintf(fd, "looking for %s from %s\n",
-                       tsptype[type], machfrom);
-               ptr = head->p;
-               fprintf(fd, "msgqueue:\n");
-               while (ptr != NULL) {
-                       fprintf(fd, "\t");
-                       print(&ptr->info, &ptr->addr);
-                       ptr = ptr->p;
+               fprintf(fd, "readmsg: looking for %s from %s, %s\n",
+                       tsptype[type], machfrom == NULL ? "ANY" : machfrom,
+                       netfrom == NULL ? "ANYNET" : inet_ntoa(netfrom->net));
+               if (head->p != 0) {
+                       length = 1;
+                       for (ptr = head->p; ptr != 0; ptr = ptr->p) {
+                               /* do not repeat the hundreds of messages */
+                               if (++length > 3) {
+                                       if (ptr == tail) {
+                                               fprintf(fd,"\t ...%d skipped\n",
+                                                       length);
+                                       } else {
+                                               continue;
+                                       }
+                               }
+                               fprintf(fd, length > 1 ? "\t" : "queue:\t");
+                               print(&ptr->info, &ptr->addr);
+                       }
                }
        }
 
                }
        }
 
@@ -84,162 +115,220 @@ struct netinfo *netfrom;
        prev = head;
 
        /*
        prev = head;
 
        /*
-        * Look for the requested message scanning through the 
-        * linked list. If found, return it and free the space 
+        * Look for the requested message scanning through the
+        * linked list. If found, return it and free the space
         */
 
        while (ptr != NULL) {
                if (LOOKAT(ptr->info, type, machfrom, netfrom, ptr->addr)) {
         */
 
        while (ptr != NULL) {
                if (LOOKAT(ptr->info, type, machfrom, netfrom, ptr->addr)) {
-                       ret = (struct tsp *)malloc(sizeof(struct tsp)); 
-                       *ret = ptr->info;
+again:
+                       msgin = ptr->info;
                        from = ptr->addr;
                        from = ptr->addr;
+                       from_when = ptr->when;
                        prev->p = ptr->p;
                        prev->p = ptr->p;
-                       if (ptr == tail) 
+                       if (ptr == tail)
                                tail = prev;
                        free((char *)ptr);
                                tail = prev;
                        free((char *)ptr);
-                       break;
+                       fromnet = NULL;
+                       if (netfrom == NULL)
+                           for (ntp = nettab; ntp != NULL; ntp = ntp->next) {
+                                   if ((ntp->mask & from.sin_addr.s_addr) ==
+                                       ntp->net.s_addr) {
+                                           fromnet = ntp;
+                                           break;
+                                   }
+                           }
+                       else
+                           fromnet = netfrom;
+                       if (trace) {
+                               fprintf(fd, "readmsg: found ");
+                               print(&msgin, &from);
+                       }
+
+/* The protocol can get far behind.  When it does, it gets
+ *     hopelessly confused.  So delete duplicate messages.
+ */
+                       for (ptr = prev; (ptr = ptr->p) != NULL; prev = ptr) {
+                               if (ptr->addr.sin_addr.s_addr
+                                       == from.sin_addr.s_addr
+                                   && ptr->info.tsp_type == msgin.tsp_type) {
+                                       if (trace)
+                                               fprintf(fd, "\tdup ");
+                                       goto again;
+                               }
+                       }
+                       msgcnt--;
+                       return(&msgin);
                } else {
                        prev = ptr;
                        ptr = ptr->p;
                }
        }
 
                } else {
                        prev = ptr;
                        ptr = ptr->p;
                }
        }
 
-       if (ret != NULL)
-               goto out;
-
        /*
         * If the message was not in the linked list, it may still be
        /*
         * If the message was not in the linked list, it may still be
-        * coming from the network. Set the timer and wait 
+        * coming from the network. Set the timer and wait
         * on a select to read the next incoming message: if it is the
         * right one, return it, otherwise insert it in the linked list.
         */
 
         * on a select to read the next incoming message: if it is the
         * right one, return it, otherwise insert it in the linked list.
         */
 
-       (void)gettimeofday(&rtime, (struct timezone *)0);
-       rtout.tv_sec = rtime.tv_sec + intvl->tv_sec;
-       rtout.tv_usec = rtime.tv_usec + intvl->tv_usec;
-       if (rtout.tv_usec > 1000000) {
-               rtout.tv_usec -= 1000000;
-               rtout.tv_sec++;
-       }
-
+       (void)gettimeofday(&rtout, 0);
+       timevaladd(&rtout, intvl);
        FD_ZERO(&ready);
        for (;;) {
        FD_ZERO(&ready);
        for (;;) {
-               rwait.tv_sec = rtout.tv_sec - rtime.tv_sec;
-               rwait.tv_usec = rtout.tv_usec - rtime.tv_usec;
-               if (rwait.tv_usec < 0) {
-                       rwait.tv_usec += 1000000;
-                       rwait.tv_sec--;
-               }
-               if (rwait.tv_sec < 0) 
+               (void)gettimeofday(&rtime, 0);
+               timevalsub(&rwait, &rtout, &rtime);
+               if (rwait.tv_sec < 0)
                        rwait.tv_sec = rwait.tv_usec = 0;
                        rwait.tv_sec = rwait.tv_usec = 0;
+               else if (rwait.tv_sec == 0
+                        && rwait.tv_usec < 1000000/CLK_TCK)
+                       rwait.tv_usec = 1000000/CLK_TCK;
 
                if (trace) {
 
                if (trace) {
-                       fprintf(fd, "readmsg: wait: (%d %d)\n", 
-                                               rwait.tv_sec, rwait.tv_usec);
+                       fprintf(fd, "readmsg: wait %ld.%6ld at %s\n",
+                               rwait.tv_sec, rwait.tv_usec, date());
+                       /* Notice a full disk, as we flush trace info.
+                        * It is better to flush periodically than at
+                        * every line because the tracing consists of bursts
+                        * of many lines.  Without care, tracing slows
+                        * down the code enough to break the protocol.
+                        */
+                       if (rwait.tv_sec != 0
+                           && EOF == fflush(fd))
+                               traceoff("Tracing ended for cause at %s\n");
                }
                }
+
                FD_SET(sock, &ready);
                FD_SET(sock, &ready);
-               if (select(FD_SETSIZE, &ready, (fd_set *)0, (fd_set *)0,
-                   &rwait)) {
-                       length = sizeof(struct sockaddr_in);
-                       if (recvfrom(sock, (char *)&msgin, sizeof(struct tsp), 
-                                               0, &from, &length) < 0) {
-                               syslog(LOG_ERR, "receiving datagram packet: %m");
-                               exit(1);
+               if (!select(sock+1, &ready, (fd_set *)0, (fd_set *)0,
+                          &rwait)) {
+                       if (rwait.tv_sec == 0 && rwait.tv_usec == 0)
+                               return(0);
+                       continue;
+               }
+               length = sizeof(from);
+               if (recvfrom(sock, (char *)&msgin, sizeof(struct tsp), 0,
+                            (struct sockaddr*)&from, &length) < 0) {
+                       syslog(LOG_ERR, "recvfrom: %m");
+                       exit(1);
+               }
+               (void)gettimeofday(&from_when, (struct timezone *)0);
+               bytehostorder(&msgin);
+
+               if (msgin.tsp_vers > TSPVERSION) {
+                       if (trace) {
+                           fprintf(fd,"readmsg: version mismatch\n");
+                           /* should do a dump of the packet */
                        }
                        }
+                       continue;
+               }
 
 
-                       bytehostorder(&msgin);
+               fromnet = NULL;
+               for (ntp = nettab; ntp != NULL; ntp = ntp->next)
+                       if ((ntp->mask & from.sin_addr.s_addr) ==
+                           ntp->net.s_addr) {
+                               fromnet = ntp;
+                               break;
+                       }
 
 
+               /*
+                * drop packets from nets we are ignoring permanently
+                */
+               if (fromnet == NULL) {
                        /*
                        /*
-                        * Throw away messages coming from this machine, unless
-                        * they are of some particular type.
-                        * This gets rid of broadcast messages and reduces
-                        * master processing time.
+                        * The following messages may originate on
+                        * this host with an ignored network address
                         */
                         */
-                       if ( !(strcmp(msgin.tsp_name, hostname) != 0 ||
-                                       msgin.tsp_type == TSP_SETDATE ||
-#ifdef TESTING
-                                       msgin.tsp_type == TSP_TEST ||
-#endif
-                                       msgin.tsp_type == TSP_MSITE ||
-                                       (msgin.tsp_type == TSP_LOOP &&
-                                       msgin.tsp_hopcnt != 10) ||
-                                       msgin.tsp_type == TSP_TRACEON ||
-                                       msgin.tsp_type == TSP_TRACEOFF)) {
+                       if (msgin.tsp_type != TSP_TRACEON &&
+                           msgin.tsp_type != TSP_SETDATE &&
+                           msgin.tsp_type != TSP_MSITE &&
+                           msgin.tsp_type != TSP_TEST &&
+                           msgin.tsp_type != TSP_TRACEOFF) {
                                if (trace) {
                                if (trace) {
-                                       fprintf(fd, "readmsg: discarded: ");
-                                       print(&msgin, &from);
+                                   fprintf(fd,"readmsg: discard null net ");
+                                   print(&msgin, &from);
                                }
                                }
-                               (void)gettimeofday(&rtime,(struct timezone *)0);
-                               if (ISTOUTOFF(rtime, rtout))
-                                       break;
-                               else
-                                       continue;
+                               continue;
                        }
                        }
+               }
 
 
-                       /*
-                        * Send acknowledgements here; this is faster and avoids
-                        * deadlocks that would occur if acks were sent from a 
-                        * higher level routine.  Different acknowledgements are
-                        * necessary, depending on status.
-                        */
-                       for (ntp = nettab; ntp != NULL; ntp = ntp->next) {
-                               if ((ntp->mask & from.sin_addr.s_addr) ==
-                                   ntp->net) {
-                                       if (ntp->status == MASTER)
-                                               masterack();
-                                       else
-                                               slaveack();
-                                       break;
-                               }
+               /*
+                * Throw away messages coming from this machine,
+                * unless they are of some particular type.
+                * This gets rid of broadcast messages and reduces
+                * master processing time.
+                */
+               if (!strcmp(msgin.tsp_name, hostname)
+                   && msgin.tsp_type != TSP_SETDATE
+                   && msgin.tsp_type != TSP_TEST
+                   && msgin.tsp_type != TSP_MSITE
+                   && msgin.tsp_type != TSP_TRACEON
+                   && msgin.tsp_type != TSP_TRACEOFF
+                   && msgin.tsp_type != TSP_LOOP) {
+                       if (trace) {
+                               fprintf(fd, "readmsg: discard own ");
+                               print(&msgin, &from);
                        }
                        }
-                       if (LOOKAT(msgin, type, machfrom, netfrom, from)) {
-                               ret = &msgin;
-                               break;
-                       } else {
-                               tail->p = (struct tsplist *)
-                                               malloc(sizeof(struct tsplist)); 
-                               tail = tail->p;
-                               tail->p = NULL;
-                               tail->info = msgin;
-                               tail->addr = from;
-                       }
-
-                       (void)gettimeofday(&rtime, (struct timezone *)0);
-                       if (ISTOUTOFF(rtime, rtout))
-                               break;
-               } else {
-                       break;
-               }
-       }
-out:
-       if (ret != NULL) {
-               if (trace) {
-                       fprintf(fd, "readmsg: ");
-                       print(ret, &from);
+                       continue;
                }
                }
-               fromnet = NULL;
-               for (ntp = nettab; ntp != NULL; ntp = ntp->next) {
-                       if ((ntp->mask & from.sin_addr.s_addr) ==
-                           ntp->net) {
-                               fromnet = ntp;
-                               break;
+
+               /*
+                * Send acknowledgements here; this is faster and
+                * avoids deadlocks that would occur if acks were
+                * sent from a higher level routine.  Different
+                * acknowledgements are necessary, depending on
+                * status.
+                */
+               if (fromnet == NULL)    /* do not de-reference 0 */
+                       ignoreack();
+               else if (fromnet->status == MASTER)
+                       masterack();
+               else if (fromnet->status == SLAVE)
+                       slaveack();
+               else
+                       ignoreack();
+
+               if (LOOKAT(msgin, type, machfrom, netfrom, from)) {
+                       if (trace) {
+                               fprintf(fd, "readmsg: ");
+                               print(&msgin, &from);
+                       }
+                       return(&msgin);
+               } else if (++msgcnt > NHOSTS*3) {
+
+/* The protocol gets hopelessly confused if it gets too far
+*      behind.  However, it seems able to recover from all cases of lost
+*      packets.  Therefore, if we are swamped, throw everything away.
+*/
+                       if (trace)
+                               fprintf(fd,
+                                       "readmsg: discarding %d msgs\n",
+                                       msgcnt);
+                       msgcnt = 0;
+                       while ((ptr=head->p) != NULL) {
+                               head->p = ptr->p;
+                               free((char *)ptr);
                        }
                        }
+                       tail = head;
+               } else {
+                       tail->p = (struct tsplist *)
+                                   malloc(sizeof(struct tsplist));
+                       tail = tail->p;
+                       tail->p = NULL;
+                       tail->info = msgin;
+                       tail->addr = from;
+                       /* timestamp msgs so SETTIMEs are correct */
+                       tail->when = from_when;
                }
        }
                }
        }
-       return(ret);
 }
 
 /*
 }
 
 /*
- * `slaveack' sends the necessary acknowledgements: 
- * only the type ACK is to be sent by a slave 
+ * Send the necessary acknowledgements:
+ * only the type ACK is to be sent by a slave
  */
  */
-
+void
 slaveack()
 {
 slaveack()
 {
-       int length;
-       struct tsp resp;
-
-       length = sizeof(struct sockaddr_in);
        switch(msgin.tsp_type) {
 
        case TSP_ADJTIME:
        switch(msgin.tsp_type) {
 
        case TSP_ADJTIME:
@@ -249,38 +338,59 @@ slaveack()
        case TSP_TRACEON:
        case TSP_TRACEOFF:
        case TSP_QUIT:
        case TSP_TRACEON:
        case TSP_TRACEOFF:
        case TSP_QUIT:
-               resp = msgin;
-               resp.tsp_type = TSP_ACK;
-               resp.tsp_vers = TSPVERSION;
-               (void)strcpy(resp.tsp_name, hostname);
                if (trace) {
                        fprintf(fd, "Slaveack: ");
                if (trace) {
                        fprintf(fd, "Slaveack: ");
-                       print(&resp, &from);
-               }
-               bytenetorder(&resp);     /* this is not really necessary here */
-               if (sendto(sock, (char *)&resp, sizeof(struct tsp), 0, 
-                                               &from, length) < 0) {
-                       syslog(LOG_ERR, "sendto: %m");
-                       exit(1);
+                       print(&msgin, &from);
                }
                }
+               xmit(TSP_ACK,msgin.tsp_seq, &from);
                break;
                break;
+
        default:
        default:
+               if (trace) {
+                       fprintf(fd, "Slaveack: no ack: ");
+                       print(&msgin, &from);
+               }
                break;
        }
 }
 
 /*
                break;
        }
 }
 
 /*
- * `masterack' sends the necessary acknowledgments 
- * to the messages received by a master 
+ * Certain packets may arrive from this machine on ignored networks.
+ * These packets should be acknowledged.
  */
  */
+void
+ignoreack()
+{
+       switch(msgin.tsp_type) {
+
+       case TSP_TRACEON:
+       case TSP_TRACEOFF:
+       case TSP_QUIT:
+               if (trace) {
+                       fprintf(fd, "Ignoreack: ");
+                       print(&msgin, &from);
+               }
+               xmit(TSP_ACK,msgin.tsp_seq, &from);
+               break;
+
+       default:
+               if (trace) {
+                       fprintf(fd, "Ignoreack: no ack: ");
+                       print(&msgin, &from);
+               }
+               break;
+       }
+}
 
 
+/*
+ * `masterack' sends the necessary acknowledgments
+ * to the messages received by a master
+ */
+void
 masterack()
 {
 masterack()
 {
-       int length;
        struct tsp resp;
 
        struct tsp resp;
 
-       length = sizeof(struct sockaddr_in);
-
        resp = msgin;
        resp.tsp_vers = TSPVERSION;
        (void)strcpy(resp.tsp_name, hostname);
        resp = msgin;
        resp.tsp_vers = TSPVERSION;
        (void)strcpy(resp.tsp_name, hostname);
@@ -290,92 +400,89 @@ masterack()
        case TSP_QUIT:
        case TSP_TRACEON:
        case TSP_TRACEOFF:
        case TSP_QUIT:
        case TSP_TRACEON:
        case TSP_TRACEOFF:
-       case TSP_MSITE:
        case TSP_MSITEREQ:
        case TSP_MSITEREQ:
-               resp.tsp_type = TSP_ACK;
-               bytenetorder(&resp);
                if (trace) {
                        fprintf(fd, "Masterack: ");
                if (trace) {
                        fprintf(fd, "Masterack: ");
-                       print(&resp, &from);
-               }
-               if (sendto(sock, (char *)&resp, sizeof(struct tsp), 0, 
-                                               &from, length) < 0) {
-                       syslog(LOG_ERR, "sendto: %m");
-                       exit(1);
+                       print(&msgin, &from);
                }
                }
+               xmit(TSP_ACK,msgin.tsp_seq, &from);
                break;
                break;
+
        case TSP_RESOLVE:
        case TSP_MASTERREQ:
        case TSP_RESOLVE:
        case TSP_MASTERREQ:
-               resp.tsp_type = TSP_MASTERACK;
-               bytenetorder(&resp);
                if (trace) {
                        fprintf(fd, "Masterack: ");
                if (trace) {
                        fprintf(fd, "Masterack: ");
-                       print(&resp, &from);
-               }
-               if (sendto(sock, (char *)&resp, sizeof(struct tsp), 0, 
-                                               &from, length) < 0) {
-                       syslog(LOG_ERR, "sendto: %m");
-                       exit(1);
+                       print(&msgin, &from);
                }
                }
+               xmit(TSP_MASTERACK,msgin.tsp_seq, &from);
                break;
                break;
-       case TSP_SETDATEREQ:
-               resp.tsp_type = TSP_DATEACK;
-               bytenetorder(&resp);
+
+       default:
                if (trace) {
                if (trace) {
-                       fprintf(fd, "Masterack: ");
-                       print(&resp, &from);
-               }
-               if (sendto(sock, (char *)&resp, sizeof(struct tsp), 0, 
-                                               &from, length) < 0) {
-                       syslog(LOG_ERR, "sendto: %m");
-                       exit(1);
+                       fprintf(fd,"Masterack: no ack: ");
+                       print(&msgin, &from);
                }
                break;
                }
                break;
-       default:
-               break;
        }
 }
 
 /*
        }
 }
 
 /*
- * Print a TSP message 
+ * Print a TSP message
  */
  */
+void
 print(msg, addr)
 print(msg, addr)
-struct tsp *msg;
-struct sockaddr_in *addr;
+       struct tsp *msg;
+       struct sockaddr_in *addr;
 {
 {
+       char tm[26];
        switch (msg->tsp_type) {
 
        case TSP_LOOP:
        switch (msg->tsp_type) {
 
        case TSP_LOOP:
-               fprintf(fd, "%s %d %d (#%d) %s %s\n",
+               fprintf(fd, "%s %d %-6u #%d %-15s %s\n",
                        tsptype[msg->tsp_type],
                        msg->tsp_vers,
                        msg->tsp_seq,
                        msg->tsp_hopcnt,
                        tsptype[msg->tsp_type],
                        msg->tsp_vers,
                        msg->tsp_seq,
                        msg->tsp_hopcnt,
-                       msg->tsp_name,
-                       inet_ntoa(addr->sin_addr));
+                       inet_ntoa(addr->sin_addr),
+                       msg->tsp_name);
                break;
 
        case TSP_SETTIME:
                break;
 
        case TSP_SETTIME:
-       case TSP_ADJTIME:
        case TSP_SETDATE:
        case TSP_SETDATEREQ:
        case TSP_SETDATE:
        case TSP_SETDATEREQ:
-               fprintf(fd, "%s %d %d (%d, %d) %s %s\n",
+#ifdef sgi
+               (void)cftime(tm, "%D %T", &msg->tsp_time.tv_sec);
+#else
+               strncpy(tm, ctime(&msg->tsp_time.tv_sec)+3+1, sizeof(tm));
+               tm[15] = '\0';          /* ugh */
+#endif /* sgi */
+               fprintf(fd, "%s %d %-6u %s %-15s %s\n",
+                       tsptype[msg->tsp_type],
+                       msg->tsp_vers,
+                       msg->tsp_seq,
+                       tm,
+                       inet_ntoa(addr->sin_addr),
+                       msg->tsp_name);
+               break;
+
+       case TSP_ADJTIME:
+               fprintf(fd, "%s %d %-6u (%ld,%ld) %-15s %s\n",
                        tsptype[msg->tsp_type],
                        msg->tsp_vers,
                        msg->tsp_seq,
                        tsptype[msg->tsp_type],
                        msg->tsp_vers,
                        msg->tsp_seq,
-                       msg->tsp_time.tv_sec, 
-                       msg->tsp_time.tv_usec, 
-                       msg->tsp_name,
-                       inet_ntoa(addr->sin_addr));
+                       msg->tsp_time.tv_sec,
+                       msg->tsp_time.tv_usec,
+                       inet_ntoa(addr->sin_addr),
+                       msg->tsp_name);
                break;
 
        default:
                break;
 
        default:
-               fprintf(fd, "%s %d %d %s %s\n",
+               fprintf(fd, "%s %d %-6u %-15s %s\n",
                        tsptype[msg->tsp_type],
                        msg->tsp_vers,
                        msg->tsp_seq,
                        tsptype[msg->tsp_type],
                        msg->tsp_vers,
                        msg->tsp_seq,
-                       msg->tsp_name,
-                       inet_ntoa(addr->sin_addr));
+                       inet_ntoa(addr->sin_addr),
+                       msg->tsp_name);
                break;
        }
 }
                break;
        }
 }