// // Finger Version 3.1, a Windows Sockets Finger Client // // Copyright 1992, 1993 Network Research Corporation // // Permission to use, modify, and distribute this software and its // documentation for any purpose and without fee is hereby granted, provided // that the above copyright notice appears in all copies and that both // that copyright notice and this permission notice appear in supporting // documentation. NRC makes no claims as to the suitability of this software // for any purpose. // // Module NETWRKB uses Windows Sockets synchronous (blocking) calls to // query a remote finger server for a list of currently logged in users. // Module FINGER initiates the operation by calling FingerStart(), and // NETWRKB signals completion by calling FingerFinish(). NETWRKB uses DSPLIST // functions to send the retrieved data to the FINGER user interface module. // // 02/12/92 Lee Murach Created. // 10/20/92 Lee Murach Adapted to use display lists. // 11/02/92 Lee Murach Don't assume gethostbyname() works with dotted // decimal internet addr string. Prepare for // inet_addr() change in future windows sockets. // 12/02/92 Lee Murach Restructured for Finger 3.0 integrated release // 03/25/93 Lee Murach Added per-user finger support. // 05/18/93 F. Whiteside Fixed a simple bug in the getservbyname() code // #include #include #include #include "finger.h" BOOL Finger(IPA ipa, UINT port); IPA GetHostAddr(char *szHostName); // // InitNetApp -- no application wide initialization needed; provided for // compatability with NETWRKM. // VOID InitNetApp(VOID) { } // // InitNetInst -- no instance initialization needed; provided for // compatability with NETWRKM. // VOID InitNetInst(HWND hWnd) { } // // FingerStart -- called by FINGER module to initiate a conversation with // the remote finger server. We start by resolving the finger tcp service // to a port number, and then we resolve the host specifier to an IP address. // Finger() then establishes the connection, submits query, and retrieves // results. Calls FINGER module FingerFinish() to signal completion. // VOID FingerStart(VOID) { int err = FE_ERROR; // assume failure SERVENT FAR *pse; // pts to "service" data (internally allocated) // looking for finger tcp port if (pse = getservbyname("finger", NULL)) { UINT fingerport; // hold the data returned by getservbyname // because the standard says you *must* copy this // data out before calling any winsock API function IPA ipa; // holds internet protocol address fingerport = pse->s_port; if ((ipa = GetHostAddr(szHostName)) != INADDR_NONE) { if (Finger(ipa, fingerport)) err = 0; // it worked! } else // don't recognize host name ReportFingerErr(FE_NOHOST); } else // can't find finger port ReportFingerErr(FE_NOPORT); FingerFinish(err); } // // GetHostAddr -- gets host's internet address. Interprets argument first // as dotted internet address string, and failing that, as a DNS host // name. // IPA GetHostAddr(char *szHostName) { IPA ipa; HOSTENT FAR *phe; // pts to host info struct (internally allocated) if ((ipa = INET_ADDR(szHostName)) != INADDR_NONE) return ipa; if (phe = gethostbyname(szHostName)) { ipa = *(IPA FAR *) *(phe->h_addr_list); return ipa; } return INADDR_NONE; } // // Finger -- queries remote finger server for list of users currently // logged in. Returns the data as a display list by using DSPLIST functions. // BOOL Finger(IPA ipa, UINT port) { BOOL ret = TRUE; // assume success SOCKET sock; // communications end point if ((sock = socket(AF_INET, SOCK_STREAM, 0)) >= 0) { SOCKADDR_IN server; // address of the finger server memset(&server, 0, sizeof(server)); server.sin_family = AF_INET; server.sin_port = port; server.sin_addr.s_addr = ipa; // establish a stream connection to server if (!connect(sock, (SOCKADDR *)&server, sizeof(server))) { char msg[MAXUSER+3]; int msglen; strcpy(msg, szUser); strcat(msg, "\r\n"); msglen = strlen(msg); if (send(sock, msg, msglen, 0) == msglen) { static char buf[500]; // receive buffer int nchars; // n chars just received, or error /* open a new display list and push characters until either no more received or an error occurs */ OpenDisplayList(); while (( nchars = recv(sock, (char FAR *)&buf, sizeof(buf), 0)) > 0) PushChars(buf, nchars); // add chars to display list CloseDisplayList(); if (nchars < 0) { FreeDisplayList(); // list is invalid ReportFingerErr(FE_NORECV); // error during receive ret = FALSE; } } else ReportFingerErr(FE_NOSEND); // didn't send it (all) } else ReportFingerErr(FE_NOCONN); // cannot connect to server closesocket(sock); // don't need this anymore } else ReportFingerErr(FE_NOSOCK); // cannot get socket return(ret); }