|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1985 Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * Redistribution and use in source and binary forms are permitted ! 6: * provided that this notice is preserved and that due credit is given ! 7: * to the University of California at Berkeley. The name of the University ! 8: * may not be used to endorse or promote products derived from this ! 9: * software without specific prior written permission. This software ! 10: * is provided ``as is'' without express or implied warranty. ! 11: */ ! 12: ! 13: #ifndef lint ! 14: static char sccsid[] = "@(#)list.c 5.10 (Berkeley) 2/17/88"; ! 15: #endif /* not lint */ ! 16: ! 17: /* ! 18: ******************************************************************************* ! 19: * ! 20: * list.c -- ! 21: * ! 22: * Routines to obtain info from name and finger servers. ! 23: * ! 24: * Adapted from 4.3BSD BIND ns_init.c and from /usr/src/ucb/finger.c ! 25: * ! 26: ******************************************************************************* ! 27: */ ! 28: ! 29: #include <sys/types.h> ! 30: #include <sys/socket.h> ! 31: #include <netinet/in.h> ! 32: #include <netdb.h> ! 33: #include <stdio.h> ! 34: #include <strings.h> ! 35: #include <ctype.h> ! 36: #include <arpa/nameser.h> ! 37: #include <resolv.h> ! 38: #include "res.h" ! 39: ! 40: /* ! 41: * Imported from res_debug.c ! 42: */ ! 43: extern char *_res_resultcodes[]; ! 44: ! 45: typedef union { ! 46: HEADER qb1; ! 47: char qb2[PACKETSZ]; ! 48: } querybuf; ! 49: ! 50: extern u_long inet_addr(); ! 51: extern HostInfo *defaultPtr; ! 52: extern HostInfo curHostInfo; ! 53: extern int curHostValid; ! 54: ! 55: /* ! 56: * During a listing to a file, hash marks are printed ! 57: * every HASH_SIZE records. ! 58: */ ! 59: ! 60: #define HASH_SIZE 50 ! 61: ! 62: ! 63: /* ! 64: ******************************************************************************* ! 65: * ! 66: * ListHosts -- ! 67: * ! 68: * Requests the name server to do a zone transfer so we ! 69: * find out what hosts it knows about. ! 70: * ! 71: * There are five types of output: ! 72: * - internet addresses (default) ! 73: * - cpu type and operating system (-h option) ! 74: * - canonical and alias names (-a option) ! 75: * - well-known service names (-s option) ! 76: * - ALL records (-d option) ! 77: * ! 78: * To see all three types of information in sorted order, ! 79: * do the following: ! 80: * ls domain.edu > file ! 81: * ls -a domain.edu >> file ! 82: * ls -h domain.edu >> file ! 83: * ls -s domain.edu >> file ! 84: * view file ! 85: * ! 86: * Results: ! 87: * SUCCESS the listing was successful. ! 88: * ERROR the server could not be contacted because ! 89: * a socket could not be obtained or an error ! 90: * occured while receiving, or the output file ! 91: * could not be opened. ! 92: * ! 93: ******************************************************************************* ! 94: */ ! 95: ! 96: int ! 97: ListHosts(string, putToFile) ! 98: char *string; ! 99: int putToFile; ! 100: { ! 101: querybuf buf; ! 102: struct sockaddr_in sin; ! 103: HEADER *headerPtr; ! 104: int queryType; ! 105: int msglen; ! 106: int amtToRead; ! 107: int numRead; ! 108: int i; ! 109: int numAnswers = 0; ! 110: int result; ! 111: int soacnt = 0; ! 112: u_short len; ! 113: char *cp, *nmp; ! 114: char name[NAME_LEN]; ! 115: char dname[2][NAME_LEN]; ! 116: char option[NAME_LEN]; ! 117: char file[NAME_LEN]; ! 118: char *namePtr; ! 119: enum { ! 120: NO_ERRORS, ! 121: ERR_READING_LEN, ! 122: ERR_READING_MSG, ! 123: ERR_PRINTING, ! 124: } error = NO_ERRORS; ! 125: ! 126: ! 127: /* ! 128: * ! 129: /* ! 130: * Parse the command line. It maybe of the form "ls domain", ! 131: * "ls -a domain" or "ls -h domain". ! 132: */ ! 133: i = sscanf(string, " ls %s %s", option, name); ! 134: if (putToFile && i == 2 && name[0] == '>') { ! 135: i--; ! 136: } ! 137: if (i == 2) { ! 138: if (strcmp("-a", option) == 0) { ! 139: queryType = T_CNAME; ! 140: } else if (strcmp("-h", option) == 0) { ! 141: queryType = T_HINFO; ! 142: } else if (strcmp("-m", option) == 0) { ! 143: queryType = T_MX; ! 144: } else if (strcmp("-s", option) == 0) { ! 145: queryType = T_WKS; ! 146: } else if (strcmp("-d", option) == 0) { ! 147: queryType = T_ANY; ! 148: } else { ! 149: queryType = T_A; ! 150: } ! 151: namePtr = name; ! 152: } else if (i == 1) { ! 153: namePtr = option; ! 154: queryType = T_A; ! 155: } else { ! 156: fprintf(stderr, "ListHosts: invalid request %s\n",string); ! 157: return(ERROR); ! 158: } ! 159: ! 160: ! 161: /* ! 162: * Create a query packet for the requested domain name. ! 163: * ! 164: */ ! 165: msglen = res_mkquery(QUERY, namePtr, C_IN, T_AXFR, ! 166: (char *)0, 0, (char *)0, ! 167: (char *) &buf, sizeof(buf)); ! 168: if (msglen < 0) { ! 169: if (_res.options & RES_DEBUG) { ! 170: fprintf(stderr, "ListHosts: Res_mkquery failed\n"); ! 171: } ! 172: return (ERROR); ! 173: } ! 174: ! 175: bzero((char *)&sin, sizeof(sin)); ! 176: sin.sin_family = AF_INET; ! 177: sin.sin_port = htons(NAMESERVER_PORT); ! 178: ! 179: /* ! 180: * Check to see if we have the address of the server or the ! 181: * address of a server who knows about this domain. ! 182: * ! 183: * For now, just use the first address in the list. ! 184: */ ! 185: ! 186: if (defaultPtr->addrList != NULL) { ! 187: sin.sin_addr = *(struct in_addr *) defaultPtr->addrList[0]; ! 188: } else { ! 189: sin.sin_addr = *(struct in_addr *)defaultPtr->servers[0]->addrList[0]; ! 190: } ! 191: ! 192: /* ! 193: * Set up a virtual circuit to the server. ! 194: */ ! 195: if ((sockFD = socket(AF_INET, SOCK_STREAM, 0)) < 0) { ! 196: perror("ListHosts"); ! 197: return(ERROR); ! 198: } ! 199: if (connect(sockFD, &sin, sizeof(sin)) < 0) { ! 200: perror("ListHosts"); ! 201: (void) close(sockFD); ! 202: sockFD = -1; ! 203: return(ERROR); ! 204: } ! 205: ! 206: /* ! 207: * Send length & message for zone transfer ! 208: */ ! 209: ! 210: len = htons(msglen); ! 211: ! 212: if (write(sockFD, (char *)&len, sizeof(len)) != sizeof(len) || ! 213: write(sockFD, (char *) &buf, msglen) != msglen) { ! 214: perror("ListHosts"); ! 215: (void) close(sockFD); ! 216: sockFD = -1; ! 217: return(ERROR); ! 218: } ! 219: ! 220: fprintf(stdout,"[%s]\n", ! 221: (defaultPtr->addrList != NULL) ? defaultPtr->name : ! 222: defaultPtr->servers[0]->name); ! 223: ! 224: if (!putToFile) { ! 225: filePtr = stdout; ! 226: } else { ! 227: filePtr = OpenFile(string, file); ! 228: if (filePtr == NULL) { ! 229: fprintf(stderr, "*** Can't open %s for writing\n", file); ! 230: (void) close(sockFD); ! 231: sockFD = -1; ! 232: return(ERROR); ! 233: } ! 234: fprintf(filePtr, "> %s\n", string); ! 235: fprintf(filePtr,"[%s]\n", ! 236: (defaultPtr->addrList != NULL) ? defaultPtr->name : ! 237: defaultPtr->servers[0]->name); ! 238: } ! 239: ! 240: fprintf(filePtr, "%-30s", "Host or domain name"); ! 241: switch(queryType) { ! 242: case T_ANY: ! 243: fprintf(filePtr, " %-30s\n", "Resource record info"); ! 244: break; ! 245: case T_A: ! 246: fprintf(filePtr, " %-30s\n", "Internet address"); ! 247: break; ! 248: case T_HINFO: ! 249: fprintf(filePtr, " %-10s %s\n", "CPU", "OS"); ! 250: break; ! 251: case T_CNAME: ! 252: fprintf(filePtr, " %-30s\n", "Alias"); ! 253: break; ! 254: case T_MX: ! 255: fprintf(filePtr, " %3s %s\n", "Metric", "Host"); ! 256: break; ! 257: case T_WKS: ! 258: fprintf(filePtr, " %-4s %s\n", "Protocol", "Services"); ! 259: } ! 260: ! 261: ! 262: while (1) { ! 263: ! 264: /* ! 265: * Read the length of the response. ! 266: */ ! 267: ! 268: cp = (char *) &buf; ! 269: amtToRead = sizeof(u_short); ! 270: while(amtToRead > 0 && (numRead = read(sockFD, cp, amtToRead)) > 0){ ! 271: cp += numRead; ! 272: amtToRead -= numRead; ! 273: } ! 274: if (numRead <= 0) { ! 275: error = ERR_READING_LEN; ! 276: break; ! 277: } ! 278: ! 279: if ((len = htons(*(u_short *)&buf)) == 0) { ! 280: break; /* nothing left to read */ ! 281: } ! 282: ! 283: /* ! 284: * Read the response. ! 285: */ ! 286: ! 287: amtToRead = len; ! 288: cp = (char *) &buf; ! 289: while(amtToRead > 0 && (numRead = read(sockFD, cp, amtToRead)) > 0){ ! 290: cp += numRead; ! 291: amtToRead -= numRead; ! 292: } ! 293: if (numRead <= 0) { ! 294: error = ERR_READING_MSG; ! 295: break; ! 296: } ! 297: ! 298: result = PrintListInfo(filePtr, (char *) &buf, cp, queryType); ! 299: if (result != SUCCESS) { ! 300: error = ERR_PRINTING; ! 301: break; ! 302: } ! 303: ! 304: numAnswers++; ! 305: if (putToFile && ((numAnswers % HASH_SIZE) == 0)) { ! 306: fprintf(stdout, "#"); ! 307: fflush(stdout); ! 308: } ! 309: cp = buf.qb2 + sizeof(HEADER); ! 310: if (ntohs(buf.qb1.qdcount) > 0) ! 311: cp += dn_skipname(cp, buf.qb2 + len) + QFIXEDSZ; ! 312: nmp = cp; ! 313: cp += dn_skipname(cp, (u_char *)&buf + len); ! 314: if ((_getshort(cp) == T_SOA)) { ! 315: dn_expand(buf.qb2, buf.qb2 + len, nmp, dname[soacnt], ! 316: sizeof(dname[0])); ! 317: if (soacnt) { ! 318: if (strcmp(dname[0], dname[1]) == 0) ! 319: break; ! 320: } else ! 321: soacnt++; ! 322: } ! 323: } ! 324: ! 325: if (putToFile) { ! 326: fprintf(stdout, "%sReceived %d record%s.\n", ! 327: (numAnswers >= HASH_SIZE) ? "\n" : "", ! 328: numAnswers, ! 329: (numAnswers > 1) ? "s" : ""); ! 330: } ! 331: ! 332: (void) close(sockFD); ! 333: sockFD = -1; ! 334: if (putToFile) { ! 335: fclose(filePtr); ! 336: filePtr = NULL; ! 337: } ! 338: ! 339: switch (error) { ! 340: case NO_ERRORS: ! 341: return (SUCCESS); ! 342: ! 343: case ERR_READING_LEN: ! 344: return(ERROR); ! 345: ! 346: case ERR_PRINTING: ! 347: fprintf(stderr,"*** Error during listing of %s: %s\n", ! 348: namePtr, DecodeError(result)); ! 349: return(result); ! 350: ! 351: case ERR_READING_MSG: ! 352: headerPtr = (HEADER *) &buf; ! 353: fprintf(stderr,"ListHosts: error receiving zone transfer:\n"); ! 354: fprintf(stderr, ! 355: " result: %s, answers = %d, authority = %d, additional = %d\n", ! 356: _res_resultcodes[headerPtr->rcode], ! 357: ntohs(headerPtr->ancount), ntohs(headerPtr->nscount), ! 358: ntohs(headerPtr->arcount)); ! 359: return(ERROR); ! 360: default: ! 361: return(ERROR); ! 362: } ! 363: } ! 364: ! 365: ! 366: /* ! 367: ******************************************************************************* ! 368: * ! 369: * PrintListInfo -- ! 370: * ! 371: * Used by the ListInfo routine to print the answer ! 372: * received from the name server. Only the desired ! 373: * information is printed. ! 374: * ! 375: * Results: ! 376: * SUCCESS the answer was printed without a problem. ! 377: * NO_INFO the answer packet did not contain an answer. ! 378: * ERROR the answer was malformed. ! 379: * Misc. errors returned in the packet header. ! 380: * ! 381: ******************************************************************************* ! 382: */ ! 383: ! 384: #define NAME_FORMAT " %-30s" ! 385: #define STRIP_DOMAIN(string) if((dot = index(string, '.')) != NULL) *dot = '\0' ! 386: ! 387: ! 388: PrintListInfo(file, msg, eom, queryType) ! 389: FILE *file; ! 390: char *msg, *eom; ! 391: int queryType; ! 392: { ! 393: register char *cp; ! 394: HEADER *headerPtr; ! 395: int type, class, dlen, nameLen; ! 396: u_long ttl; ! 397: int n; ! 398: struct in_addr inaddr; ! 399: char name[NAME_LEN]; ! 400: char name2[NAME_LEN]; ! 401: char *dot; ! 402: ! 403: /* ! 404: * Read the header fields. ! 405: */ ! 406: headerPtr = (HEADER *)msg; ! 407: cp = msg + sizeof(HEADER); ! 408: if (headerPtr->rcode != NOERROR) { ! 409: return(headerPtr->rcode); ! 410: } ! 411: ! 412: /* ! 413: * We are looking for info from answer resource records. ! 414: * If there aren't any, return with an error. We assume ! 415: * there aren't any question records. ! 416: */ ! 417: ! 418: if (ntohs(headerPtr->ancount) == 0) { ! 419: return(NO_INFO); ! 420: } else { ! 421: if (ntohs(headerPtr->qdcount) > 0) { ! 422: nameLen = dn_skipname(cp, eom); ! 423: if (nameLen < 0) ! 424: return (ERROR); ! 425: cp += nameLen + QFIXEDSZ; ! 426: } ! 427: if ((nameLen = dn_expand(msg, eom, cp, name, sizeof(name))) < 0) { ! 428: return (ERROR); ! 429: } ! 430: cp += nameLen; ! 431: type = _getshort(cp); ! 432: cp += sizeof(u_short); ! 433: class = _getshort(cp); ! 434: cp += sizeof(u_short); ! 435: ttl = _getlong(cp); ! 436: cp += sizeof(u_long); ! 437: dlen = _getshort(cp); ! 438: cp += sizeof(u_short); ! 439: if (name[0] == 0) ! 440: strcpy(name, "(root)"); ! 441: ! 442: /* ! 443: * QueryType is used to specify the type of desired information. ! 444: * T_A - internet address ! 445: * T_CNAME - aliases ! 446: * T_HINFO - cpu, OS type ! 447: * T_MX - mail routing ! 448: * T_WKS - well known service ! 449: * T_ANY - any ! 450: * ! 451: */ ! 452: switch (type) { ! 453: ! 454: case T_A: ! 455: if (queryType != T_A && queryType != T_ANY) ! 456: break; ! 457: ! 458: if ((_res.options & RES_DEBUG) == 0) ! 459: STRIP_DOMAIN(name); ! 460: fprintf(file, NAME_FORMAT, name); ! 461: if (queryType == T_ANY) ! 462: fprintf(file," %-5s", p_type(type)); ! 463: if (class == C_IN) { ! 464: bcopy(cp, (char *)&inaddr, sizeof(inaddr)); ! 465: if (dlen == 4) { ! 466: fprintf(file," %s", inet_ntoa(inaddr)); ! 467: } else if (dlen == 7) { ! 468: fprintf(file," %s", inet_ntoa(inaddr)); ! 469: fprintf(file," (%d, %d)", cp[4],(cp[5] << 8) + cp[6]); ! 470: } else ! 471: fprintf(file, " (dlen = %d?)", dlen); ! 472: if (_res.options & RES_DEBUG) ! 473: fprintf(file,"\t\t\t%lu", ttl); ! 474: fprintf(file,"\n"); ! 475: } else ! 476: goto other; ! 477: break; ! 478: ! 479: case T_CNAME: ! 480: if (queryType != T_CNAME && queryType != T_ANY) ! 481: break; ! 482: ! 483: if ((_res.options & RES_DEBUG) == 0) ! 484: STRIP_DOMAIN(name); ! 485: fprintf(file, NAME_FORMAT, name); ! 486: if (queryType == T_ANY) ! 487: fprintf(file," %-5s", p_type(type)); ! 488: if ((nameLen = dn_expand(msg, eom, cp, name2, sizeof(name2))) < 0) { ! 489: fprintf(file, " ***\n"); ! 490: return (ERROR); ! 491: } ! 492: /* ! 493: * a bug -- cnames need not be in same domain! ! 494: * STRIP_DOMAIN(name2); ! 495: */ ! 496: ! 497: fprintf(file, NAME_FORMAT, name2); ! 498: if (_res.options & RES_DEBUG) ! 499: fprintf(file,"\t%lu", ttl); ! 500: fprintf(file,"\n"); ! 501: break; ! 502: ! 503: case T_HINFO: ! 504: if (queryType != T_HINFO && queryType != T_ANY) ! 505: break; ! 506: ! 507: if ((_res.options & RES_DEBUG) == 0) ! 508: STRIP_DOMAIN(name); ! 509: fprintf(file, NAME_FORMAT, name); ! 510: if (queryType == T_ANY) ! 511: fprintf(file," %-5s", p_type(type)); ! 512: if (n = *cp++) { ! 513: (void)sprintf(name,"%.*s", n, cp); ! 514: fprintf(file," %-10s", name); ! 515: cp += n; ! 516: } else { ! 517: fprintf(file," %-10s", " "); ! 518: } ! 519: if (n = *cp++) { ! 520: fprintf(file," %.*s", n, cp); ! 521: cp += n; ! 522: } ! 523: if (_res.options & RES_DEBUG) ! 524: fprintf(file,"\t\t%lu", ttl); ! 525: fprintf(file,"\n"); ! 526: break; ! 527: ! 528: case T_MX: ! 529: if (queryType != T_MX && queryType != T_ANY) ! 530: break; ! 531: ! 532: if ((_res.options & RES_DEBUG) == 0) ! 533: STRIP_DOMAIN(name); ! 534: fprintf(file, NAME_FORMAT, name); ! 535: if (queryType == T_ANY) ! 536: fprintf(file," %-5s", p_type(type)); ! 537: ! 538: { ! 539: short pref; ! 540: ! 541: pref = _getshort(cp); ! 542: cp += sizeof(u_short); ! 543: fprintf(file," %-3d ",pref); ! 544: } ! 545: if ((nameLen = dn_expand(msg, eom, cp, name2, sizeof(name2))) < 0) { ! 546: fprintf(file, " ***\n"); ! 547: return (ERROR); ! 548: } ! 549: fprintf(file, " %s", name2); ! 550: if (_res.options & RES_DEBUG) ! 551: fprintf(file,"\t%lu", ttl); ! 552: fprintf(file,"\n"); ! 553: ! 554: break; ! 555: ! 556: ! 557: case T_NS: ! 558: case T_PTR: ! 559: if (queryType != T_A && queryType != T_ANY) ! 560: break; ! 561: /* ! 562: * Found a name server or pointer record. ! 563: */ ! 564: if ((_res.options & RES_DEBUG) == 0) ! 565: STRIP_DOMAIN(name); ! 566: fprintf(file, NAME_FORMAT, name); ! 567: if (queryType == T_ANY) ! 568: fprintf(file," %-5s", p_type(type)); ! 569: fprintf(file," %s = ", type == T_PTR ? "host" : "server"); ! 570: cp = Print_cdname2(cp, msg, eom, file); ! 571: if (_res.options & RES_DEBUG) ! 572: fprintf(file,"\t%lu", ttl); ! 573: fprintf(file,"\n"); ! 574: break; ! 575: ! 576: case T_WKS: ! 577: if (queryType != T_WKS && queryType != T_ANY) ! 578: break; ! 579: ! 580: if ((_res.options & RES_DEBUG) == 0) ! 581: STRIP_DOMAIN(name); ! 582: fprintf(file, NAME_FORMAT, name); ! 583: if (queryType == T_ANY) ! 584: fprintf(file," %-5s", p_type(type)); ! 585: if (class == C_IN) { ! 586: cp += 4; dlen -= 4; ! 587: { ! 588: struct protoent *pp; ! 589: struct servent *ss; ! 590: u_short port; ! 591: ! 592: setprotoent(1); ! 593: setservent(1); ! 594: n = *cp & 0377; ! 595: pp = getprotobynumber(n); ! 596: if(pp == 0) ! 597: fprintf(file," %-3d ", n); ! 598: else ! 599: fprintf(file," %-3s ", pp->p_name); ! 600: cp++; dlen--; ! 601: ! 602: port = 0; ! 603: while(dlen-- > 0) { ! 604: n = *cp++; ! 605: do { ! 606: if(n & 0200) { ! 607: ss = getservbyport((int)htons(port), pp->p_name); ! 608: if(ss == 0) ! 609: fprintf(file," %d", port); ! 610: else ! 611: fprintf(file," %s", ss->s_name); ! 612: } ! 613: n <<= 1; ! 614: } while(++port & 07); ! 615: } ! 616: } ! 617: } else ! 618: goto other; ! 619: if (_res.options & RES_DEBUG) ! 620: fprintf(file,"\t%lu", ttl); ! 621: fprintf(file,"\n"); ! 622: endprotoent(); ! 623: endservent(); ! 624: break; ! 625: ! 626: case T_SOA: ! 627: case T_AXFR: ! 628: if (queryType != T_ANY) ! 629: break; ! 630: fprintf(file, NAME_FORMAT, name); ! 631: if (queryType == T_ANY) ! 632: fprintf(file," %-5s", p_type(type)); ! 633: if ((nameLen = dn_expand(msg, eom, cp, name2, sizeof(name2))) < 0) { ! 634: fprintf(file, " ***\n"); ! 635: return (ERROR); ! 636: } ! 637: cp += nameLen; ! 638: fprintf(file, " %s", name2); ! 639: if ((nameLen = dn_expand(msg, eom, cp, name2, sizeof(name2))) < 0) { ! 640: fprintf(file, " ***\n"); ! 641: return (ERROR); ! 642: } ! 643: cp += nameLen; ! 644: fprintf(file, " %s. (", name2); ! 645: for (n = 0; n < 5; n++) { ! 646: u_long u; ! 647: ! 648: u = _getlong(cp); ! 649: cp += sizeof(u_long); ! 650: fprintf(file,"%s%d", n? " " : "", u); ! 651: } ! 652: fprintf(file, ")", name2); ! 653: if (_res.options & RES_DEBUG) ! 654: fprintf(file,"\t%lu", ttl); ! 655: fprintf(file,"\n"); ! 656: break; ! 657: ! 658: default: ! 659: /* ! 660: * Unwanted answer type -- ignore it. ! 661: */ ! 662: if (queryType != T_ANY) ! 663: break; ! 664: if ((_res.options & RES_DEBUG) == 0) ! 665: STRIP_DOMAIN(name); ! 666: fprintf(file, NAME_FORMAT, name); ! 667: other: ! 668: fprintf(file," type = %-5s", p_type(type)); ! 669: fprintf(file,", class = %-5s", p_class(class)); ! 670: if (_res.options & RES_DEBUG) ! 671: fprintf(file,"\t%lu\n", ttl); ! 672: break; ! 673: } ! 674: } ! 675: return(SUCCESS); ! 676: } ! 677: ! 678: ! 679: /* ! 680: ******************************************************************************* ! 681: * ! 682: * ViewList -- ! 683: * ! 684: * A hack to view the output of the ls command in sorted ! 685: * order using more. ! 686: * ! 687: ******************************************************************************* ! 688: */ ! 689: ! 690: ViewList(string) ! 691: char *string; ! 692: { ! 693: char file[NAME_LEN]; ! 694: char command[NAME_LEN]; ! 695: ! 696: sscanf(string, " view %s", file); ! 697: (void)sprintf(command, "grep \"^ \" %s | sort | more", file); ! 698: system(command); ! 699: } ! 700: ! 701: /* ! 702: ******************************************************************************* ! 703: * ! 704: * Finger -- ! 705: * ! 706: * Connects with the finger server for the current host ! 707: * to request info on the specified person (long form) ! 708: * who is on the system (short form). ! 709: * ! 710: * Results: ! 711: * SUCCESS the finger server was contacted. ! 712: * ERROR the server could not be contacted because ! 713: * a socket could not be obtained or connected ! 714: * to or the service could not be found. ! 715: * ! 716: ******************************************************************************* ! 717: */ ! 718: ! 719: Finger(string, putToFile) ! 720: char *string; ! 721: int putToFile; ! 722: { ! 723: struct servent *sp; ! 724: struct sockaddr_in sin; ! 725: register FILE *f; ! 726: register int c; ! 727: register int lastc; ! 728: char name[NAME_LEN]; ! 729: char file[NAME_LEN]; ! 730: ! 731: /* ! 732: * We need a valid current host info to get an inet address. ! 733: */ ! 734: if (!curHostValid) { ! 735: fprintf(stderr, "Finger: no current host defined.\n"); ! 736: return (ERROR); ! 737: } ! 738: ! 739: if (sscanf(string, " finger %s", name) == 1) { ! 740: if (putToFile && (name[0] == '>')) { ! 741: name[0] = '\0'; ! 742: } ! 743: } else { ! 744: name[0] = '\0'; ! 745: } ! 746: ! 747: sp = getservbyname("finger", "tcp"); ! 748: if (sp == 0) { ! 749: fprintf(stderr, "Finger: unknown service\n"); ! 750: return (ERROR); ! 751: } ! 752: ! 753: bzero((char *)&sin, sizeof(sin)); ! 754: sin.sin_family = curHostInfo.addrType; ! 755: sin.sin_port = sp->s_port; ! 756: bcopy(curHostInfo.addrList[0], (char *)&sin.sin_addr, ! 757: curHostInfo.addrLen); ! 758: ! 759: /* ! 760: * Set up a virtual circuit to the host. ! 761: */ ! 762: ! 763: sockFD = socket(curHostInfo.addrType, SOCK_STREAM, 0); ! 764: if (sockFD < 0) { ! 765: fflush(stdout); ! 766: perror("Finger"); ! 767: return (ERROR); ! 768: } ! 769: ! 770: if (connect(sockFD, (char *)&sin, sizeof (sin)) < 0) { ! 771: fflush(stdout); ! 772: perror("Finger"); ! 773: close(sockFD); ! 774: sockFD = -1; ! 775: return (ERROR); ! 776: } ! 777: ! 778: if (!putToFile) { ! 779: filePtr = stdout; ! 780: } else { ! 781: filePtr = OpenFile(string, file); ! 782: if (filePtr == NULL) { ! 783: fprintf(stderr, "*** Can't open %s for writing\n", file); ! 784: close(sockFD); ! 785: sockFD = -1; ! 786: return(ERROR); ! 787: } ! 788: fprintf(filePtr,"> %s\n", string); ! 789: } ! 790: fprintf(filePtr, "[%s]\n", curHostInfo.name); ! 791: ! 792: if (name[0] != '\0') { ! 793: write(sockFD, "/W ", 3); ! 794: } ! 795: write(sockFD, name, strlen(name)); ! 796: write(sockFD, "\r\n", 2); ! 797: f = fdopen(sockFD, "r"); ! 798: while ((c = getc(f)) != EOF) { ! 799: switch(c) { ! 800: case 0210: ! 801: case 0211: ! 802: case 0212: ! 803: case 0214: ! 804: c -= 0200; ! 805: break; ! 806: case 0215: ! 807: c = '\n'; ! 808: break; ! 809: } ! 810: putc(lastc = c, filePtr); ! 811: } ! 812: if (lastc != '\n') { ! 813: putc('\n', filePtr); ! 814: } ! 815: putc('\n', filePtr); ! 816: ! 817: close(sockFD); ! 818: sockFD = -1; ! 819: ! 820: if (putToFile) { ! 821: fclose(filePtr); ! 822: filePtr = NULL; ! 823: } ! 824: return (SUCCESS); ! 825: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.