home *** CD-ROM | disk | FTP | other *** search
/ PC World 2000 May / PCWorld_2000-05_cd.bin / Software / Servis / sambar / _SETUP.1 / netutils.c < prev    next >
C/C++ Source or Header  |  2000-03-15  |  11KB  |  501 lines

  1. /*
  2. ** NETUTILS
  3. **
  4. **      HTTP Wrapper for some basic Network Utilities
  5. **        (Not yet ported to UNIX)
  6. **
  7. **        Confidential Property of Tod Sambar
  8. **        (c) Copyright Tod Sambar 1997
  9. **        All rights reserved.
  10. **
  11. **
  12. ** Public Functions:
  13. **
  14. **        netutils_init
  15. **        ipname_lookup
  16. **        whois_lookup
  17. **        finger_lookup
  18. **
  19. **
  20. ** History:
  21. ** Chg#    Date    Description                                                Resp
  22. ** ----    -------    -------------------------------------------------------    ----
  23. **         2FEB97    Created                                                    sambar
  24. */
  25.  
  26. #include    <stdio.h>
  27. #include    <memory.h>
  28. #include    <string.h>
  29. #include    <stdlib.h>
  30. #ifdef    WIN32
  31. #include    <winsock.h>
  32. #include    <direct.h>
  33. #endif    /* WIN32 */
  34. #include    <errno.h>
  35. #include    <netutils.h>
  36.  
  37. /*
  38. ** WHOIS defines
  39. */
  40. #define WHOIS_PORT        43
  41. #define WHOIS_SERVER    "198.41.0.6"        /* rs.internic.net */
  42.  
  43. /*
  44. ** Network Utility RPC Commands
  45. */
  46. typedef struct netutils__rpcs
  47. {
  48.     SA_CHAR        *name;
  49.     SA_RPCPARAM    *params;
  50.     SA_INT        numparams;
  51.     SA_INT        auth;
  52.     SA_VOID        *func;
  53.     SA_CHAR        *descr;
  54. } NETUTILS__RPCS;
  55.  
  56. static SA_RPCPARAM        ipnamep [] =
  57. {
  58.     { "ipaddr",        1,    "IP Address to lookup." }
  59. };
  60. static SA_RPCPARAM        whoisp [] =
  61. {
  62.     { "sitename",    1,    "Site name to lookup." },
  63.     { "nameserver",    0,    "Name server to use (rs.internic.net is default)" }
  64. };
  65. static SA_RPCPARAM        fingerp [] =
  66. {
  67.     { "user",        0,    "User name to lookup (may be NULL)." },
  68.     { "host",        1,    "Site to lookup user on (must have finger daemon)." }
  69. };
  70.  
  71. static NETUTILS__RPCS     netutils_rpcs [] =
  72. {
  73.     { "ipname",        ipnamep,    sizeof(ipnamep) / sizeof(SA_RPCPARAM),
  74.       SA_AUTHORIZATION_ALL,    (SA_VOID *)ipname_lookup,
  75.       "Lookup the DNS name associated with an IP address." },
  76.     { "whois",        whoisp,        sizeof(ipnamep) / sizeof(SA_RPCPARAM),
  77.       SA_AUTHORIZATION_ALL,    (SA_VOID *)whois_lookup,
  78.       "Perform a whois lookup given a network domain name." },
  79.     { "finger",        fingerp,        sizeof(fingerp) / sizeof(SA_RPCPARAM),
  80.       SA_AUTHORIZATION_ALL,    (SA_VOID *)finger_lookup,
  81.       "Perform a finger lookup given a user and host." }
  82. };
  83.  
  84. /*
  85. **  NETUTILS_INIT
  86. **
  87. **    Initialize the Network Utilities.
  88. **
  89. **  Parameters:
  90. **    sactx        Sambar Server context
  91. **
  92. **  Returns:
  93. **    SA_SUCCEED | SA_FAIL
  94. */
  95. SA_RETCODE SA_PUBLIC
  96. netutils_init(sactx)
  97. SA_CTX        *sactx;
  98. {
  99.     int            i;
  100.  
  101.     /* Register the Network Uitlities RPCs with the application            */
  102.     for (i = 0; i < sizeof(netutils_rpcs) / sizeof(NETUTILS__RPCS); i++)
  103.     {
  104.         if (sa_cmd_init(sactx, netutils_rpcs[i].name, 
  105.             netutils_rpcs[i].params, netutils_rpcs[i].numparams,
  106.             netutils_rpcs[i].auth, netutils_rpcs[i].descr, 
  107.             (SA_RPCFUNC)netutils_rpcs[i].func) != SA_SUCCEED)
  108.         {
  109.             sa_log(sactx, "Unable to initialize Network Utility RPCs");
  110.             return (SA_FAIL);
  111.         }
  112.     } 
  113.  
  114.     sa_log(sactx, "Network Utilities Initialized");
  115.  
  116.     return (SA_SUCCEED);
  117. }
  118.  
  119. /*
  120. **  IPNAME_LOOKUP
  121. **
  122. **    Get the host name associated with an IP address.
  123. **
  124. **  Parameters:
  125. **    sactx        Sambar Server context
  126. **    saconn        Sambar Server connection
  127. **    saparams    RPC Parameters
  128. **    infop        Error parameters
  129. **
  130. **  Returns:
  131. **    SA_SUCCEED | SA_FAIL
  132. */
  133. SA_RETCODE SA_PUBLIC
  134. ipname_lookup(sactx, saconn, saparams, infop)
  135. SA_CTX        *sactx;
  136. SA_CONN        *saconn;
  137. SA_PARAMS    *saparams;
  138. SA_INT        *infop;
  139. {
  140. #ifndef    WIN32
  141.     return (SA_FAIL);
  142. #else
  143.     unsigned long    addr;
  144.     SA_INT            datalen;
  145.     SA_CHAR            *data;
  146.     struct hostent    *hent;
  147.  
  148.     /* Get the ip address to lookup                                        */
  149.     if ((sa_param(sactx, saparams, "ipaddr", &data, &datalen) != SA_SUCCEED) ||
  150.         (datalen == 0))
  151.     {
  152.         *infop = SA_E_INVALIDDATA;
  153.         return (SA_FAIL);
  154.     }
  155.  
  156.     addr = (int)inet_addr((char *)data);
  157.     if (addr == -1)
  158.     {
  159.         *infop = SA_E_INVALIDDATA;
  160.         return (SA_FAIL);
  161.     }
  162.  
  163.     hent = gethostbyaddr((char *)&addr, sizeof(addr), AF_INET);
  164.     if (hent != NULL)
  165.     {
  166.         if (sa_conn_send(saconn, hent->h_name, SA_NULLTERM) != SA_SUCCEED)
  167.             return (SA_FAIL);
  168.     }
  169.     else
  170.     {
  171.         if (sa_conn_send(saconn, "unknown", SA_NULLTERM) != SA_SUCCEED)
  172.             return (SA_FAIL);
  173.     }
  174.  
  175.     return (SA_SUCCEED);
  176. #endif    /* WIN32 */
  177. }
  178.  
  179. /*
  180. **  WHOIS_LOOKUP
  181. **
  182. **    Perform a whois search.
  183. **
  184. **  Parameters:
  185. **    sactx        Sambar Server context
  186. **    saconn        Sambar Server connection
  187. **    saparams    RPC Parameters
  188. **    infop        Error parameters
  189. **
  190. **  Returns:
  191. **    SA_SUCCEED | SA_FAIL
  192. */
  193. SA_RETCODE SA_PUBLIC
  194. whois_lookup(sactx, saconn, saparams, infop)
  195. SA_CTX        *sactx;
  196. SA_CONN        *saconn;
  197. SA_PARAMS    *saparams;
  198. SA_INT        *infop;
  199. {
  200. #ifndef    WIN32
  201.     return (SA_FAIL);
  202. #else    
  203.     int                    timeo;
  204.     SA_INT                buflen;
  205.     SA_INT                datalen;
  206.     SA_BOOL                finished;
  207.     SOCKET                sock;
  208.     unsigned long        addr;
  209.     SA_CHAR                *data;
  210.     SA_CHAR                *nameserver;
  211.     struct sockaddr_in    sin;
  212.     struct hostent        *hent;
  213.     SA_CHAR                buffer[1024];
  214.  
  215.     /* Get the (optional) name server to use.                            */
  216.     datalen = 0;
  217.     (void)sa_param(sactx, saparams, "nameserver", &data, &datalen);
  218.     if (datalen > 0)
  219.         nameserver = data;
  220.     else
  221.         nameserver = WHOIS_SERVER;
  222.  
  223.     /* Get the site name                                                */
  224.     if ((sa_param(sactx, saparams, "sitename", &data, &datalen) != SA_SUCCEED)
  225.         || (datalen == 0))
  226.     {
  227.         *infop = SA_E_INVALIDDATA;
  228.         return (SA_FAIL);
  229.     }
  230.  
  231.     /* Get the WHOIS server address for the query                        */
  232.     addr = (int)inet_addr(nameserver);
  233.     if (addr == -1)
  234.     {
  235.         /* Try gethostbyname()                                            */
  236.         hent = gethostbyname(nameserver);
  237.         if (hent == NULL)
  238.         {
  239.             *infop = SA_E_INVALIDDATA;
  240.             return (SA_FAIL);
  241.         }
  242.  
  243.         addr = (int)hent->h_addr;
  244.     }
  245.  
  246.     hent = gethostbyaddr((char *)&addr, sizeof(addr), AF_INET);
  247.     if (hent == NULL)
  248.     {
  249.         if (sa_conn_send(saconn, "The WHOIS server is not available.", 
  250.             SA_NULLTERM) != SA_SUCCEED)
  251.         {
  252.             return (SA_FAIL);
  253.         }
  254.  
  255.         return (SA_SUCCEED);
  256.     }
  257.  
  258.     /* Create a socket                                                     */
  259.     sock = socket(hent->h_addrtype, SOCK_STREAM, 0);
  260.     if (sock == INVALID_SOCKET)
  261.     {
  262.         if (sa_conn_send(saconn, "The WHOIS server is not available.", 
  263.             SA_NULLTERM) != SA_SUCCEED)
  264.         {
  265.             return (SA_FAIL);
  266.         }
  267.  
  268.         return (SA_SUCCEED);
  269.     }
  270.  
  271.     /* Connect to the WHOIS server                                        */
  272.     sin.sin_family = AF_INET;
  273.     sin.sin_port = htons((u_short)WHOIS_PORT);
  274.     memcpy(&sin.sin_addr, hent->h_addr, hent->h_length);
  275.  
  276.     /* Now, connect to that WHOIS server                                */
  277.     if (connect(sock, (struct sockaddr *)&sin, sizeof(sin)) < 0) 
  278.     {
  279.         closesocket(sock);
  280.  
  281.         if (sa_conn_send(saconn, "The WHOIS server is not available.", 
  282.             SA_NULLTERM) != SA_SUCCEED)
  283.         {
  284.             return (SA_FAIL);
  285.         }
  286.  
  287.         return (SA_SUCCEED);
  288.     }
  289.  
  290.      /* Set the socket recv timeout to 10 seconds            */
  291.      timeo = 10000;
  292.      (void)setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (const char *)&timeo,
  293.          sizeof(int));
  294.  
  295.     /* Send the request.                                                */
  296.     sprintf(buffer, "%s\r\n", data);
  297.     buflen = strlen(buffer);
  298.  
  299.     if (send(sock, buffer, buflen, 0) != buflen)
  300.     {
  301.         closesocket(sock);
  302.  
  303.         if (sa_conn_send(saconn, "The WHOIS server is not available.", 
  304.             SA_NULLTERM) != SA_SUCCEED)
  305.         {
  306.             return (SA_FAIL);
  307.         }
  308.  
  309.         return (SA_SUCCEED);
  310.     }
  311.  
  312.     /* Receive the response.                                            */
  313.     finished = 0;
  314.     while (!finished)
  315.     {
  316.         buflen = recv(sock, buffer, 1024, 0);
  317.         if ((buflen < 0) && (errno == EINTR))
  318.             continue;
  319.  
  320.         if (buflen == SOCKET_ERROR)
  321.         {
  322.             closesocket(sock);
  323.             return (SA_FAIL);
  324.         }
  325.  
  326.         if (buflen > 0)
  327.         {
  328.             if (sa_conn_send(saconn, buffer, buflen) != SA_SUCCEED)
  329.             {
  330.                 closesocket(sock);
  331.                 return (SA_FAIL);
  332.             }
  333.         }
  334.         else
  335.         {
  336.             finished = 1;
  337.         }
  338.     }
  339.  
  340.     closesocket(sock);
  341.  
  342.     if (!finished)
  343.     {
  344.         if (sa_conn_send(saconn, "The WHOIS server is not available.", 
  345.             SA_NULLTERM) != SA_SUCCEED)
  346.         {
  347.             return (SA_FAIL);
  348.         }
  349.     }
  350.  
  351.     return (SA_SUCCEED);
  352. #endif    /* WIN32 */
  353. }
  354.  
  355. /*
  356. **  FINGER_LOOKUP
  357. **
  358. **    Perform a 'finger' search.
  359. **
  360. **  Parameters:
  361. **    sactx        Sambar Server context
  362. **    saconn        Sambar Server connection
  363. **    saparams    RPC Parameters
  364. **    infop        Error parameters
  365. **
  366. **  Returns:
  367. **    SA_SUCCEED | SA_FAIL
  368. */
  369. SA_RETCODE SA_PUBLIC
  370. finger_lookup(sactx, saconn, saparams, infop)
  371. SA_CTX        *sactx;
  372. SA_CONN        *saconn;
  373. SA_PARAMS    *saparams;
  374. SA_INT        *infop;
  375. {
  376. #ifndef    WIN32
  377.     return (SA_FAIL);
  378. #else
  379.     int                    timeo;
  380.     SA_INT                buflen;
  381.     SA_INT                userlen;
  382.     SA_INT                hostlen;
  383.     SA_BOOL                finished;
  384.     SOCKET                sock;
  385.     SA_CHAR                *host;
  386.     SA_CHAR                *user;
  387.     struct sockaddr_in    sin;
  388.     struct hostent        *hent;
  389.     SA_CHAR                buffer[1024];
  390.  
  391.     /* Get the host where the finger server is running                    */
  392.     if ((sa_param(sactx, saparams, "host", &host, &hostlen) != SA_SUCCEED)
  393.         || (hostlen == 0))
  394.     {
  395.         *infop = SA_E_INVALIDDATA;
  396.         return (SA_FAIL);
  397.     }
  398.  
  399.     (void)sa_param(sactx, saparams, "user", &user, &userlen);
  400.  
  401.     /* Get the finger server address                                */
  402.     hent = gethostbyname(host);
  403.     if (hent == NULL)
  404.     {
  405.         sprintf(buffer, "Unable to locate the specified host: '%s'", host);
  406.         if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  407.             return (SA_FAIL);
  408.  
  409.         return (SA_SUCCEED);
  410.     }
  411.  
  412.     /* Open a socket                                                     */
  413.     sock = socket(PF_INET, SOCK_STREAM, 0);
  414.     if (sock == INVALID_SOCKET)
  415.     {
  416.         if (sa_conn_send(saconn, "Unable to create a new TCP/IP socket.", 
  417.             SA_NULLTERM) != SA_SUCCEED)
  418.         {
  419.             return (SA_FAIL);
  420.         }
  421.  
  422.         return (SA_SUCCEED);
  423.     }
  424.  
  425.     /* Connect to the finger server                                        */
  426.     sin.sin_family = AF_INET;
  427.     sin.sin_port = htons((u_short)IPPORT_FINGER);
  428.     memcpy(&sin.sin_addr, hent->h_addr, hent->h_length);
  429.  
  430.     /* Now, connect to that WHOIS server                                */
  431.     if (connect(sock, (struct sockaddr *)&sin, sizeof(sin)) < 0) 
  432.     {
  433.         closesocket(sock);
  434.         sprintf(buffer, "Unable to connect to the host: '%s'", host);
  435.         if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  436.             return (SA_FAIL);
  437.  
  438.         return (SA_SUCCEED);
  439.     }
  440.  
  441.      /* Set the socket recv timeout to 10 seconds            */
  442.      timeo = 10000;
  443.      (void)setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (const char *)&timeo,
  444.          sizeof(int));
  445.  
  446.     /* Send the request.                                                */
  447.     sprintf(buffer, "%s\r\n", userlen > 0 ? user : "");
  448.     buflen = strlen(buffer);
  449.  
  450.     if (send(sock, buffer, buflen, 0) != buflen)
  451.     {
  452.         closesocket(sock);
  453.  
  454.         sprintf(buffer, "Failure connecting to finger daemon at: '%s'", host);
  455.         if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  456.             return (SA_FAIL);
  457.  
  458.         return (SA_SUCCEED);
  459.     }
  460.  
  461.     /* Receive the response.                                            */
  462.     finished = 0;
  463.     while (!finished)
  464.     {
  465.         buflen = recv(sock, buffer, 1024, 0);
  466.         if ((buflen < 0) && (errno == EINTR))
  467.             continue;
  468.  
  469.         if (buflen == SOCKET_ERROR)
  470.         {
  471.             closesocket(sock);
  472.             return (SA_FAIL);
  473.         }
  474.  
  475.         if (buflen > 0)
  476.         {
  477.             if (sa_conn_send(saconn, buffer, buflen) != SA_SUCCEED)
  478.             {
  479.                 closesocket(sock);
  480.                 return (SA_FAIL);
  481.             }
  482.         }
  483.         else
  484.         {
  485.             finished = 1;
  486.         }
  487.     }
  488.  
  489.     closesocket(sock);
  490.  
  491.     if (!finished)
  492.     {
  493.         sprintf(buffer, "Finger daemon at host '%s' is not available.", host);
  494.         if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  495.             return (SA_FAIL);
  496.     }
  497.  
  498.     return (SA_SUCCEED);
  499. #endif    /* WIN32 */
  500. }
  501.