/*---------------------------------------------------------------------+ | Copyright (c) 1995, SAS Institute Inc. | | Unpublished - All Rights Reserved | | S A S / C S A M P L E | | | | NAME: FINGER | | LANGUAGE: C | | PURPOSE: This is a sample FINGER client. The client queries the | | finger server on the remote host. The finger server | | returns information about currently logged on users. | | This is a complete sample using: gethostbyname(), | | getservbyname(), socket(), connect(), write(), and | | close(). The syntax of the command is: | | finger [-l] host_name | | NOTES: -l is optional, and produces additional output. | | MVS - | | COMPILE, LINK, EXECUTE: SUBMIT prefix.SAMPLE.AUX(LC370CLG) | | NOTES: "prefix" is the SAS/C installation defined high-level | | qualifier. | | NOTES: on the EXEC statement add a: ,PARM.GO='host_name' | | Where "host_name" is the host running a "fingerd". | | TSO - | | COMPILE: LC370 CLIST | | LINK: CLK370 CLIST | | EXECUTE: CALL 'your.load.lib(FINGER)' 'host_name' asis | | Where "host_name" is the host running a "fingerd". | | CMS - | | COMPILE: LC370 | | LINK: CLINK FINGER (GENMOD | | EXECUTE: FINGER host_name | | Where "host_name" is the host running a "fingerd". | +---------------------------------------------------------------------*/ #include #include #include #include #include #include #include #include #include /* No need to translate characters on ASCII systems. */ #ifndef __SASC__ #define ntohcs(c) (c) #define htoncs(c) (c) #endif /* Define some useful constants. */ #define FALSE 0 #define TRUE 1 #define READ_BLOCK_SIZE 256 #define OUTBUF_SIZE 2 #define FINGER_PORT 79 #define ASCII_CR 0x0D #define ASCII_LF 0x0A main(int argc, char *argv[]) { int n,i; /* Socket descriptor for communication with the */ /* finger server. */ int s; /* Socket address for server. */ struct sockaddr_in sa; /* Use to send ASCII CR and LF characters required by */ /* the protocol. */ char cr = ASCII_CR, lf = ASCII_LF; /* Buffers. */ char in[READ_BLOCK_SIZE]; char out[OUTBUF_SIZE]; /* Option status. */ int longlist = FALSE; char *op; /* Will contain information about the finger service. */ struct servent *serv; /* Will contain information about the remote host. */ struct hostent *host; /* Argument processing. */ if (*++argv && *argv[0] == '-') { op = *argv; if (op[1]=='l') longlist = 1; else printf("finger: unsupported option \"%c\"",op[1]); argv++; } if (!*argv) { printf("finger: hostname missing"); exit(EXIT_FAILURE); } /* Assume *argv now points to hostname. */ /* Find the IP address for the requested host. */ host = gethostbyname(*argv); if (host==NULL) { printf("finger: Host %s is unknown.\n",*argv); exit(EXIT_FAILURE); } /* Find the port for the finger service. If the */ /* services file is not available, we will use the */ /* standard number. We specify "tcp" as the protocol.*/ /* This call will attempt to find the services file. */ serv = getservbyname("finger", "tcp"); /* Prepare a socket address for the server. We need an */ /* IP address (corresponding to the given hostname) */ /* and a port number (corresponding to the "finger" */ /* service. */ memset(&sa,'\0',sizeof(sa)); sa.sin_family = AF_INET; memcpy(&sa.sin_addr,host->h_addr,sizeof(sa.sin_addr)); sa.sin_port = serv ? serv->s_port : htons(FINGER_PORT); /* Get a socket of the proper type. We use SOCK_STREAM */ /* because we want to communicate using TCP */ /* (we want a reliable protocol). */ s = socket(AF_INET, SOCK_STREAM, 0); if (s == -1) { perror("finger - socket() failed"); exit(EXIT_FAILURE); } /* Connect to the host and port. */ if (connect(s, &sa, sizeof(sa)) == -1) { perror("finger - connect() failed"); return(EXIT_FAILURE); } /* read() and write() are the most convenient calls */ /* for transmitting and receiving data over stream */ /* sockets. */ /* Write to server. */ /* If long option specified, pass that first. */ if (longlist) { out[0] = htoncs('/'); out[1] = htoncs('W'); write(s,out,2); } /* Terminate msg with CR-LF. */ write(s,&cr,1); write(s,&lf,1); /* Server should respond. */ /* Read until EOF indicated. */ while (n=read(s,in,READ_BLOCK_SIZE)) { for (i=0; i