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