home *** CD-ROM | disk | FTP | other *** search
-
- // Contents ---------------------------------------------------------------
- //
- // file.c -- a Windows Socket Finger Daemon
- //
- // Version 1.0
- //
- // Copyright (C) Frederick W. Bent 1994
- // All rights reserved.
- //
- //
- // Description
- //
- // FINGERD is both the user interface and the network interface.
- // FINGERD is a server, its 'users' are FINGER clients, so the user
- // interface requirements of the daemon are rather simple. FINGERD
- // simply updates its display with outbound buffer traffic. We also
- // display winsock errors in the server display.
- //
- // FINGERD uses WSAAsyncSelect() to receive the SOCKET_MESSAGE window
- // messages that notify FINGERD of pending client requests, causing
- // FINGERD to respond. When an FD_ACCEPT is received, the socket is
- // added to the linked list of clients.
- //
- // FINGERD speaks the finger protocol, and will reply to finger
- // (e.g., the MS-Windows 3.x winsock finger client).
- //
- // Ends -------------------------------------------------------------------
-
- // History ----------------------------------------------------------------
- //
- // 6/28/94 1.0 Fred Bent First release
- //
- // Ends -------------------------------------------------------------------
-
- // Legal Stuff ------------------------------------------------------------
- //
- // 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. The author makes no claims as to the
- // suitability of this software and documentation for any purpose.
- //
- // Legal Stuff Ends -------------------------------------------------------
-
-
- // Interface Dependencies -------------------------------------------------
-
- #define STRICT
-
- #include <windows.h>
- #include <windowsx.h>
- #include <time.h>
- #include "file.h"
-
- // Ends -------------------------------------------------------------------
-
-
- // State variables --------------------------------------------------------
-
- int nextchar = -1;
- BOOL lastchar = FALSE;
-
- // Ends -------------------------------------------------------------------
-
-
-
- // Function
-
- UINT file_read(HFILE hfFile, LPBYTE ptr, UINT maxnbytes, int mode)
-
- {
- char c;
- int status, count;
-
-
- if (mode == MODE_BINARY)
- {
- count = _lread(hfFile, ptr, maxnbytes);
- if ( count == HFILE_ERROR )
- {
- /* read error on local file */
- }
- return (count);
- }
- else if (mode == MODE_ASCII)
- {
- /*
- * For files that are transfered in netascii, we must
- * perform the following conversions:
- *
- * Since MS-DOS uses a CR,LF to indicate a newline
- * we do not have to do too much processing.
- *
- * CR,LF -> "\r\n"
- * CR,anything_else -> "\r\0"<anything_else>
- */
-
- for (count = 0; count < maxnbytes; count++)
- {
- if (nextchar >= 0)
- {
- *(ptr++) = nextchar;
- nextchar = -1;
- continue;
- }
-
- status = _lread(hfFile, &c, sizeof(c));
-
- if ( status == 0 ) // EOF
- {
- lastchar = FALSE;
- nextchar = -1;
- return(count);
- }
- else if ( c == '\r' ) // CR
- {
- if (!lastchar)
- lastchar = TRUE;
- else // CR,CR
- {
- c = '\0';
- nextchar = c;
- }
- }
- else if ( c == '\n' ) // LF
- {
- if (lastchar) // CR,LF
- lastchar = FALSE;
- } else { // anything_else
- if (lastchar)
- {
- c = '\0';
- nextchar = c;
- lastchar = FALSE;
- }
- }
-
- *(ptr++) = c;
-
- }
-
- return(count);
- } else {
- /* Unknown mode */
- }
-
- /* NOT REACHED */
- return 0;
- }
-
-
- // Function
-
- int netascii(LPBYTE lpBuffer, UINT maxnbytes)
-
- // Summary ----------------------------------------------------------------
- //
- // Converts a buffer of ASCII text to netascii format. This means
- // that each line of text is terminated with a CR,LF "\r\n" pair,
- // and a single CR is followed by a NULL '\0'. The worst case
- // scenario is a buffer full of CRs, which will cause the resulting
- // buffer to be twice the size of the original buffer.
- //
- // So we allocate a buffer that is twice the size of maxnbytes
- // and then transfer the bytes in the source buffer, adding the
- // necessary NULL bytes.
- //
- // Since MS-DOS uses a CR,LF pair to indicate a newline, we do not
- // have to worry about generating these.
- //
- //
- // Parameters
- //
- // lpBuffer
- //
- // The pointer to the ASCII buffer in MS-DOS text format.
- //
- // maxnbytes
- //
- // The number of bytes in the buffer to be converted.
- //
- //
- // Return
- //
- // BOOL Returns the number of bytes copied into lpBuffer, or
- // -1 if there was an error allocating buffer memory.
- //
- // Ends -------------------------------------------------------------------
-
- {
- UINT count;
- int nextchar = -1;
- BYTE c;
- BOOL lastchar = FALSE;
- HGLOBAL hDest;
- LPBYTE lpDest;
- UINT nDestSize;
- LPBYTE ptr;
-
- if (( maxnbytes == 0 ) || ( lpBuffer == NULL )) return(0);
-
- nDestSize = maxnbytes * 2;
- hDest = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, nDestSize);
- if ( hDest == NULL ) return(-1);
-
- /* Now get a pointer to it */
- lpDest = GlobalLock(hDest);
- if (lpDest == NULL )
- {
- GlobalFree(hDest);
- return(-1);
- }
-
- for (count = 0, ptr = lpDest; count < maxnbytes; count++)
- {
- if (nextchar >= 0)
- {
- *(ptr++) = (char) nextchar;
- nextchar = -1;
- }
-
- c = lpBuffer[count];
-
- if ( c == '\r' ) // CR
- {
- if (!lastchar)
- lastchar = TRUE;
- else // CR,CR
- {
- c = '\0';
- nextchar = c;
- }
- }
- else if ( c == '\n' ) // LF
- {
- if (lastchar) // CR,LF
- lastchar = FALSE;
- } else { // anything_else
- if (lastchar)
- {
- c = '\0';
- nextchar = c;
- lastchar = FALSE;
- }
- }
-
- *(ptr++) = c;
- }
-
- count = (ptr - lpDest);
-
- hmemcpy(lpBuffer, lpDest, (long)count);
-
- GlobalUnlock(hDest);
- GlobalFree(hDest);
-
- return (count);
-
- }
-
-
- // Library Function
-
- LPSTR lstrchr(LPSTR lpszString, char cChar)
-
- // Summary ----------------------------------------------------------------
- //
- // Search for the first occurance of the character in a string
- // and returns a pointer to it.
- //
- // Parameters
- //
- // lpszString A pointer to a ASCIIZ string
- //
- // cChar The character to be searched for.
- //
- // Return
- //
- // LPSTR A pointer to the character, otherwise NULL.
- //
- // Ends -------------------------------------------------------------------
-
-
- {
- int iWalker;
-
-
- if ( lpszString == NULL ) return(NULL);
-
- iWalker = 0;
- while ( lpszString[iWalker] != '\0' )
- {
- if ( lpszString[iWalker] == cChar ) return &lpszString[iWalker];
- iWalker++;
- }
-
- return NULL;
- }
-
-
- // Library Function
-
- LPSTR lstrrchr(LPSTR lpszString, char cChar)
-
- // Summary ----------------------------------------------------------------
- //
- // Search for the first occurance of the character in a string
- // and returns a pointer to it.
- //
- // Parameters
- //
- // lpszString A pointer to a ASCIIZ string
- //
- // cChar The character to be searched for.
- //
- // Return
- //
- // LPSTR A pointer to the character, otherwise NULL.
- //
- // Ends -------------------------------------------------------------------
-
-
- {
- int iWalker;
-
-
- if ( lpszString == NULL ) return(NULL);
-
- iWalker = lstrlen(lpszString);
- while ( iWalker >= 0 )
- {
- if ( lpszString[iWalker] == cChar ) return &lpszString[iWalker];
- iWalker--;
- }
-
- return NULL;
- }
-
-
-
-
- LPSTR rip(LPSTR lpszString)
-
- // Summary ----------------------------------------------------------------
- //
- // Removes the first carriage return and/or line-feed from a string.
- //
- // Parameters
- //
- // lpszString A pointer to a ASCIIZ string
- //
- // Return
- //
- // LPSTR A pointer to the ASCIIZ string, otherwise NULL.
- //
- // Ends -------------------------------------------------------------------
-
- {
- LPSTR temp;
-
- if ((temp = lstrchr( lpszString, '\n')) != NULL) *temp = '\0';
- if ((temp = lstrchr( lpszString, '\r')) != NULL) *temp = '\0';
- return( lpszString );
- }
-
-
- int FillInTheBlanks( LPSTR lpszFName, LPSTR lpszLine, int iLine, HFILE hfFile )
- {
- struct tm *tmClock;
- DWORD dwTick;
- time_t lTime;
- HLOCAL hBuffer = NULL;
- LPSTR lpszBuffer = NULL;
- HLOCAL hTemp = NULL;
- PSTR szTemp = NULL;
- char szLogin[8];
- char szRealname[32];
- char szLoginDir[36];
- char szShell[36];
- char szOffice[80];
- char szTime[36];
- LPSTR lpstr = NULL;
- char szFile[336];
- BOOL bDoingSnark;
-
-
- hTemp = LocalAlloc(LHND, 336);
- if ( hTemp == NULL ) return(-1);
-
-
- szTemp = LocalLock(hTemp);
- if ( szTemp == NULL )
- {
- LocalFree(hTemp);
- return(-1);
- }
-
- hBuffer = GlobalAlloc(GHND, 336);
- if ( hBuffer == NULL ) return(-1);
-
-
- lpszBuffer = GlobalLock(hBuffer);
- if ( lpszBuffer == NULL )
- {
- GlobalFree(hBuffer);
- return(-1);
- }
-
- bDoingSnark = TRUE;
- if ( lstrlen(lpszFName) != 0 )
- {
- bDoingSnark = FALSE;
- lstrcpy((LPSTR) szFile, lpszFName);
- lpstr = lstrrchr((LPSTR) szFile, '\\');
-
- *lpstr = '\0';
- lpstr = lstrrchr((LPSTR) szFile, '\\');
- lpstr++;
- lstrcpy((LPSTR) szLogin, lpstr);
-
- lstrcat((LPSTR) szFile, "\\USERINFO.INI");
-
-
- GetPrivateProfileString( "FingerInfo"
- , "RealName"
- , ""
- , (LPSTR) szRealname
- , 32
- , (LPSTR) szFile );
-
- GetPrivateProfileString( "FingerInfo"
- , "Office"
- , ""
- , (LPSTR) szOffice
- , 28
- , (LPSTR) szFile );
-
- lstrcpy((LPSTR) szLoginDir, lpszFName);
- lpstr = lstrrchr(szLoginDir, '\\' );
- if (lpstr != NULL) *lpstr = '\0';
-
- GetPrivateProfileString( "FingerInfo"
- , "Directory"
- , (LPCSTR) szLoginDir
- , (LPSTR) szLoginDir
- , 36
- , (LPSTR) szFile );
-
-
- GetPrivateProfileString( "FingerInfo"
- , "Shell"
- , "c:\\dos\\command.com"
- , (LPSTR) szShell
- , 336
- , (LPSTR) szFile );
-
- wsprintf( szTemp, "Login name: %-8s In real life: %s\r\n"
- , (LPSTR) szLogin
- , (LPSTR) szRealname );
- lstrcpy( lpszLine, (LPSTR) szTemp );
-
- if (lstrlen(szOffice) > 0 )
- {
- wsprintf( szTemp, "Office: %s\r\n", (LPSTR) szOffice );
- lstrcat( lpszLine, (LPSTR) szTemp );
- }
-
- wsprintf( szTemp, "Directory: %-27s Shell: %s\r\n", (LPSTR) szLoginDir, (LPSTR) szShell );
- lstrcat( lpszLine, (LPSTR) szTemp );
-
- }
- /*
- * Borland C++ 3.1 funtion which will read the
- * TZ=EST5EDT environment variable
- */
- tzset();
-
- time(&lTime);
- dwTick = GetTickCount() / 1000L; /* Time system started in ms*/
- lTime = lTime - dwTick;
-
- tmClock = localtime(&lTime);
-
- if ( !strftime(szTime, sizeof(szTime), "%a %b %d %H:%M:%S %Y %Z", tmClock))
- {
- /* remove the newline character from the string */
- lstrcpy((LPSTR) szTime, (LPSTR)asctime(tmClock));
- szTemp[lstrlen((LPSTR)szTime)-1] = '\0';
- }
-
- if(lstrlen((LPSTR)szTime) > iLine)
- {
- szTemp[iLine-1] = '\0';
- }
-
- if (bDoingSnark)
- wsprintf(szTemp, "Up since: %-28s\r\n", (LPSTR) szTime);
- else
- wsprintf(szTemp, "On since: %-28s Terminal: console\r\n", (LPSTR) szTime);
-
- lstrcat( lpszLine, (LPSTR) szTemp);
-
-
-
- // GetPrivateProfileString( "FingerInfo"
- // , "Plan"
- // , ""
- // , lpszBuffer
- // , 256
- // , (LPSTR) szFile );
- //
- // if (lstrlen(lpszBuffer) > 0 )
- // lstrcat( lpszLine, "Plan:\r\n" );
-
- if (hfFile != HFILE_ERROR)
- lstrcat( lpszLine, "Plan:\r\n" );
-
- LocalUnlock(hTemp);
- LocalFree(hTemp);
- GlobalUnlock(hBuffer);
- GlobalFree(hBuffer);
-
- return(lstrlen(lpszLine));
- }