pcmdserve.c 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385
  1. /*+-------------------------------------------------------------------------
  2. pcmdserve.c - ecu socket server procedure commands
  3. wht@wht.net
  4. Defined functions:
  5. pcmd_serve(param)
  6. pcmd_servewire(param)
  7. ptrace on
  8. dial 'ttyS42'
  9. AGAIN
  10. hangup
  11. serve 44553 # may set $i0 - $i6 and $s0
  12. ifnz $i0
  13. echo 'serve error '+%itos($i0)+': '+%errstr($i0) ; return
  14. # if we get this far,
  15. # $s0 is set to IP address of calling host as a string
  16. # $i1,$i2,$i3,$i4 are set to each individual byte of the IP address
  17. # $i5 is the calling port number
  18. # $i6 is the ecu file number for the socket
  19. echo 'Connect from host '+$s0+' port '+%itos($i5)
  20. echo -n 'Integer variable address breakout: '
  21. echo %itos($i1)+'.'+%itos($i2)+'.'+%itos($i3)+'.'+%itos($i4)+'.'
  22. #set $i0,$s0,$i1,$i2,$i3,$i4,$i5,$i6
  23. servewire $i6
  24. ifnz $i0
  25. echo 'servewire error '+%itos($i0)+': '+%errstr($i0) ; return
  26. goto AGAIN
  27. --------------------------------------------------------------------------*/
  28. /*+:EDITS:*/
  29. /*:04-26-2000-11:16-wht@bob-RELEASE 4.42 */
  30. /*:04-02-1998-19:04-wht@kepler-increase tty read size */
  31. /*:03-31-1998-18:33-wht@kepler-creation */
  32. #include "ecu.h"
  33. #if defined(CFG_TelnetServer)
  34. #include "ecuerror.h"
  35. #include "termecu.h"
  36. #include "ecukey.h"
  37. #include "esd.h"
  38. #include "var.h"
  39. #include "procedure.h"
  40. #include <sys/types.h>
  41. #include <sys/socket.h>
  42. #include <sys/stat.h>
  43. #include <sys/time.h>
  44. #include <sys/resource.h>
  45. #include <setjmp.h>
  46. #include <net/if.h>
  47. #include <netinet/in.h>
  48. #include <netdb.h>
  49. char *timeofday_text();
  50. char *inet_utoa();
  51. /*+-------------------------------------------------------------------------
  52. pcmd_serve(param)
  53. --------------------------------------------------------------------------*/
  54. int
  55. pcmd_serve(param)
  56. ESD *param;
  57. {
  58. int erc = 0;
  59. char switches[8];
  60. int itmp;
  61. long ltmp;
  62. UINT16 serve_port;
  63. int listen_sockfd = -1;
  64. int sockfd = -1;
  65. struct sockaddr_in sockaddr,*sa = &sockaddr;
  66. struct timeval tval,*tv = &tval;
  67. UINT32 peer_addr;
  68. UINT16 peer_port;
  69. int old_ttymode = get_ttymode(); /* save original tty mode */
  70. #ifdef CFG_HasFdSet
  71. CFG_FDSET fdset;
  72. #else
  73. int fdset;
  74. #endif
  75. get_switches(param, switches, sizeof(switches));
  76. if(strchr(switches,'R'))
  77. {
  78. }
  79. if (erc = gint(param, &ltmp))
  80. return (erc);
  81. serve_port = ltmp;
  82. if (proc_trace)
  83. {
  84. pprintf("%s: ",timeofday_text(3,0));
  85. pprintf("serve on port %d\n",serve_port);
  86. }
  87. iv[0] = 0;
  88. listen_sockfd = socket(AF_INET,SOCK_STREAM,0);
  89. if(listen_sockfd < 0)
  90. {
  91. iv[0] = errno;
  92. pperror("socket");
  93. goto FUNC_EXIT;
  94. }
  95. itmp = 1;
  96. if(setsockopt(listen_sockfd,SOL_SOCKET,SO_REUSEADDR,&itmp,sizeof(itmp)) < 0)
  97. {
  98. iv[0] = errno;
  99. pperror("setsockopt SO_REUSEADDR");
  100. goto FUNC_EXIT;
  101. }
  102. memset((char *)sa,0,sizeof(*sa));
  103. sa->sin_family = AF_INET;
  104. sa->sin_port = htons(serve_port);
  105. itmp = bind(listen_sockfd,(struct sockaddr *)sa,sizeof(*sa));
  106. if(itmp < 0)
  107. {
  108. iv[0] = errno;
  109. pperror("bind");
  110. goto FUNC_EXIT;
  111. }
  112. itmp = 1;
  113. if(setsockopt(listen_sockfd,SOL_SOCKET,SO_REUSEADDR,&itmp,sizeof(itmp)) < 0)
  114. {
  115. iv[0] = errno;
  116. pperror("setsockopt SO_REUSEADDR");
  117. goto FUNC_EXIT;
  118. }
  119. if(listen(listen_sockfd,1))
  120. {
  121. iv[0] = errno;
  122. pperror("listen");
  123. goto FUNC_EXIT;
  124. }
  125. if(proc_trace)
  126. {
  127. pprintf("%s: ",timeofday_text(3, 0));
  128. pprintf("serve listen on TCP port %d started (sockfd=%d)\n",
  129. serve_port,listen_sockfd);
  130. }
  131. ttymode(3);
  132. while(1)
  133. {
  134. #ifdef CFG_HasFdSet
  135. FD_ZERO(&fdset);
  136. FD_SET(listen_sockfd, &fdset);
  137. #else
  138. fdset = 1 << listen_sockfd;
  139. #endif
  140. tv->tv_sec = 10;
  141. tv->tv_usec = 0;
  142. if ((itmp = select(listen_sockfd + 1, &fdset, 0, 0, tv)) < 1)
  143. {
  144. if(itmp == 0)
  145. continue;
  146. else if ((errno == EINTR) && !ck_sigint())
  147. continue;
  148. iv[0] = errno;
  149. pperror("listen select");
  150. goto FUNC_EXIT;
  151. }
  152. break;
  153. }
  154. itmp = sizeof(*sa);
  155. if((sockfd = accept(listen_sockfd,(struct sockaddr *)sa,&itmp)) < 0)
  156. {
  157. iv[0] = errno;
  158. pperror("accept");
  159. goto FUNC_EXIT;
  160. }
  161. itmp = sizeof(*sa);
  162. if(itmp = getpeername(sockfd,(struct sockaddr *)sa,&itmp))
  163. {
  164. iv[0] = errno;
  165. pperror("getpeername");
  166. goto FUNC_EXIT;
  167. }
  168. peer_addr = ntohl(sa->sin_addr.s_addr);
  169. peer_port = ntohs(sa->sin_port);
  170. if (proc_trace)
  171. {
  172. pprintf("%s: ",timeofday_text(3,0));
  173. pprintf("connect from %s:%d\n", inet_utoa(peer_addr),peer_port);
  174. }
  175. if(erc = socket_fdopen(sockfd,&itmp))
  176. {
  177. pputs("socket_fdopen: ");
  178. proc_error(erc);
  179. erc = 0;
  180. iv[0] = EPERM;
  181. goto FUNC_EXIT;
  182. }
  183. esdzero(sv[0]);
  184. esdstrcat(sv[0], inet_utoa(peer_addr));
  185. iv[1] = (peer_addr >> 24) & 0xFF;
  186. iv[2] = (peer_addr >> 16) & 0xFF;
  187. iv[3] = (peer_addr >> 8) & 0xFF;
  188. iv[4] = (peer_addr >> 0) & 0xFF;
  189. iv[5] = peer_port;
  190. iv[6] = itmp;
  191. FUNC_EXIT:
  192. if(listen_sockfd > -1)
  193. close(listen_sockfd);
  194. ttymode(old_ttymode);
  195. if(!iv[0])
  196. return(0);
  197. if(sockfd >= 0)
  198. close(sockfd);
  199. return (erc);
  200. } /* end of pcmd_serve */
  201. /*+-------------------------------------------------------------------------
  202. pcmd_servewire(param)
  203. --------------------------------------------------------------------------*/
  204. int
  205. pcmd_servewire(param)
  206. ESD *param;
  207. {
  208. int erc = 0;
  209. int log_traffic = 0;
  210. int itmp;
  211. char switches[8];
  212. char banner[1024];
  213. char myhostnm[256];
  214. int filenum = -1;
  215. int fdmax;
  216. int sockfd;
  217. int ttyfd;
  218. struct timeval tval,*tv = &tval;
  219. char buf[1024];
  220. int old_ttymode = get_ttymode(); /* save original tty mode */
  221. char *timeofday_text();
  222. #ifdef CFG_HasFdSet
  223. CFG_FDSET fdset;
  224. #else
  225. int fdset;
  226. #endif
  227. if (shm->Liofd < 0)
  228. return(eNoLineAttached);
  229. get_switches(param, switches, sizeof(switches));
  230. log_traffic = !!strchr(switches,'l');
  231. if (erc = get_filenum(param, &filenum))
  232. return (erc);
  233. sockfd = ecufileno(filenum);
  234. if(sockfd < 0)
  235. {
  236. iv[0] = EBADF;
  237. pperror("ecu file number illegal or not open");
  238. goto FUNC_EXIT;
  239. }
  240. fdmax = sockfd;
  241. ttyfd = shm->Liofd;
  242. if(fdmax < ttyfd)
  243. fdmax = ttyfd;
  244. fdmax++;
  245. if(log_traffic || proc_trace)
  246. {
  247. pprintf("%s: ",timeofday_text(3, 0));
  248. pputs("servewire entering service\n");
  249. }
  250. iv[0] = 0;
  251. ttymode(3);
  252. lflush(2); /* flush line input and output */
  253. shm->Ltelnet_raw = 1;
  254. myhostnm[0] = 0;
  255. gethostname(myhostnm,sizeof(myhostnm));
  256. if(!myhostnm[0])
  257. strcpy(myhostnm,"noname");
  258. sprintf(banner,"%s:%s at %s\r\n",myhostnm, shm->Lline, timeofday_text(4,0));
  259. write(sockfd,banner,strlen(banner));
  260. while(1)
  261. {
  262. #ifdef CFG_HasFdSet
  263. FD_ZERO(&fdset);
  264. FD_SET(sockfd, &fdset);
  265. FD_SET(ttyfd, &fdset);
  266. #else
  267. fdset = 1 << sockfd;
  268. fdset |= 1 << ttyfd;
  269. #endif
  270. tv->tv_sec = 10;
  271. tv->tv_usec = 0;
  272. if ((itmp = select(fdmax, &fdset, 0, 0, tv)) < 1)
  273. {
  274. if(itmp == 0)
  275. continue;
  276. iv[0] = errno;
  277. pperror("connection select");
  278. goto FUNC_EXIT;
  279. }
  280. if(FD_ISSET(sockfd,&fdset))
  281. {
  282. errno = 0;
  283. /*
  284. * shorter read length for socket than tty
  285. */
  286. if((itmp = read(sockfd,buf,sizeof(buf) / 4)) < 0)
  287. {
  288. iv[0] = errno;
  289. pperror("socket read");
  290. goto FUNC_EXIT;
  291. }
  292. if(!itmp)
  293. {
  294. if(log_traffic || proc_trace)
  295. {
  296. pprintf("%s: ",timeofday_text(3, 0));
  297. pputs("socket closed\n");
  298. }
  299. break;
  300. }
  301. if(log_traffic)
  302. hex_dump(buf,itmp,"socket read",1);
  303. write(ttyfd,buf,itmp);
  304. }
  305. if(FD_ISSET(ttyfd,&fdset))
  306. {
  307. errno = 0;
  308. /*
  309. * big gulps from short tty buffers
  310. */
  311. if((itmp = read(ttyfd,buf,sizeof(buf))) < 0)
  312. {
  313. iv[0] = errno;
  314. pperror("tty read");
  315. goto FUNC_EXIT;
  316. }
  317. if(log_traffic)
  318. hex_dump(buf,itmp,"tty read",1);
  319. write(sockfd,buf,itmp);
  320. }
  321. }
  322. FUNC_EXIT:
  323. if(log_traffic || proc_trace)
  324. {
  325. pprintf("%s: ",timeofday_text(3, 0));
  326. pputs("servewire exiting\n");
  327. }
  328. shm->Ltelnet_raw = 0;
  329. ttymode(old_ttymode);
  330. close_ecu_file(filenum);
  331. return(0);
  332. } /* end of pcmd_servewire */
  333. #endif /* CFG_TelnetServer */
  334. /* vi: set tabstop=4 shiftwidth=4: */
  335. /* end of pcmdserve.c */