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