dial.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. #include <stdlib.h>
  2. #include <sys/types.h>
  3. #include <string.h>
  4. #include <fcntl.h>
  5. #include <stdio.h>
  6. #include <unistd.h>
  7. #include <libnet.h>
  8. #define NAMELEN 28
  9. static int
  10. call(char *clone, char *dest, int *cfdp, char *dir, char *local)
  11. {
  12. int fd, cfd;
  13. int n;
  14. char name[3*NAMELEN+5];
  15. char data[3*NAMELEN+10];
  16. char *p;
  17. cfd = open(clone, O_RDWR);
  18. if(cfd < 0)
  19. return -1;
  20. /* get directory name */
  21. n = read(cfd, name, sizeof(name)-1);
  22. if(n < 0){
  23. close(cfd);
  24. return -1;
  25. }
  26. name[n] = 0;
  27. p = strrchr(clone, '/');
  28. *p = 0;
  29. if(dir)
  30. sprintf(dir, "%.*s/%.*s", 2*NAMELEN+1, clone, NAMELEN, name);
  31. sprintf(data, "%.*s/%.*s/data", 2*NAMELEN+1, clone, NAMELEN, name);
  32. /* set local side (port number, for example) if we need to */
  33. if(local)
  34. sprintf(name, "connect %.*s %.*s", 2*NAMELEN, dest, NAMELEN, local);
  35. else
  36. sprintf(name, "connect %.*s", 2*NAMELEN, dest);
  37. /* connect */
  38. if(write(cfd, name, strlen(name)) < 0){
  39. close(cfd);
  40. return -1;
  41. }
  42. /* open data connection */
  43. fd = open(data, O_RDWR);
  44. if(fd < 0){
  45. close(cfd);
  46. return -1;
  47. }
  48. if(cfdp)
  49. *cfdp = cfd;
  50. else
  51. close(cfd);
  52. return fd;
  53. }
  54. int
  55. dial(char *dest, char *local, char *dir, int *cfdp)
  56. {
  57. char net[128];
  58. char netdir[128], csname[NETPATHLEN], *slp;
  59. char clone[NAMELEN+12];
  60. char *p;
  61. int n;
  62. int fd;
  63. int rv;
  64. /* go for a standard form net!... */
  65. p = strchr(dest, '!');
  66. if(p == 0){
  67. sprintf(net, "net!%.*s", sizeof(net)-5, dest);
  68. } else {
  69. strncpy(net, dest, sizeof(net)-1);
  70. net[sizeof(net)-1] = 0;
  71. }
  72. slp = strrchr(net, '/');
  73. if (slp != 0) {
  74. *slp++ = '\0';
  75. strcpy(netdir, net);
  76. memmove(net, slp, strlen(slp)+1);
  77. } else
  78. strcpy(netdir, "/net");
  79. /* call the connection server */
  80. sprintf(csname, "%s/cs", netdir);
  81. fd = open(csname, O_RDWR);
  82. if(fd < 0){
  83. /* no connection server, don't translate */
  84. p = strchr(net, '!');
  85. *p++ = 0;
  86. sprintf(clone, "%s/%s/clone", netdir, net);
  87. return call(clone, p, cfdp, dir, local);
  88. }
  89. /*
  90. * send dest to connection to translate
  91. */
  92. if(write(fd, net, strlen(net)) < 0){
  93. close(fd);
  94. return -1;
  95. }
  96. /*
  97. * loop through each address from the connection server till
  98. * we get one that works.
  99. */
  100. rv = -1;
  101. lseek(fd, 0, 0);
  102. while((n = read(fd, net, sizeof(net) - 1)) > 0){
  103. net[n] = 0;
  104. p = strchr(net, ' ');
  105. if(p == 0)
  106. continue;
  107. *p++ = 0;
  108. rv = call(net, p, cfdp, dir, local);
  109. if(rv >= 0)
  110. break;
  111. }
  112. close(fd);
  113. return rv;
  114. }