must unlock parent directory on error; fix symlink interpretation
[unix-history] / usr / src / old / implog / implog.c
CommitLineData
19538291 1/*
b8c620d6 2 * Copyright (c) 1983, 1988 Regents of the University of California.
df2b70fd
MK
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms are permitted
b8c620d6
KB
6 * provided that the above copyright notice and this paragraph are
7 * duplicated in all such forms and that any documentation,
8 * advertising materials, and other materials related to such
9 * distribution and use acknowledge that the software was developed
10 * by the University of California, Berkeley. The name of the
11 * University may not be used to endorse or promote products derived
12 * from this software without specific prior written permission.
13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
19538291
DF
16 */
17
18#ifndef lint
19char copyright[] =
b8c620d6 20"@(#) Copyright (c) 1983, 1988 Regents of the University of California.\n\
19538291 21 All rights reserved.\n";
b8c620d6 22#endif /* not lint */
19538291 23
28b5b7e7 24#ifndef lint
132e10ac 25static char sccsid[] = "@(#)implog.c 5.11 (Berkeley) %G%";
b8c620d6 26#endif /* not lint */
bbb841ef 27
132e10ac 28#include <sys/param.h>
e2feeea9 29#include <sys/time.h>
132e10ac 30#include <sys/signal.h>
8cc7a4f3 31#include <sys/file.h>
bbb841ef
SL
32#include <sys/stat.h>
33#include <sys/socket.h>
56013160 34
ae92ba7a
MK
35#include <net/if.h>
36
56013160 37#include <netinet/in.h>
ae92ba7a 38#define IMPMESSAGES
bbb841ef 39#define IMPLEADERS
56013160 40#include <netimp/if_imp.h>
bbb841ef 41
132e10ac
KB
42#include <sgtty.h>
43#include <stdio.h>
44#include "pathnames.h"
bbb841ef
SL
45
46u_char buf[1024];
47int showdata = 1;
48int showcontents = 0;
28026947 49int rawheader = 0;
bbb841ef 50int follow = 0;
8cc7a4f3 51int skip = 0;
bbb841ef
SL
52int link = -1;
53int host = -1;
54int imp = -1;
55int packettype = -1;
56extern int errno;
57int log;
bbb841ef
SL
58
59/*
60 * Socket address, internet style, with
61 * unused space taken by timestamp and packet
62 * size.
63 */
64struct sockstamp {
65 short sin_family;
66 u_short sin_port;
67 struct in_addr sin_addr;
68 time_t sin_time;
69 int sin_cc;
70};
71struct sockstamp from;
72
73main(argc, argv)
132e10ac
KB
74 int argc;
75 char **argv;
bbb841ef 76{
132e10ac
KB
77 extern int errno, optind;
78 extern char *optarg;
bbb841ef 79 struct stat b;
132e10ac
KB
80 off_t size, lseek();
81 char *logfile, *strerror();
82 int ch;
83 long hostfrom, impfrom;
84
85 while ((ch = getopt(argc, argv, "DFLcfh:i:l:rt:")) != EOF)
86 switch(ch) {
87 case 'D':
bbb841ef 88 showdata = 0;
132e10ac
KB
89 break;
90 case 'F':
8cc7a4f3 91 skip++;
132e10ac
KB
92 /* FALLTHROUGH */
93 case 'f':
8cc7a4f3 94 follow++;
132e10ac
KB
95 break;
96 case 'L':
97 link = IMPLINK_IP;
98 break;
99 case 'c':
bbb841ef 100 showcontents++;
132e10ac
KB
101 break;
102 case 'h':
103 host = atoi(optarg);
104 break;
105 case 'i':
106 imp = atoi(optarg);
107 break;
108 case 'l':
109 link = atoi(optarg);
110 break;
111 case 'r':
28026947 112 rawheader++;
132e10ac
KB
113 break;
114 case 't':
115 packettype = atoi(optarg);
116 break;
117 case '?':
118 default:
119 fprintf(stderr,
120"usage: implog [-DFLcfr] [-h host] [-i imp] [-l link] [-t type] [logfile]\n");
121 exit(2);
bbb841ef 122 }
132e10ac
KB
123 argc -= optind;
124 argv += optind;
125
126 logfile = argc ? *argv : _PATH_IMPLOG;
127 log = open(logfile, O_RDONLY, 0);
128 if (log < 0 || fstat(log, &b)) {
129 fprintf(stderr, "implog: %s: %s\n", logfile, strerror(errno));
bbb841ef
SL
130 exit(1);
131 }
bbb841ef 132 size = b.st_size;
8cc7a4f3 133 if (skip)
132e10ac 134 (void)lseek(log, size, L_SET);
bbb841ef
SL
135again:
136 while (read(log, (char *)&from, sizeof(from)) == sizeof(from)) {
137 if (from.sin_family == 0) {
138 printf("restarted: %.24s\n", ctime(&from.sin_time));
139 continue;
140 }
607b7b53
MK
141 if (host >= 0) {
142 long addr = ntohs(from.sin_addr.s_addr);
143
144 if (IN_CLASSA(addr)) {
145 hostfrom = ((addr>>16) & 0xFF);
146 impfrom = addr & 0xFF;
147 } else if (IN_CLASSB(addr)) {
148 hostfrom = ((addr>>8) & 0xFF);
149 impfrom = addr & 0xFF;
150 } else {
151 hostfrom = ((addr>>4) & 0xF);
152 impfrom = addr & 0xF;
153 }
154 }
155 if (host >= 0 && hostfrom != host) {
132e10ac 156 (void)lseek(log, (long)from.sin_cc, L_INCR);
bbb841ef
SL
157 continue;
158 }
607b7b53 159 if (imp >= 0 && impfrom != imp) {
132e10ac 160 (void)lseek(log, (long)from.sin_cc, L_INCR);
607b7b53 161 continue;
bbb841ef
SL
162 }
163 process(log, &from);
164 }
165 while (follow) {
132e10ac
KB
166 (void)fflush(stdout);
167 (void)sleep(5);
168 (void)fstat(log, &b);
bbb841ef
SL
169 if (b.st_size > size) {
170 size = b.st_size;
171 goto again;
172 }
173 }
174}
175
176int impdata(), impbadleader(), impdown(), impnoop();
177int imprfnm(), impincomplete(), imphostdead(), imphostunreach();
178int impbaddata(), impreset(), impretry(), impnotify(), imptrying();
179int impready(), impundef();
180
181struct messages {
182 u_char m_type; /* type of message */
183 int (*m_func)(); /* routine to process message */
184} mtypes[] = {
185 { IMPTYPE_DATA, impdata },
186 { IMPTYPE_BADLEADER, impbadleader },
187 { IMPTYPE_DOWN, impdown },
188 { IMPTYPE_NOOP, impnoop },
189 { IMPTYPE_RFNM, imprfnm },
190 { IMPTYPE_INCOMPLETE, impincomplete },
191 { IMPTYPE_HOSTDEAD, imphostdead },
192 { IMPTYPE_HOSTUNREACH, imphostunreach },
193 { IMPTYPE_BADDATA, impbaddata },
194 { IMPTYPE_RESET, impreset },
195 { IMPTYPE_RETRY, impretry },
196 { IMPTYPE_NOTIFY, impnotify },
197 { IMPTYPE_TRYING, imptrying },
198 { IMPTYPE_READY, impready },
199 { -1, impundef }
200};
201
202/*
203 * Print a packet.
204 */
205process(l, f)
206 int l;
207 struct sockstamp *f;
208{
209 register struct messages *mp;
210 struct imp_leader *ip;
28026947 211 int (*fn)();
bbb841ef
SL
212
213 if (read(l, (char *)buf, f->sin_cc) != f->sin_cc) {
132e10ac 214 perror("implog: read");
bbb841ef
SL
215 return;
216 }
217 ip = (struct imp_leader *)buf;
db434d07 218 ip->il_imp = ntohs(ip->il_imp);
28026947
MK
219 if (ip->il_format != IMP_NFF)
220 fn = impundef;
221 else {
f10a0ae9 222 for (mp = mtypes; mp->m_type != (u_char)-1; mp++)
28026947
MK
223 if (mp->m_type == ip->il_mtype)
224 break;
225 fn = mp->m_func;
226 }
227 if (ip->il_mtype == IMPTYPE_DATA) {
bbb841ef
SL
228 if (link >= 0 && ip->il_link != link)
229 return;
230 if (!showdata)
231 return;
232 }
28026947 233 if (packettype >= 0 && ip->il_mtype != packettype)
bbb841ef
SL
234 return;
235 printf("%.24s: ", ctime(&f->sin_time));
db434d07
MK
236 if (f->sin_cc < sizeof(struct control_leader))
237 printf("(truncated header, %d bytes): ", f->sin_cc);
28026947 238 (*fn)(ip, f->sin_cc);
db434d07
MK
239 if (rawheader && fn != impundef) {
240 putchar('\t');
28026947 241 impundef(ip, f->sin_cc);
db434d07 242 }
bbb841ef
SL
243}
244
245impdata(ip, cc)
246 register struct imp_leader *ip;
132e10ac 247 int cc;
bbb841ef 248{
132e10ac 249 printf("<DATA, source=%d/%u, link=", ip->il_host, (u_short)ip->il_imp);
bbb841ef
SL
250 if (ip->il_link == IMPLINK_IP)
251 printf("ip,");
252 else
253 printf("%d,", ip->il_link);
132e10ac 254 printf(" len=%u bytes>\n", ntohs((u_short)ip->il_length) >> 3);
bbb841ef
SL
255 if (showcontents) {
256 register u_char *cp = ((u_char *)ip) + sizeof(*ip);
257 register int i;
258
259 i = (ntohs(ip->il_length) >> 3) - sizeof(struct imp_leader);
132e10ac 260 cc = MIN(i, cc);
bbb841ef
SL
261 printf("data: (%d bytes)", cc);
262 for (i = 0; i < cc; i++, cp++) {
263 if (i % 25 == 0)
264 printf("\n");
265 printf("%02x ", *cp);
266 }
267 putchar('\n');
268 }
269}
270
271char *badleader[] = {
272 "error flip-flop set",
273 "message < 80 bits",
274 "illegal type field",
275 "opposite leader type"
276};
277
132e10ac
KB
278/* ARGSUSED */
279impbadleader(ip, cc)
bbb841ef 280 register struct imp_leader *ip;
132e10ac 281 int cc;
bbb841ef
SL
282{
283 printf("bad leader: ");
284 if (ip->il_subtype > IMPLEADER_OPPOSITE)
285 printf("%x\n", ip->il_subtype);
286 else
287 printf("%s\n", badleader[ip->il_subtype]);
288}
289
132e10ac
KB
290/* ARGSUSED */
291impdown(ip, cc)
bbb841ef 292 register struct imp_leader *ip;
132e10ac 293 int cc;
bbb841ef
SL
294{
295 int tdown, tbackup;
296
ae92ba7a
MK
297 printf("imp going down %s", impmessage[ip->il_link & IMP_DMASK]);
298 tdown = ((ip->il_link >> IMPDOWN_WHENSHIFT) & IMPDOWN_WHENMASK) *
299 IMPDOWN_WHENUNIT;
300 if ((ip->il_link & IMP_DMASK) != IMPDOWN_GOING)
bbb841ef 301 printf(" in %d minutes", tdown);
ae92ba7a 302 tbackup = ip->il_subtype * IMPDOWN_WHENUNIT;
bbb841ef
SL
303 printf(": back up ");
304 if (tbackup)
305 printf("%d minutes\n", tbackup);
306 else
307 printf("immediately\n");
308}
309
132e10ac
KB
310/* ARGSUSED */
311impnoop(ip, cc)
bbb841ef 312 register struct imp_leader *ip;
132e10ac 313 int cc;
bbb841ef 314{
132e10ac 315 printf("noop: host %d, imp %u\n", ip->il_host, ip->il_imp);
bbb841ef
SL
316}
317
132e10ac
KB
318/* ARGSUSED */
319imprfnm(ip, cc)
bbb841ef 320 register struct imp_leader *ip;
132e10ac 321 int cc;
bbb841ef 322{
132e10ac 323 printf("rfnm: htype=%x, source=%d/%u, link=",
bbb841ef
SL
324 ip->il_htype, ip->il_host, ip->il_imp);
325 if (ip->il_link == IMPLINK_IP)
326 printf("ip,");
327 else
28026947 328 printf("%d,", ip->il_link);
bbb841ef
SL
329 printf(" subtype=%x\n", ip->il_subtype);
330}
331
332char *hostdead[] = {
56013160 333 "#0",
bbb841ef
SL
334 "ready-line negated",
335 "tardy receiving messages",
336 "ncc doesn't know host",
337 "imp software won't allow messages",
338 "host down for scheduled pm",
339 "host down for hardware work",
340 "host down for software work",
341 "host down for emergency restart",
342 "host down because of power outage",
343 "host stopped at a breakpoint",
344 "host down due to hardware failure",
345 "host not scheduled to be up",
56013160
SL
346 "#13",
347 "#14",
bbb841ef
SL
348 "host in the process of coming up"
349};
350
132e10ac
KB
351/* ARGSUSED */
352imphostdead(ip, cc)
bbb841ef 353 register struct imp_leader *ip;
132e10ac 354 int cc;
bbb841ef 355{
132e10ac 356 printf("host %u/%u dead: ", ip->il_host, ip->il_imp);
bbb841ef 357 if (ip->il_link & IMP_DMASK)
ae92ba7a 358 printf("down %s, ", impmessage[ip->il_link & IMP_DMASK]);
bbb841ef
SL
359 if (ip->il_subtype <= IMPHOST_COMINGUP)
360 printf("%s\n", hostdead[ip->il_subtype]);
361 else
362 printf("subtype=%x\n", ip->il_subtype);
363}
364
365char *hostunreach[] = {
366 "destination imp can't be reached",
367 "destination host isn't up",
368 "host doesn't support long leader",
369 "communication is prohibited"
370};
371
132e10ac
KB
372/* ARGSUSED */
373imphostunreach(ip, cc)
bbb841ef 374 register struct imp_leader *ip;
132e10ac 375 int cc;
bbb841ef 376{
132e10ac 377 printf("host %u/%u unreachable: ", ip->il_host, ip->il_imp);
bbb841ef
SL
378 if (ip->il_subtype <= IMPREACH_PROHIBITED)
379 printf("%s\n", hostunreach[ip->il_subtype]);
380 else
381 printf("subtype=%x\n", ip->il_subtype);
382}
383
132e10ac
KB
384/* ARGSUSED */
385impbaddata(ip, cc)
bbb841ef 386 register struct imp_leader *ip;
132e10ac 387 int cc;
bbb841ef 388{
132e10ac 389 printf("error in data: htype=%x, source=%u/%u, link=",
bbb841ef
SL
390 ip->il_htype, ip->il_host, ip->il_imp);
391 if (ip->il_link == IMPLINK_IP)
392 printf("ip, ");
393 else
28026947 394 printf("%d, ", ip->il_link);
bbb841ef
SL
395 printf("subtype=%x\n", ip->il_subtype);
396}
397
398char *incomplete[] = {
399 "host didn't take data fast enough",
400 "message was too long",
401 "message transmission time > 15 seconds",
402 "imp/circuit failure",
403 "no resources within 15 seconds",
404 "source imp i/o failure during receipt"
405};
406
132e10ac
KB
407/* ARGSUSED */
408impincomplete(ip, cc)
bbb841ef 409 register struct imp_leader *ip;
132e10ac 410 int cc;
bbb841ef 411{
132e10ac 412 printf("incomplete: htype=%x, source=%u/%u, link=",
bbb841ef
SL
413 ip->il_htype, ip->il_host, ip->il_imp);
414 if (ip->il_link == IMPLINK_IP)
415 printf("ip,");
416 else
28026947 417 printf("%d,", ip->il_link);
bbb841ef
SL
418 if (ip->il_subtype <= IMPCOMPLETE_IMPIO)
419 printf(" %s\n", incomplete[ip->il_subtype]);
420 else
421 printf(" subtype=%x\n", ip->il_subtype);
422}
423
132e10ac
KB
424/* ARGSUSED */
425impreset(ip, cc)
426 struct imp_leader *ip;
427 int cc;
bbb841ef
SL
428{
429 printf("reset complete\n");
430}
431
432char *retry[] = {
433 "imp buffer wasn't available",
434 "connection block unavailable"
435};
436
132e10ac
KB
437/* ARGSUSED */
438impretry(ip, cc)
bbb841ef 439 register struct imp_leader *ip;
132e10ac 440 int cc;
bbb841ef
SL
441{
442 printf("refused, try again: ");
443 if (ip->il_subtype <= IMPRETRY_BLOCK)
444 printf("%s\n", retry[ip->il_subtype]);
445 else
446 printf("subtype=%x\n", ip->il_subtype);
447}
448
449char *notify[] = {
56013160
SL
450 "#0",
451 "#1",
bbb841ef
SL
452 "connection not available",
453 "reassembly space not available at destination",
454 "message number not available",
455 "transaction block for message not available"
456};
457
132e10ac
KB
458/* ARGSUSED */
459impnotify(ip, cc)
bbb841ef 460 register struct imp_leader *ip;
132e10ac 461 int cc;
bbb841ef
SL
462{
463 printf("refused, will notify: ");
464 if (ip->il_subtype <= 5)
465 printf("%s\n", notify[ip->il_subtype]);
466 else
467 printf("subtype=%x\n", ip->il_subtype);
468}
469
132e10ac
KB
470/* ARGSUSED */
471imptrying(ip, cc)
472 struct imp_leader *ip;
473 int cc;
bbb841ef
SL
474{
475 printf("refused, still trying\n");
476}
477
132e10ac
KB
478/* ARGSUSED */
479impready(ip, cc)
480 struct imp_leader *ip;
481 int cc;
bbb841ef
SL
482{
483 printf("ready\n");
484}
485
132e10ac
KB
486/* ARGSUSED */
487impundef(ip, cc)
bbb841ef 488 register struct imp_leader *ip;
132e10ac 489 int cc;
bbb841ef
SL
490{
491 printf("<fmt=%x, net=%x, flags=%x, mtype=", ip->il_format,
492 ip->il_network, ip->il_flags);
132e10ac 493 printf("%x, htype=%x,\n\t host=%d(x%x), imp=%u(x%x), link=",
db434d07
MK
494 ip->il_mtype, ip->il_htype, ip->il_host, ip->il_host,
495 ip->il_imp, ip->il_imp);
bbb841ef
SL
496 if (ip->il_link == IMPLINK_IP)
497 printf("ip,");
498 else
db434d07
MK
499 printf("%d (x%x),", ip->il_link, ip->il_link);
500 printf(" subtype=%x", ip->il_subtype);
132e10ac
KB
501 if (cc >= sizeof(struct imp_leader) && ip->il_length)
502 printf(" len=%u bytes", ntohs((u_short)ip->il_length) >> 3);
db434d07 503 printf(">\n");
bbb841ef 504}