home *** CD-ROM | disk | FTP | other *** search
/ Borland Programmer's Resource / Borland_Programmers_Resource_CD_1995.iso / winsock / fingd100 / src / file.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-19  |  11.9 KB  |  526 lines

  1.  
  2. // Contents ---------------------------------------------------------------
  3. //
  4. //   file.c  -- a Windows Socket Finger Daemon
  5. //
  6. //   Version 1.0
  7. //
  8. //   Copyright (C) Frederick W. Bent 1994
  9. //   All rights reserved.
  10. //
  11. //
  12. // Description
  13. //
  14. //      FINGERD is both the user interface and the network interface.
  15. //    FINGERD is a server, its 'users' are FINGER clients, so the user
  16. //    interface requirements of the daemon are rather simple.  FINGERD
  17. //      simply updates its display with outbound buffer traffic.  We also
  18. //      display winsock errors in the server display.
  19. //
  20. //      FINGERD uses WSAAsyncSelect() to receive the SOCKET_MESSAGE window
  21. //      messages that notify FINGERD of pending client requests, causing
  22. //    FINGERD to respond.  When an FD_ACCEPT is received, the socket is
  23. //      added to the linked list of clients.
  24. //
  25. //      FINGERD speaks the finger protocol, and will reply to finger
  26. //    (e.g., the MS-Windows 3.x winsock finger client).
  27. //
  28. // Ends -------------------------------------------------------------------
  29.  
  30. // History ----------------------------------------------------------------
  31. //
  32. // 6/28/94  1.0  Fred Bent    First release
  33. //
  34. // Ends -------------------------------------------------------------------
  35.  
  36. // Legal Stuff ------------------------------------------------------------
  37. //
  38. // Permission to use, modify, and distribute this software and its
  39. // documentation for any purpose and without fee is hereby granted,
  40. // provided that the above copyright notice appears in all copies and
  41. // that both that copyright notice and this permission notice appear in
  42. // supporting documentation.  The author makes no claims as to the
  43. // suitability of this software and documentation for any purpose.
  44. //
  45. // Legal Stuff Ends -------------------------------------------------------
  46.  
  47.  
  48. // Interface Dependencies -------------------------------------------------
  49.  
  50. #define STRICT
  51.  
  52. #include <windows.h>
  53. #include <windowsx.h>
  54. #include <time.h>
  55. #include "file.h"
  56.  
  57. // Ends -------------------------------------------------------------------
  58.  
  59.  
  60. // State variables --------------------------------------------------------
  61.  
  62. int    nextchar = -1;
  63. BOOL    lastchar = FALSE;
  64.  
  65. // Ends -------------------------------------------------------------------
  66.  
  67.  
  68.  
  69. // Function
  70.  
  71.     UINT file_read(HFILE hfFile, LPBYTE ptr, UINT maxnbytes, int mode)
  72.  
  73. {
  74.     char    c;
  75.     int    status, count;
  76.  
  77.  
  78.     if (mode == MODE_BINARY)
  79.         {
  80.         count = _lread(hfFile, ptr, maxnbytes);
  81.         if ( count == HFILE_ERROR )
  82.         {
  83.                     /* read error on local file */
  84.         }
  85.         return (count);
  86.     }
  87.     else if (mode == MODE_ASCII)
  88.     {
  89.         /*
  90.          * For files that are transfered in netascii, we must
  91.          * perform the following conversions:
  92.          *
  93.          * Since MS-DOS uses a CR,LF to indicate a newline
  94.                  * we do not have to do too much processing.
  95.          *
  96.          *    CR,LF         -> "\r\n"
  97.          *    CR,anything_else -> "\r\0"<anything_else>
  98.          */
  99.  
  100.         for (count = 0; count < maxnbytes; count++)
  101.         {
  102.             if (nextchar >= 0)
  103.             {
  104.                 *(ptr++) = nextchar;
  105.                 nextchar = -1;
  106.                 continue;
  107.             }
  108.  
  109.             status = _lread(hfFile, &c, sizeof(c));
  110.  
  111.             if ( status == 0 )    // EOF
  112.             {
  113.                 lastchar = FALSE;
  114.                 nextchar = -1;
  115.                             return(count);
  116.             }
  117.             else if ( c == '\r' )    // CR
  118.             {
  119.                             if (!lastchar)
  120.                     lastchar = TRUE;
  121.                 else        // CR,CR
  122.                 {
  123.                     c = '\0';
  124.                     nextchar = c;
  125.                                 }
  126.             }
  127.             else if ( c == '\n' )    // LF
  128.             {
  129.                 if (lastchar)    // CR,LF
  130.                     lastchar = FALSE;
  131.             } else {        // anything_else
  132.                 if (lastchar)
  133.                 {
  134.                     c = '\0';
  135.                                         nextchar = c;
  136.                     lastchar = FALSE;
  137.                 }
  138.             }
  139.  
  140.             *(ptr++) = c;
  141.  
  142.         }
  143.  
  144.         return(count);
  145.     } else {
  146.         /* Unknown mode */
  147.     }
  148.  
  149.     /* NOT REACHED */
  150.     return 0;
  151. }
  152.  
  153.  
  154. // Function
  155.  
  156.     int netascii(LPBYTE lpBuffer, UINT maxnbytes)
  157.  
  158. // Summary ----------------------------------------------------------------
  159. //
  160. //    Converts a buffer of ASCII text to netascii format.  This means
  161. //    that each line of text is terminated with a CR,LF "\r\n" pair,
  162. //    and a single CR is followed by a NULL '\0'.  The worst case
  163. //    scenario is a buffer full of CRs, which will cause the resulting
  164. //    buffer to be twice the size of the original buffer.
  165. //
  166. //    So we allocate a buffer that is twice the size of maxnbytes
  167. //    and then transfer the bytes in the source buffer, adding the
  168. //    necessary NULL bytes.
  169. //
  170. //    Since MS-DOS uses a CR,LF pair to indicate a newline, we do not
  171. //    have to worry about generating these.
  172. //
  173. //
  174. // Parameters
  175. //
  176. //    lpBuffer
  177. //
  178. //    The pointer to the ASCII buffer in MS-DOS text format.
  179. //
  180. //    maxnbytes
  181. //
  182. //    The number of bytes in the buffer to be converted.
  183. //
  184. //
  185. // Return
  186. //
  187. //    BOOL    Returns the number of bytes copied into lpBuffer, or
  188. //        -1 if there was an error allocating buffer memory.
  189. //
  190. // Ends -------------------------------------------------------------------
  191.  
  192. {
  193.     UINT    count;
  194.     int    nextchar = -1;
  195.     BYTE    c;
  196.     BOOL    lastchar = FALSE;
  197.     HGLOBAL    hDest;
  198.     LPBYTE    lpDest;
  199.     UINT    nDestSize;
  200.     LPBYTE    ptr;
  201.  
  202.     if (( maxnbytes == 0 ) || ( lpBuffer == NULL )) return(0);
  203.  
  204.     nDestSize = maxnbytes * 2;
  205.     hDest = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, nDestSize);
  206.     if ( hDest == NULL ) return(-1);
  207.  
  208.     /* Now get a pointer to it */
  209.     lpDest = GlobalLock(hDest);
  210.     if (lpDest == NULL )
  211.     {
  212.         GlobalFree(hDest);
  213.         return(-1);
  214.     }
  215.  
  216.     for (count = 0, ptr = lpDest; count < maxnbytes; count++)
  217.     {
  218.         if (nextchar >= 0)
  219.         {
  220.             *(ptr++) = (char) nextchar;
  221.             nextchar = -1;
  222.         }
  223.  
  224.         c = lpBuffer[count];
  225.  
  226.         if ( c == '\r' )    // CR
  227.         {
  228.                            if (!lastchar)
  229.                 lastchar = TRUE;
  230.             else        // CR,CR
  231.             {
  232.                 c = '\0';
  233.                 nextchar = c;
  234.                         }
  235.         }
  236.         else if ( c == '\n' )    // LF
  237.         {
  238.             if (lastchar)    // CR,LF
  239.                 lastchar = FALSE;
  240.         } else {        // anything_else
  241.             if (lastchar)
  242.             {
  243.                 c = '\0';
  244.                                 nextchar = c;
  245.                 lastchar = FALSE;
  246.             }
  247.         }
  248.  
  249.         *(ptr++) = c;
  250.     }
  251.  
  252.     count = (ptr - lpDest);
  253.  
  254.     hmemcpy(lpBuffer, lpDest, (long)count);
  255.  
  256.     GlobalUnlock(hDest);
  257.     GlobalFree(hDest);
  258.  
  259.     return (count);
  260.  
  261. }
  262.  
  263.  
  264. // Library Function
  265.  
  266.     LPSTR    lstrchr(LPSTR lpszString, char cChar)
  267.  
  268. // Summary ----------------------------------------------------------------
  269. //
  270. //    Search for the first occurance of the character in a string
  271. //    and returns a pointer to it.
  272. //
  273. // Parameters
  274. //
  275. //    lpszString    A pointer to a ASCIIZ string
  276. //
  277. //    cChar        The character to be searched for.
  278. //
  279. // Return
  280. //
  281. //    LPSTR        A pointer to the character, otherwise NULL.
  282. //
  283. // Ends -------------------------------------------------------------------
  284.  
  285.  
  286.     {
  287.         int    iWalker;
  288.  
  289.  
  290.         if ( lpszString == NULL ) return(NULL);
  291.  
  292.         iWalker = 0;
  293.         while ( lpszString[iWalker] != '\0' )
  294.         {
  295.             if ( lpszString[iWalker] == cChar ) return &lpszString[iWalker];
  296.             iWalker++;
  297.         }
  298.  
  299.         return NULL;
  300.         }
  301.  
  302.  
  303. // Library Function
  304.  
  305.     LPSTR    lstrrchr(LPSTR lpszString, char cChar)
  306.  
  307. // Summary ----------------------------------------------------------------
  308. //
  309. //    Search for the first occurance of the character in a string
  310. //    and returns a pointer to it.
  311. //
  312. // Parameters
  313. //
  314. //    lpszString    A pointer to a ASCIIZ string
  315. //
  316. //    cChar        The character to be searched for.
  317. //
  318. // Return
  319. //
  320. //    LPSTR        A pointer to the character, otherwise NULL.
  321. //
  322. // Ends -------------------------------------------------------------------
  323.  
  324.  
  325.     {
  326.         int    iWalker;
  327.  
  328.  
  329.         if ( lpszString == NULL ) return(NULL);
  330.  
  331.         iWalker = lstrlen(lpszString);
  332.         while ( iWalker >= 0 )
  333.         {
  334.             if ( lpszString[iWalker] == cChar ) return &lpszString[iWalker];
  335.             iWalker--;
  336.         }
  337.  
  338.         return NULL;
  339.         }
  340.  
  341.  
  342.  
  343.  
  344.     LPSTR rip(LPSTR lpszString)
  345.  
  346. // Summary ----------------------------------------------------------------
  347. //
  348. //    Removes the first carriage return and/or line-feed from a string.
  349. //
  350. // Parameters
  351. //
  352. //    lpszString    A pointer to a ASCIIZ string
  353. //
  354. // Return
  355. //
  356. //    LPSTR        A pointer to the ASCIIZ string, otherwise NULL.
  357. //
  358. // Ends -------------------------------------------------------------------
  359.  
  360.     {
  361.         LPSTR temp;
  362.  
  363.         if ((temp = lstrchr( lpszString, '\n')) != NULL) *temp = '\0';
  364.         if ((temp = lstrchr( lpszString, '\r')) != NULL) *temp = '\0';
  365.         return( lpszString );
  366.     }
  367.  
  368.  
  369.     int    FillInTheBlanks( LPSTR lpszFName, LPSTR lpszLine, int iLine, HFILE hfFile )
  370.     {
  371.         struct tm    *tmClock;
  372.         DWORD        dwTick;
  373.                 time_t        lTime;
  374.         HLOCAL        hBuffer = NULL;
  375.                 LPSTR        lpszBuffer = NULL;
  376.                 HLOCAL        hTemp = NULL;
  377.         PSTR        szTemp = NULL;
  378.         char        szLogin[8];
  379.         char        szRealname[32];
  380.         char        szLoginDir[36];
  381.         char        szShell[36];
  382.         char        szOffice[80];
  383.         char        szTime[36];
  384.         LPSTR        lpstr = NULL;
  385.         char        szFile[336];
  386.         BOOL        bDoingSnark;
  387.  
  388.  
  389.         hTemp = LocalAlloc(LHND, 336);
  390.         if ( hTemp == NULL ) return(-1);
  391.  
  392.  
  393.         szTemp = LocalLock(hTemp);
  394.         if ( szTemp == NULL )
  395.         {
  396.             LocalFree(hTemp);
  397.             return(-1);
  398.         }
  399.  
  400.         hBuffer = GlobalAlloc(GHND, 336);
  401.         if ( hBuffer == NULL ) return(-1);
  402.  
  403.     
  404.         lpszBuffer = GlobalLock(hBuffer);
  405.         if ( lpszBuffer == NULL )
  406.         {
  407.             GlobalFree(hBuffer);
  408.             return(-1);
  409.         }
  410.  
  411.         bDoingSnark = TRUE;
  412.         if ( lstrlen(lpszFName) != 0 )
  413.         {
  414.             bDoingSnark = FALSE;
  415.             lstrcpy((LPSTR) szFile, lpszFName);
  416.             lpstr = lstrrchr((LPSTR) szFile, '\\');
  417.  
  418.             *lpstr = '\0';
  419.             lpstr = lstrrchr((LPSTR) szFile, '\\');
  420.             lpstr++;
  421.                     lstrcpy((LPSTR) szLogin, lpstr);
  422.  
  423.             lstrcat((LPSTR) szFile, "\\USERINFO.INI");
  424.  
  425.  
  426.             GetPrivateProfileString( "FingerInfo"
  427.                     , "RealName"
  428.                     , ""
  429.                     , (LPSTR) szRealname
  430.                     , 32
  431.                     , (LPSTR) szFile );
  432.  
  433.             GetPrivateProfileString( "FingerInfo"
  434.                     , "Office"
  435.                     , ""
  436.                     , (LPSTR) szOffice
  437.                     , 28
  438.                     , (LPSTR) szFile );
  439.  
  440.             lstrcpy((LPSTR) szLoginDir, lpszFName);
  441.             lpstr = lstrrchr(szLoginDir, '\\' );
  442.             if (lpstr != NULL) *lpstr = '\0';
  443.  
  444.             GetPrivateProfileString( "FingerInfo"
  445.                     , "Directory"
  446.                     , (LPCSTR) szLoginDir
  447.                     , (LPSTR) szLoginDir
  448.                     , 36
  449.                     , (LPSTR) szFile );
  450.  
  451.  
  452.             GetPrivateProfileString( "FingerInfo"
  453.                     , "Shell"
  454.                     , "c:\\dos\\command.com"
  455.                     , (LPSTR) szShell
  456.                     , 336
  457.                     , (LPSTR) szFile );
  458.                         
  459.             wsprintf( szTemp, "Login name: %-8s                    In real life: %s\r\n"
  460.                     , (LPSTR) szLogin
  461.                     , (LPSTR) szRealname );
  462.             lstrcpy( lpszLine, (LPSTR) szTemp );
  463.  
  464.             if (lstrlen(szOffice) > 0 )
  465.                         {
  466.                 wsprintf( szTemp, "Office:     %s\r\n", (LPSTR) szOffice );
  467.                 lstrcat( lpszLine, (LPSTR) szTemp );
  468.             }
  469.  
  470.             wsprintf( szTemp, "Directory:  %-27s Shell: %s\r\n", (LPSTR) szLoginDir, (LPSTR) szShell );
  471.             lstrcat( lpszLine, (LPSTR) szTemp );
  472.  
  473.                 }
  474.         /*
  475.          * Borland C++ 3.1 funtion which will read the
  476.          * TZ=EST5EDT environment variable
  477.          */
  478.         tzset();
  479.  
  480.                 time(&lTime);
  481.         dwTick = GetTickCount() / 1000L;    /* Time system started in ms*/
  482.         lTime = lTime - dwTick;
  483.  
  484.         tmClock = localtime(&lTime);
  485.  
  486.         if ( !strftime(szTime, sizeof(szTime), "%a %b %d %H:%M:%S %Y %Z", tmClock))
  487.         {
  488.             /* remove the newline character from the string */
  489.             lstrcpy((LPSTR) szTime, (LPSTR)asctime(tmClock));
  490.             szTemp[lstrlen((LPSTR)szTime)-1] = '\0';
  491.         }
  492.  
  493.         if(lstrlen((LPSTR)szTime) > iLine)
  494.         {
  495.             szTemp[iLine-1] = '\0';
  496.         }
  497.  
  498.         if (bDoingSnark)
  499.             wsprintf(szTemp, "Up since: %-28s\r\n", (LPSTR) szTime);
  500.                 else
  501.             wsprintf(szTemp, "On since: %-28s  Terminal: console\r\n", (LPSTR) szTime);
  502.  
  503.         lstrcat( lpszLine, (LPSTR) szTemp);
  504.  
  505.  
  506.  
  507. //        GetPrivateProfileString( "FingerInfo"
  508. //                    , "Plan"
  509. //                    , ""
  510. //                    , lpszBuffer
  511. //                    , 256
  512. //                    , (LPSTR) szFile );
  513. //
  514. //                if (lstrlen(lpszBuffer) > 0 )
  515. //            lstrcat( lpszLine, "Plan:\r\n" );
  516.  
  517.         if (hfFile != HFILE_ERROR)
  518.             lstrcat( lpszLine, "Plan:\r\n" );
  519.  
  520.         LocalUnlock(hTemp);
  521.         LocalFree(hTemp);
  522.         GlobalUnlock(hBuffer);
  523.         GlobalFree(hBuffer);
  524.  
  525.         return(lstrlen(lpszLine));
  526.     }