⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 netwrkm.c

📁 finger client程序
💻 C
字号:
//
// 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 NETWRKM uses Windows Sockets asynchronous (message based) calls to
// query a remote finger server for a list of currently logged in users.
// Module FINGER initiates the operation by calling FingerStart(), and
// NETWRKM signals completion by calling FingerFinish(). NETWRKM uses DSPLIST
// functions to send the retrieved data to the FINGER user interface module.
//
// 04/01/92 Lee Murach  Created.
// 11/30/92 Lee Murach  Adapted for WS 1.1 WSAAsyncSelect()
// 12/02/92 Lee Murach  Restructured for Finger 3.0 integrated release
// 01/15/92 Lee Murach  Change FD_READ to FD_READ | FD_CLOSE
// 03/01/93 Lee Murach  Added WSAEWOULDBLOCK check to DoConnect()
// 03/25/93 Lee Murach  Added per-user finger support.
//

#include <memory.h>
#include <string.h>
#include <windows.h>
#include <winsock.h>
#include "finger.h"

// messages for windows sockets returns
#define WM_SERVICE            (WM_USER + 1)
#define WM_HOSTRESOLVED       (WM_USER + 2)
#define WM_CONNECTED          (WM_USER + 3)
#define WM_OKTORECV           (WM_USER + 4)
#define NETWINDOW "NetWindow"

LONG FAR APIENTRY NetWndProc(HWND hWnd, UINT wMsg, UINT wParam, LONG lParam);
LONG DoResolveHost(HWND hWnd, UINT wMsg, UINT wParam, LONG lParam);
LONG DoConnect(HWND hWnd, UINT wMsg, UINT wParam, LONG lParam);
LONG DoQuery(HWND hWnd, UINT wMsg, UINT wParam, LONG lParam);
LONG DoRetrieval(HWND hWnd, UINT wMsg, UINT wParam, LONG lParam);
void LoadEntBuf(IPA ipa);

DECODEWORD netMsgs[] =                 // network window messages & handlers
{
   WM_SERVICE,       DoResolveHost,
   WM_HOSTRESOLVED,  DoConnect,
   WM_CONNECTED,     DoQuery,
   WM_OKTORECV,      DoRetrieval
};

SOCKET   Sock;                         // connects to remote server's socket
int      Port;                         // hold port for finger service
char     EntBuf[MAXGETHOSTSTRUCT];     // buf for service & resolve returns
HWND     hNetWnd;                      // network window handle

//
// InitNetApp -- registers window class for the network module's invisible
// child window. This is called only for the first instance of finger.
//
VOID InitNetApp(VOID)
{
   WNDCLASS wndclass;

   wndclass.style         = 0;
   wndclass.lpfnWndProc   = NetWndProc;
   wndclass.cbClsExtra    = 0;
   wndclass.cbWndExtra    = 0;
   wndclass.hInstance     = hInst;
   wndclass.hIcon         = 0;
   wndclass.hCursor       = 0;
   wndclass.hbrBackground = 0;
   wndclass.lpszMenuName  = NULL;
   wndclass.lpszClassName = NETWINDOW;

   RegisterClass(&wndclass);
}

//
// InitNetInst -- initializes the network module by creating an invisible
// child of the main finger window which will be used to receive Windows
// Sockets notification messages.  The window will be automatically
// destroyed when the main window exits, so no finalization is required.
//
VOID InitNetInst(HWND hWnd)
{
   hNetWnd = CreateWindow( NETWINDOW, "", WS_OVERLAPPEDWINDOW,
                           CW_USEDEFAULT, CW_USEDEFAULT,
                           CW_USEDEFAULT, CW_USEDEFAULT,
                           hWnd, 0, hInst, NULL);
}

//
// NetWndProc -- callback function for network window.  The network window
// is a child window created especially to receive windows sockets network
// messages.  The function decodes and routes to appropriate message handler.
//
LONG FAR APIENTRY NetWndProc(HWND hWnd, UINT wMsg, UINT wParam, LONG lParam)
{
   int i;

   for (i = 0; i < dim(netMsgs); i++)
   {
      if (wMsg == netMsgs[i].Code)
         return((*netMsgs[i].Fxn)(hWnd, wMsg, wParam, lParam));
   }

   return(DefWindowProc(hWnd, wMsg, wParam, lParam));
}

//
// 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. Windows Sockets WSAAsync routines signal completion
// by posting messages, which are dispatched to appropriate handlers.
//
VOID FingerStart(VOID)
{
   if (WSAAsyncGetServByName(hNetWnd, WM_SERVICE, "finger", "tcp",
                             EntBuf, sizeof(EntBuf)) == -1)
   {
      ReportFingerErr(FE_NOPORT);
      FingerFinish(FE_ERROR);
   }
}

