wrap.c
上传用户:sddyfurun
上传日期:2007-01-04
资源大小:525k
文件大小:21k
源码类别:

代理服务器

开发平台:

Unix_Linux

  1. /* Copyright (c) 1995,1996,1997 NEC Corporation.  All rights reserved.       */
  2. /*                                                                           */
  3. /* The redistribution, use and modification in source or binary forms of     */
  4. /* this software is subject to the conditions set forth in the copyright     */
  5. /* document ("Copyright") included with this distribution.                   */
  6. /*
  7.  * $Id: wrap.c,v 1.53.2.1.2.6 1998/11/04 00:03:28 steve Exp $
  8.  */
  9. #define HIDEORIG
  10. #include "socks5p.h"
  11. #include "protocol.h"
  12. #include "buffer.h"
  13. #include "addr.h"
  14. #include "wrap.h"
  15. #include "wrap_tcp.h"
  16. #include "wrap_udp.h"
  17. #include "confutil.h"
  18. #include "cache.h"
  19. #include "hostname.h"
  20. #include "log.h"
  21. int lsInRLDFunctions = 0;
  22. int lsInWrapFunction = 0;
  23. /* This macro (w/o do...while(0)) scares me, but it gets rid of a lot of     */
  24. /* warnings with Solaris's cc.                                               */
  25. #define DLRETURN(var, rval, exp) (rval) = (exp); (var) = 0; return (rval)
  26. static int lsSocketType(S5IOHandle fd, const ss *name) {
  27.     int optval, optlen = sizeof(int), slen = sizeof(S5NetAddr), eno = GETERRNO();
  28.     S5NetAddr na;
  29.     memset(&na, 0, sizeof(na));
  30.     if (REAL(getsockname)(fd, &na.sa, &slen) < 0) return -1;
  31.     if ((!ISINET(&na.sa) && !ISUNSPEC(&na.sa)) || (ISUNSPEC(&na.sa) && (!name || !ISINET(name)))) return -1;
  32.     if (getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&optval, &optlen) < 0) return -1;
  33.     SETERRNO(eno);
  34.     return optval;
  35. }
  36. /* wrapper around the shutdown system call.  This could be kind of tricky:   */
  37. /* may be we should keep track of SHUTDOWN status as read or write may be    */
  38. /* still allowed even after shutdown, depending on the value of howto XXX    */
  39. int LIBPREFIX(shutdown)(S5IOHandle fd, int howto) {
  40. #ifdef FOR_SHARED_LIBRARY
  41.     if (lsInRLDFunctions || lsInWrapFunction) return REAL(shutdown)(fd, howto);
  42. #endif
  43.     if (!lsConnectionCached(fd)) return REAL(shutdown)(fd, howto);
  44.     lsInWrapFunction = 1;
  45.     LIBPREFIX2(init)("libsocks5");
  46.     S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(12), 0, "SOCKS shutdown: FAKE");
  47.     lsConnectionDel(fd);
  48.     lsInWrapFunction = 0;
  49.     return REAL(shutdown)(fd, howto);
  50. }
  51. /* wrapper around the connect system call.                                   */
  52. int LIBPREFIX(connect)(S5IOHandle sd, CONST ss *name, int namelen) {
  53.     int rval;
  54. #ifdef FOR_SHARED_LIBRARY
  55.     if (lsInRLDFunctions || lsInWrapFunction) return REAL(connect)(sd, (ss *)name, namelen);
  56. #endif
  57.     lsInWrapFunction = 1;
  58.     LIBPREFIX2(init)("libsocks5");
  59.     switch (lsSocketType(sd, name)) {
  60.     case SOCK_DGRAM:
  61. S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(12), 0, "SOCKS connect: FAKE");
  62.         DLRETURN(lsInWrapFunction, rval, lsUdpConnect(sd, name, namelen));
  63.     case SOCK_STREAM:
  64. S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(12), 0, "SOCKS connect: FAKE");
  65.         DLRETURN(lsInWrapFunction, rval, lsTcpConnect(sd, name, namelen));
  66.     default:
  67.         S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(12), 0, "SOCKS connect: REAL");
  68.         DLRETURN(lsInWrapFunction, rval, REAL(connect)(sd, (ss *)name, namelen));
  69.     }
  70. }
  71. /* wrapper around the bind system call.                                      */
  72. int LIBPREFIX(bind)(S5IOHandle sd, CONST ss *name, int namelen) {
  73.     int rval;
  74. #ifdef FOR_SHARED_LIBRARY
  75.     if (lsInRLDFunctions || lsInWrapFunction) return REAL(bind)(sd, (ss *)name, namelen);
  76. #endif
  77.     lsInWrapFunction = 1;
  78.     LIBPREFIX2(init)("libsocks5");
  79.     switch (lsSocketType(sd, name)) {
  80.     case SOCK_STREAM:
  81. S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(12), 0, "SOCKS bind: FAKE");
  82.         DLRETURN(lsInWrapFunction, rval, lsTcpBind(sd, name, namelen));
  83.     case SOCK_DGRAM:
  84. S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(12), 0, "SOCKS bind: FAKE");
  85.         DLRETURN(lsInWrapFunction, rval, lsUdpBind(sd, name, namelen));
  86.     default:
  87. S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(12), 0, "SOCKS bind: REAL");
  88.         DLRETURN(lsInWrapFunction, rval, REAL(bind)(sd, (ss *)name, namelen));
  89.     }
  90. }
  91. /* wrapper around the getsockname system call.                               */
  92. int LIBPREFIX(getsockname)(S5IOHandle sd, struct sockaddr *name, int *namelen) {
  93.     int rval;
  94. #ifdef FOR_SHARED_LIBRARY
  95.     if (lsInRLDFunctions || lsInWrapFunction) return REAL(getsockname)(sd, name, namelen);
  96. #endif
  97.     if (!lsConnectionCached(sd)) return REAL(getsockname)(sd, name, namelen);
  98.     lsInWrapFunction = 1;
  99.     LIBPREFIX2(init)("libsocks5");
  100.     switch (lsSocketType(sd, NULL)) {
  101.     case SOCK_STREAM:
  102. S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(12), 0, "SOCKS getsockname: FAKE");
  103.         DLRETURN(lsInWrapFunction, rval, lsTcpGetsockname(sd, name, namelen));
  104.     case SOCK_DGRAM:
  105. S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(12), 0, "SOCKS getsockname: FAKE");
  106.         DLRETURN(lsInWrapFunction, rval, lsUdpGetsockname(sd, name, namelen));
  107.     default:
  108.         S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(12), 0, "SOCKS getsockname: REAL");
  109.         DLRETURN(lsInWrapFunction, rval, REAL(getsockname)(sd, name, namelen));
  110.     }
  111. }
  112. /* wrapper around the getpeername system call.                               */
  113. int LIBPREFIX(getpeername)(S5IOHandle sd, struct sockaddr *name, int *namelen) {
  114.     int rval;
  115. #ifdef FOR_SHARED_LIBRARY
  116.     if (lsInRLDFunctions || lsInWrapFunction) return REAL(getpeername)(sd, name, namelen);
  117. #endif
  118.     if (!lsConnectionCached(sd)) return REAL(getpeername)(sd, name, namelen);
  119.     lsInWrapFunction = 1;
  120.     LIBPREFIX2(init)("libsocks5");
  121.     switch (lsSocketType(sd, NULL)) {
  122.     case SOCK_DGRAM:
  123. S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(12), 0, "SOCKS getpeername: FAKE");
  124.         DLRETURN(lsInWrapFunction, rval, lsUdpGetpeername(sd, name, namelen)); 
  125.     case SOCK_STREAM:
  126. S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(12), 0, "SOCKS getpeername: FAKE");
  127.         DLRETURN(lsInWrapFunction, rval, lsTcpGetpeername(sd, name, namelen));
  128.     default:
  129.         S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(12), 0, "SOCKS getpeername: REAL");
  130.         DLRETURN(lsInWrapFunction, rval, REAL(getpeername)(sd, name, namelen));
  131.     }
  132. }
  133. /* wrapper around the send system call.                                      */
  134. IORETTYPE LIBPREFIX(send)(S5IOHandle sd, const IOPTRTYPE msg, IOLENTYPE len, int flags) {
  135.     int rval;
  136. #ifdef FOR_SHARED_LIBRARY
  137.     if (lsInRLDFunctions || lsInWrapFunction) return REAL(send)(sd, msg, len, flags);
  138. #endif
  139.     lsInWrapFunction = 1;
  140.     LIBPREFIX2(init)("libsocks5");
  141.     switch (lsSocketType(sd, NULL)) {
  142.     case SOCK_DGRAM:
  143. S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(12), 0, "SOCKS write: FAKE: Udp");
  144.         DLRETURN(lsInWrapFunction, rval, lsUdpSend(sd, msg, len, flags));
  145.     case SOCK_STREAM:
  146. S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(12), 0, "SOCKS write: FAKE: Tcp");
  147.         DLRETURN(lsInWrapFunction, rval, lsTcpSend(sd, msg, len, flags));
  148.     default:
  149. S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(12), 0, "SOCKS send: REAL: Wrong type");
  150.         DLRETURN(lsInWrapFunction, rval, -1);
  151.     }
  152. }
  153. /* wrapper around the sendto system call.                                    */
  154. IORETTYPE LIBPREFIX(sendto)(S5IOHandle sd, const IOPTRTYPE msg, IOLENTYPE len, int flags, struct sockaddr *to, int tolen) {
  155.     int rval;
  156. #ifdef FOR_SHARED_LIBRARY
  157.     if (lsInRLDFunctions || lsInWrapFunction) return REAL(sendto)(sd, msg, len, flags, to, tolen);
  158. #endif
  159.     lsInWrapFunction = 1;
  160.     LIBPREFIX2(init)("libsocks5");
  161.     switch (lsSocketType(sd, NULL)) {
  162.     case SOCK_DGRAM:
  163. S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(12), 0, "SOCKS sendto: FAKE: Udp");
  164.         DLRETURN(lsInWrapFunction, rval, lsUdpSendto(sd, msg, len, flags, to, tolen));
  165.     case SOCK_STREAM:
  166. S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(12), 0, "SOCKS sendto: FAKE: Tcp");
  167.         DLRETURN(lsInWrapFunction, rval, lsTcpSend(sd, msg, len, flags));
  168.     default:
  169. S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(12), 0, "SOCKS sendto: REAL: Wrong type");
  170.         DLRETURN(lsInWrapFunction, rval, -1);
  171.     }
  172. }
  173. /* wrapper around the recv system call.                                      */
  174. IORETTYPE LIBPREFIX(recv)(S5IOHandle sd, IOPTRTYPE msg, IOLENTYPE len, int flags) {
  175.     int rval;
  176.     
  177. #ifdef FOR_SHARED_LIBRARY
  178.     if (lsInRLDFunctions || lsInWrapFunction) return REAL(recv)(sd, msg, len, flags);
  179. #endif
  180.     lsInWrapFunction = 1;
  181.     LIBPREFIX2(init)("libsocks5");
  182.     switch (lsSocketType(sd, NULL)) {
  183.     case SOCK_DGRAM:
  184. S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(12), 0, "SOCKS recv: FAKE: Udp");
  185.         DLRETURN(lsInWrapFunction, rval, lsUdpRecvfrom(sd, msg, len, flags, NULL, NULL, 1));
  186.     case SOCK_STREAM:
  187. S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(12), 0, "SOCKS recv: FAKE: Tcp");
  188.         DLRETURN(lsInWrapFunction, rval, lsTcpRecv(sd, msg, len, flags));
  189.     default:
  190. S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(12), 0, "SOCKS recv: REAL: Wrong type");
  191. SETSOCKETERROR(EBADF);
  192.         DLRETURN(lsInWrapFunction, rval, -1);
  193.     }
  194. }
  195. /* wrapper around the recvfrom system call.                                  */
  196. IORETTYPE 
  197. LIBPREFIX(recvfrom)(S5IOHandle sd, IOPTRTYPE msg, IOLENTYPE len, int flags, ss *from, int *fromlen) 
  198. {
  199.     int rval;
  200. #ifdef FOR_SHARED_LIBRARY
  201.     if (lsInRLDFunctions || lsInWrapFunction) return REAL(recvfrom)(sd, msg, len, flags, from, fromlen);
  202. #endif
  203.     lsInWrapFunction = 1;
  204.     LIBPREFIX2(init)("libsocks5");
  205.     switch (lsSocketType(sd, NULL)) {
  206. case SOCK_DGRAM:
  207. S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(12), 0,
  208. "SOCKS recv: FAKE: Udp");
  209. DLRETURN(lsInWrapFunction, rval, 
  210. lsUdpRecvfrom(sd, msg, len, flags, from, fromlen, 0));
  211.      case SOCK_STREAM:
  212.          S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(12), 0, "SOCKS recv: FAKE: Tcp");
  213.          DLRETURN(lsInWrapFunction, rval, 
  214. lsTcpRecvfrom(sd, msg, len, flags, from, fromlen));
  215.      default:
  216. S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(12), 0,
  217. "SOCKS recv: REAL: Wrong type");
  218. SETSOCKETERROR(EBADF);
  219. DLRETURN(lsInWrapFunction, rval, -1);
  220.     }
  221. }
  222. #ifdef HAVE_SENDMSG
  223. /* wrapper around the recvmsg system call.                                  */
  224. IORETTYPE
  225. LIBPREFIX(recvmsg)(S5IOHandle sd, ms *msg, int flags)
  226. {
  227. int rval;
  228.  
  229. #ifdef FOR_SHARED_LIBRARY
  230.     if(lsInRLDFunctions || lsInWrapFunction)
  231.      return REAL(recvmsg)(sd, msg, flags);
  232. #endif
  233.  
  234.     lsInWrapFunction = 1;
  235.     LIBPREFIX2(init)("libsocks5");
  236.  
  237.     switch (lsSocketType(sd, NULL)) {
  238. case SOCK_DGRAM:
  239.             S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(12), 0,
  240. "SOCKS recvmsg: FAKE: Udp");
  241.             DLRETURN(lsInWrapFunction, rval, lsUdpRecvmsg(sd, msg, flags));
  242.         case SOCK_STREAM:
  243.             S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(12), 0,
  244. "SOCKS recvmsg: FAKE: Tcp");
  245.             DLRETURN(lsInWrapFunction, rval, lsTcpRecvmsg(sd, msg, flags));
  246.         default:
  247.             S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(12), 0,
  248. "SOCKS recvmsg: REAL: Wrong type");
  249. SETSOCKETERROR(EBADF);
  250.             DLRETURN(lsInWrapFunction, rval, -1);
  251.     }
  252. }
  253. /* wrapper around the sendmsg system call.                                  */
  254. IORETTYPE
  255. LIBPREFIX(sendmsg)(S5IOHandle sd,ms *msg, int flags)
  256. {
  257. int rval;
  258.  
  259. #ifdef FOR_SHARED_LIBRARY
  260.     if(lsInRLDFunctions || lsInWrapFunction)
  261.      return REAL(sendmsg)(sd, msg, flags);
  262. #endif
  263.  
  264.     lsInWrapFunction = 1;
  265.     LIBPREFIX2(init)("libsocks5");
  266.  
  267.     switch (lsSocketType(sd, NULL)) {
  268.         case SOCK_DGRAM:
  269.             S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(12), 0,
  270. "SOCKS sendmsg: FAKE: Udp");
  271.             DLRETURN(lsInWrapFunction, rval, lsUdpSendmsg(sd, msg, flags));
  272.         case SOCK_STREAM:
  273.             S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(12), 0,
  274. "SOCKS sendmsg: FAKE: Tcp");
  275.             DLRETURN(lsInWrapFunction, rval, lsTcpSendmsg(sd, msg, flags));
  276.         default:
  277.             S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(12), 0,
  278. "SOCKS sendmsg: REAL: Wrong type");
  279. SETSOCKETERROR(EBADF);
  280.             DLRETURN(lsInWrapFunction, rval, -1);
  281.     }
  282. }
  283. #endif  /* HAVE_SENDMSG */
  284. /* wrapper around the close system call.  Not strictly necessary, but it     */
  285. /* cleans up some things, so it is kind of nice to call...                   */
  286. int LIBPREFIX(close)(S5IOHandle fd) {
  287.     int rval;
  288. #ifdef FOR_SHARED_LIBRARY
  289.     if (lsInRLDFunctions || lsInWrapFunction) return REAL(close)(fd);
  290. #endif
  291.     if (!lsConnectionCached(fd)) return REAL(close)(fd);
  292.     lsInWrapFunction = 1;
  293.     LIBPREFIX2(init)("libsocks5");
  294.     S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(12), 0, "SOCKS close: FAKE");
  295.     if (getenv("SOCKS5_PRESERVE_STDERR") && fd == STDERR_FILENO) {
  296. DLRETURN(lsInWrapFunction, rval, 0);
  297.     }
  298.     lsConnectionDel(fd);
  299.     DLRETURN(lsInWrapFunction, rval, REAL(close)(fd));
  300. }
  301. /* wrapper around the fclose stdio library function...See comment for close. */
  302. int LIBPREFIX(fclose)(FILE *fp) {
  303.     int rval;
  304. #ifdef FOR_SHARED_LIBRARY
  305.     if (lsInRLDFunctions || lsInWrapFunction || fp == NULL) return REAL(fclose)(fp);
  306. #endif
  307.     if (!lsConnectionCached(fileno(fp))) return REAL(fclose)(fp);
  308.     lsInWrapFunction = 1;
  309.     LIBPREFIX2(init)("libsocks5");
  310.     S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(12), 0, "SOCKS fclose: FAKE");
  311.     if (getenv("SOCKS5_PRESERVE_STDERR") && fileno(fp) == STDERR_FILENO) {
  312. DLRETURN(lsInWrapFunction, rval, 0);
  313.     }
  314.     lsConnectionDel(fileno(fp));
  315.     DLRETURN(lsInWrapFunction, rval, REAL(fclose)(fp));
  316. }
  317. IORETTYPE LIBPREFIX(write)(S5IOHandle sd, const IOPTRTYPE buf, IOLENTYPE buflen) {
  318.     int rval;
  319. #ifdef FOR_SHARED_LIBRARY
  320.     if (lsInRLDFunctions || lsInWrapFunction) return REAL(write)(sd, buf, buflen);
  321. #endif
  322.     lsInWrapFunction = 1;
  323.     LIBPREFIX2(init)("libsocks5");
  324.     switch (lsSocketType(sd, NULL)) {
  325.     case SOCK_DGRAM:
  326. S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(12), 0, "SOCKS write: FAKE: Udp");
  327. DLRETURN(lsInWrapFunction, rval, lsUdpSend(sd, buf, buflen, 0));
  328.     case SOCK_STREAM:
  329. S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(12), 0, "SOCKS write: FAKE: Tcp");
  330. DLRETURN(lsInWrapFunction, rval, lsTcpSend(sd, buf, buflen, 0));
  331.     default:
  332. S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(12), 0, "SOCKS write: REAL: Wrong type");
  333. DLRETURN(lsInWrapFunction, rval, REAL(write)(sd, buf, buflen));
  334.     }
  335. }
  336. IORETTYPE LIBPREFIX(read)(S5IOHandle sd, IOPTRTYPE buf, IOLENTYPE buflen) {
  337.     int rval;
  338.     
  339. #ifdef FOR_SHARED_LIBRARY
  340.     if (lsInRLDFunctions || lsInWrapFunction) return REAL(read)(sd, buf, buflen);
  341. #endif
  342.     lsInWrapFunction = 1;
  343.     LIBPREFIX2(init)("libsocks5");
  344.     switch (lsSocketType(sd, NULL)) {
  345.     case SOCK_DGRAM:
  346. S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(12), 0, "SOCKS read: FAKE: Udp");
  347. DLRETURN(lsInWrapFunction, rval, lsUdpRecvfrom(sd, buf, buflen, 0, NULL, NULL, 1));
  348.     case SOCK_STREAM:
  349. S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(12), 0, "SOCKS read: FAKE: Tcp");
  350. DLRETURN(lsInWrapFunction, rval, lsTcpRecv(sd, buf, buflen, 0));
  351.     default:
  352. S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(12), 0, "SOCKS read: REAL: Wrong type");
  353. DLRETURN(lsInWrapFunction, rval, REAL(read)(sd, buf, buflen));
  354.     }
  355. }
  356. S5IOHandle LIBPREFIX(dup)(S5IOHandle sd) {
  357.     lsSocksInfo *pcon, *ncon, *q;
  358.     lsProxyInfo *pri;
  359.     S5IOHandle s2;
  360. #ifdef FOR_SHARED_LIBRARY
  361.     if (lsInRLDFunctions || lsInWrapFunction) return REAL(dup)(sd);
  362. #endif
  363.     if (!lsConnectionCached(sd)) return REAL(dup)(sd);
  364.     lsInWrapFunction = 1;
  365.     LIBPREFIX2(init)("libsocks5");
  366.     /* Solaris (who knows why) occasionally gives you back a different type  */
  367.     /* of file descriptor after a DUP (e.g. SOCK_STREAM vs SOCK_DGRAM).  It  */
  368.     /* seems to mistakenly leave whatever label was there beforehand.  So,   */
  369.     /* we'll dup2 over a socket that we know is the right type instead...    */
  370.     /*                                                                       */
  371.     /* XXX Proposed new fix - Not tested - blob                              */
  372. #if defined(sun) && defined(__svr4__)
  373.     {
  374.      S5IOHandle tmpsd;
  375. int type = lsSocketType(sd, NULL);
  376.      if (type == -1 || (tmpsd = socket(AF_INET, type, 0)) == S5InvalidIOHandle) {
  377.     s2 = REAL(dup)(sd);
  378. } else if ((s2 = REAL(dup2)(sd, tmpsd)) == S5InvalidIOHandle) {
  379.          REAL(close)(tmpsd);
  380. }
  381.     }
  382. #else
  383.     s2 = REAL(dup)(sd);
  384. #endif
  385.     if (s2 == S5InvalidIOHandle) {
  386. S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(12), 0, "SOCKS dup: dup failed: %m");
  387.      lsInWrapFunction = 0;
  388. return S5InvalidIOHandle;
  389.     }
  390.     
  391.     if ((pcon = lsConnectionFind(sd)) == NULL) {
  392. S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(12), 0, "SOCKS dup: no connection found");
  393.      lsInWrapFunction = 0;
  394. return s2;
  395.     }
  396.     if ((ncon = lsConnectionFind(s2)) != NULL) {
  397. S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(12), 0, "SOCKS dup: deleting invalid connection found");
  398. lsConnectionDel(s2);
  399.     }
  400.     if ((ncon = lsConnectionAdd(s2)) == NULL) {
  401. S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(12), 0, "SOCKS dup: couldn't add connection");
  402. REAL(close)(s2);
  403. SETSOCKETERROR(EMFILE);
  404.      lsInWrapFunction = 0;
  405. return S5InvalidIOHandle;
  406.     }
  407.     q = ncon->next;
  408.     *ncon = *pcon;
  409.     ncon->fd = s2;
  410.     ncon->next = q;
  411.     for (pri = ncon->pri; pri; pri = pri->next) pri->refcount++;
  412.     S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(12), 0, "SOCKS dup: done");
  413.     lsInWrapFunction = 0;
  414.     return s2;
  415. }
  416. S5IOHandle LIBPREFIX(dup2)(S5IOHandle sd, S5IOHandle s2) {
  417.     lsSocksInfo *pcon, *ncon, *q;
  418.     lsProxyInfo *pri;
  419. #ifdef FOR_SHARED_LIBRARY
  420.     if (lsInRLDFunctions || lsInWrapFunction) return REAL(dup2)(sd, s2);
  421. #endif
  422.     if (!lsConnectionCached(sd)) return REAL(dup2)(sd, s2);
  423.     lsInWrapFunction = 1;
  424.     LIBPREFIX2(init)("libsocks5");
  425.     if (getenv("SOCKS5_PRESERVE_STDERR") && s2 == STDERR_FILENO) {
  426. S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(12), 0, "SOCKS dup2: leaving stderr alone (by request)");
  427.      lsInWrapFunction = 0;
  428. return s2;
  429.     }
  430.     if ((s2 = REAL(dup2)(sd, s2)) == S5InvalidIOHandle) {
  431. S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(12), 0, "SOCKS dup2: dup2 failed");
  432.      lsInWrapFunction = 0;
  433. return S5InvalidIOHandle;
  434.     }
  435.     
  436.     if ((pcon = lsConnectionFind(sd)) == NULL) {
  437. S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(12), 0, "SOCKS dup2: no connection found");
  438.      lsInWrapFunction = 0;
  439. return s2;
  440.     }
  441.     if ((ncon = lsConnectionFind(s2)) != NULL) {
  442. S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(12), 0, "SOCKS dup2: deleting invalid connection found");
  443. lsConnectionDel(s2);
  444.     }
  445.     if ((ncon = lsConnectionAdd(s2)) == NULL) {
  446. S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(12), 0, "SOCKS dup2: couldn't add connection");
  447. REAL(close)(s2);
  448. SETSOCKETERROR(EMFILE);
  449.      lsInWrapFunction = 0;
  450. return S5InvalidIOHandle;
  451.     }
  452.     q = ncon->next;
  453.     *ncon = *pcon;
  454.     ncon->fd = s2;
  455.     ncon->next = q;
  456.     for (pri = ncon->pri; pri; pri = pri->next) pri->refcount++;
  457.     S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(12), 0, "SOCKS dup2: done");
  458.     lsInWrapFunction = 0;
  459.     return s2;
  460. }
  461. struct tm *LIBPREFIX(localtime)(const time_t *clock) {
  462.     struct tm *rval;
  463. #ifdef FOR_SHARED_LIBRARY
  464.     if (lsInRLDFunctions || lsInWrapFunction) return REAL(localtime)(clock);
  465. #endif
  466.     lsInWrapFunction = 1;
  467.     LIBPREFIX2(init)("libsocks5");
  468.     S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(12), 0, "SOCKS localtime: FAKE");
  469.     rval = REAL(localtime)(clock);
  470.     lsInWrapFunction = 0;
  471.     return rval;
  472. }
  473. void LIBPREFIX(longjmp)(jmp_buf env, int val) {
  474. #ifdef FOR_SHARED_LIBRARY
  475.     if (!lsInWrapHostname) lsInWrapFunction = 0;
  476. #endif
  477.     LIBPREFIX2(init)("libsocks5");
  478.     S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(12), 0, "SOCKS longjmp: FAKE");
  479.     REAL(longjmp)(env, val);
  480. }
  481. #ifndef FOR_SHARED_LIBRARY
  482. #ifdef HAVE_STDARG_H
  483. #include <stdarg.h>
  484. #define VA_START(a, b) va_start((a), (b))
  485. #define va_alist ...
  486. #define va_dcl
  487. #else
  488. #include <varargs.h>
  489. #define VA_START(a, b) va_start((a))
  490. #endif
  491. int LIBPREFIX(fprintf)(FILE *fp, const char *format, va_alist) va_dcl {
  492.     char buf[2048];
  493.     va_list pvar;
  494.     int retval, optval;
  495.     int optlen = sizeof(int);
  496.     S5IOHandle sd = fileno(fp);
  497. #ifdef HAVE_STDARG_H
  498.     va_start(pvar, format);
  499. #else
  500.     VA_START(pvar, format);
  501. #endif
  502.     if (getsockopt(fileno(fp), SOL_SOCKET, SO_TYPE, (char *)&optval, &optlen) < 0)
  503. retval = REAL(vfprintf)(fp, format, pvar);
  504.     else {
  505. vsprintf(buf, format, pvar);
  506. retval = LIBPREFIX(write)(sd, buf, strlen(buf));
  507.     }
  508.     va_end(pvar);
  509.     return retval;
  510. }
  511. int LIBPREFIX(vfprintf)(FILE *fp, const char *format, va_list pvar) {
  512.     char buf[2048];
  513.     int optval;
  514.     int optlen = sizeof(int);
  515.     S5IOHandle sd = fileno(fp);
  516.     if (getsockopt(fileno(fp), SOL_SOCKET, SO_TYPE, (char *)&optval, &optlen) < 0)
  517. return REAL(vfprintf)(fp, format, pvar);
  518.     else {
  519. vsprintf(buf, format, pvar);
  520. return LIBPREFIX(write)(sd, buf, strlen(buf));
  521.     }
  522. }
  523. int LIBPREFIX(getc)(FILE *fp) {
  524.     u_char c;
  525.     int optval;
  526.     int optlen = sizeof(int);
  527.     S5IOHandle sd = fileno(fp);
  528.     if (getsockopt(fileno(fp), SOL_SOCKET, SO_TYPE, (char *)&optval, &optlen) < 0)
  529. return REAL(getc)(fp);
  530.     else {
  531. if (LIBPREFIX(read)(sd, &c, 1) != 1) return EOF;
  532. return (int)c;
  533.     }
  534. }
  535. #endif /* FOR_SHARED_LIBRARY */