home *** CD-ROM | disk | FTP | other *** search
/ PC World 2000 April / PCWorld_2000-04_cd.bin / Komunik / Servery / sambar / _setup.1 / netutils.c < prev    next >
C/C++ Source or Header  |  1999-05-02  |  10KB  |  474 lines

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