//
// DoResolveHost -- resolves host specifier to an IP address.  Since we
// allow a "dotted decimal" IP address to be entered in lieu of a DNS host
// name, we check for this syntax before assuming a DNS name.
//
LONG DoResolveHost(HWND hWnd, UINT wMsg, UINT wParam, LONG lParam)
{
   IPA ipa;

   if (WSAGETSELECTERROR(lParam))
   {
      ReportFingerErr(FE_NOPORT);         // cannot locate finger service
      FingerFinish(FE_ERROR);
      return(FALSE);
   }

   Port = ((SERVENT *)EntBuf)->s_port;    // we're going to reuse the buffer

   // if host specifier is dotted decimal ip address, resolve right here
   if ((ipa = INET_ADDR(szHostName)) != INADDR_NONE)
   {
      LoadEntBuf(ipa);
      PostMessage(hNetWnd, WM_HOSTRESOLVED, 0, 0);
      return(FALSE);
   }

   // assume specifier is DNS host name
   if (WSAAsyncGetHostByName(hNetWnd, WM_HOSTRESOLVED, szHostName,
                             EntBuf, sizeof(EntBuf)) == -1)
   {
      ReportFingerErr(FE_NOHOST);
      FingerFinish(FE_ERROR);
   }

   return(FALSE);
}

//
// LoadEntBuf -- loads the EntBuf (sufficiently) with a HOSTENT and
// referenced IPA.  This is so we can return IPAs in the same
// manner as a WSAAsync call.
//
void LoadEntBuf(IPA ipa)
{
   LPHOSTENT phe = (LPHOSTENT) EntBuf;
   LPPIPA ppipa = (LPPIPA) (EntBuf + sizeof(HOSTENT));
   LPIPA pipa = (LPIPA) (EntBuf + sizeof(HOSTENT) + sizeof(LPPIPA));

   _fmemset(phe, 0, sizeof(HOSTENT));
   phe->h_addr_list = (char FAR * FAR *) ppipa;
   *ppipa = pipa;
   *pipa = ipa;
}

//
// DoConnect -- allocates a socket and connects to remote finger server.
//
LONG DoConnect(HWND hWnd, UINT wMsg, UINT wParam, LONG lParam)
{
   if (WSAGETSELECTERROR(lParam))
   {
      ReportFingerErr(FE_NOHOST);       // could not resolve host name
      FingerFinish(FE_ERROR);
      return(FALSE);
   }

   if ((Sock = socket(AF_INET, SOCK_STREAM, 0)) >= 0)
   {
      SOCKADDR_IN server;
      u_long block = FALSE;
      HOSTENT *phe = (HOSTENT *) EntBuf;

      memset(&server, 0, sizeof(server));
      server.sin_family = AF_INET;
      server.sin_port = Port;
      server.sin_addr = *((IN_ADDR FAR *) *phe->h_addr_list);

      // post message when connect is established
      WSAAsyncSelect(Sock, hNetWnd, WM_CONNECTED, FD_CONNECT);

      if (  connect(Sock, (SOCKADDR *)&server, sizeof(server)) < 0 &&
            WSAGetLastError() != WSAEWOULDBLOCK)
      {
         ReportFingerErr(FE_NOCONN);
         FingerFinish(FE_ERROR);
      }
   }
   else
   {
      ReportFingerErr(FE_NOSOCK);
      FingerFinish(FE_ERROR);
   }

   return(FALSE);
}

//
// DoQuery -- sends a query for all currently logged in users to remote
// server.
//
LONG DoQuery(HWND hWnd, UINT wMsg, UINT wParam, LONG lParam)
{
   char msg[MAXUSER+3];
   int msglen;

   if (WSAGETSELECTERROR(lParam))
   {
      ReportFingerErr(FE_NOCONN);       // could not connect to server
      FingerFinish(FE_ERROR);
      return(FALSE);
   }

   // post message when data is available for read
   WSAAsyncSelect(Sock, hNetWnd, WM_OKTORECV, FD_READ | FD_CLOSE);

   strcpy(msg, szUser);
   strcat(msg, "\r\n");
   msglen = strlen(msg);

   if (send(Sock, msg, msglen, 0) != msglen)
   {
      ReportFingerErr(FE_NOSEND);
      FingerFinish(FE_ERROR);
      return(FALSE);
   }
   
   OpenDisplayList();   // new display list will contain received data
   
   return(FALSE);
}

//
// DoRetrieval -- fetches ascii text from remote finger server, and builds
// display list until the end of the text stream.
//
LONG DoRetrieval(HWND hWnd, UINT wMsg, UINT wParam, LONG lParam)
{
   static char buf[500];
   int nchars, err = 0;

   /* receives data not to exceed buf size & reenables notification
      of more data pending */

   if ((nchars = recv(Sock, (char FAR *)&buf, sizeof(buf), 0)) > 0)
   {
      PushChars(buf, nchars);        // adds character to display list
      return(FALSE);
   }

   CloseDisplayList();               // close list if error or end-of-data
   closesocket(Sock);                // don't need socket anymore

   if (nchars < 0)
   {
      FreeDisplayList();
      ReportFingerErr(FE_NORECV);   // error during receive
      err = FE_ERROR;
   }

   FingerFinish(err);               // signal end-of-finger

   return(FALSE);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -