session.c
上传用户:hepax88
上传日期:2007-01-03
资源大小:1101k
文件大小:8k
源码类别:

TCP/IP协议栈

开发平台:

Visual C++

  1. /* NOS User Session control
  2.  * Copyright 1991 Phil Karn, KA9Q
  3.  */
  4. #include <stdio.h>
  5. #include "global.h"
  6. #include "mbuf.h"
  7. #include "proc.h"
  8. #include "ftpcli.h"
  9. #include "icmp.h"
  10. #include "telnet.h"
  11. #include "tty.h"
  12. #include "session.h"
  13. #include "hardware.h"
  14. #include "socket.h"
  15. #include "cmdparse.h"
  16. #include "commands.h"
  17. #include "main.h"
  18. struct session **Sessions;
  19. struct session *Command;
  20. struct session *Current;
  21. struct session *Lastcurr;
  22. char Notval[] = "Not a valid control blockn";
  23. static char Badsess[] = "Invalid sessionn";
  24. char *Sestypes[] = {
  25. "",
  26. "Telnet",
  27. "FTP",
  28. "AX25",
  29. "Finger",
  30. "Ping",
  31. "NET/ROM",
  32. "Command",
  33. "More",
  34. "Hopcheck",
  35. "Tip",
  36. "PPP PAP",
  37. "Dial",
  38. "Query",
  39. "Cache",
  40. "Trace",
  41. "Repeat",
  42. };
  43. /* Convert a character string containing a decimal session index number
  44.  * into a pointer. If the arg is NULL, use the current default session.
  45.  * If the index is out of range or unused, return NULL.
  46.  */
  47. struct session *
  48. sessptr(cp)
  49. char *cp;
  50. {
  51. unsigned int i;
  52. if(cp == NULL)
  53. return Lastcurr;
  54. i = (unsigned)atoi(cp);
  55. if(i >= Nsessions)
  56. return NULL;
  57. else
  58. return Sessions[i];
  59. }
  60. /* Select and display sessions */
  61. int
  62. dosession(argc,argv,p)
  63. int argc;
  64. char *argv[];
  65. void *p;
  66. {
  67. struct session *sp;
  68. struct sockaddr fsocket;
  69. int i,k,s,ses;
  70. int t;
  71. char *cp;
  72. sp = (struct session *)p;
  73. if(argc > 1){
  74. if((sp = sessptr(argv[1])) != NULL){
  75. go(0,NULL,sp);
  76. } else
  77. printf("Session %s not activen",argv[1]);
  78. return 0;
  79. }
  80. printf(" #  S#  Snd-Q State     Remote socket         Commandn");
  81. for(ses=0;ses<Nsessions;ses++){
  82. sp = Sessions[ses];
  83. if(sp == NULL || sp->type == COMMAND)
  84. continue;
  85. t = 0;
  86. cp = NULL;
  87. if(sp->network != NULL && (s = fileno(sp->network)) != -1){
  88. i = SOCKSIZE;
  89. k = getpeername(s,&fsocket,&i);
  90. t += socklen(s,1);
  91. cp = sockstate(s);
  92. } else {
  93. k = s = -1;
  94. t = 0;
  95. cp = NULL;
  96. }
  97. printf("%c", (Lastcurr == sp)? '*':' ');
  98. printf("%-3u",sp->index);
  99. printf("%-4d%5d %-10s",s,t,(cp != NULL) ? cp : "");
  100. printf("%-22s",(k == 0) ? psocket(&fsocket) : "");
  101. if(sp->name != NULL)
  102. printf("%s",sp->name);
  103. printf("n");
  104. /* Display FTP data channel, if any */
  105. if(sp->type == FTP && (s = fileno(sp->cb.ftp->data)) != -1){
  106. i = SOCKSIZE;
  107. k = getpeername(s,&fsocket,&i);
  108. t += socklen(s,1);
  109. cp = sockstate(s);
  110. printf("    %-4d%5d %-10s",s,t,(cp != NULL) ? cp : "");
  111. printf("%-22sn",(k == 0) ? psocket(&fsocket) : "");
  112. }
  113. if(sp->record != NULL)
  114. printf("    Record: %sn",fpname(sp->record));
  115. if(sp->upload != NULL)
  116. printf("    Upload: %sn",fpname(sp->upload));
  117. }
  118. return 0;
  119. }
  120. /* Resume current session, and wait for it */
  121. int
  122. go(argc,argv,p)
  123. int argc;
  124. char *argv[];
  125. void *p;
  126. {
  127. struct session *sp;
  128. sp = (struct session *)p;
  129. if(sp == NULL || sp->type == COMMAND)
  130. return 0;
  131. if(Current != Command)
  132. Lastcurr = Current;
  133. Current = sp;
  134. alert(Display,1);
  135. return 0;
  136. }
  137. int
  138. doclose(argc,argv,p)
  139. int argc;
  140. char *argv[];
  141. void *p;
  142. {
  143. struct session *sp;
  144. sp = (struct session *)p;
  145. if(argc > 1)
  146. sp = sessptr(argv[1]);
  147. if(sp == NULL){
  148. printf(Badsess);
  149. return -1;
  150. }
  151. shutdown(fileno(sp->network),1);
  152. return 0;
  153. }
  154. int
  155. doreset(argc,argv,p)
  156. int argc;
  157. char *argv[];
  158. void *p;
  159. {
  160. struct session *sp;
  161. sp = (struct session *)p;
  162. if(argc > 1)
  163. sp = sessptr(argv[1]);
  164. if(sp == NULL){
  165. printf(Badsess);
  166. return -1;
  167. }
  168. /* Unwedge anyone waiting for a domain resolution, etc */
  169. alert(sp->proc,EABORT);
  170. shutdown(fileno(sp->network),2);
  171. if(sp->type == FTP)
  172. shutdown(fileno(sp->cb.ftp->data),2);
  173. return 0;
  174. }
  175. int
  176. dokick(argc,argv,p)
  177. int argc;
  178. char *argv[];
  179. void *p;
  180. {
  181. struct session *sp;
  182. sp = (struct session *)p;
  183. if(argc > 1)
  184. sp = sessptr(argv[1]);
  185. if(sp == NULL){
  186. printf(Badsess);
  187. return -1;
  188. }
  189. sockkick(fileno(sp->network));
  190. if(sp->type == FTP)
  191. sockkick(fileno(sp->cb.ftp->data));
  192. return 0;
  193. }
  194. int
  195. dosfsize(argc,argv,p)
  196. int argc;
  197. char *argv[];
  198. void *p;
  199. {
  200. return setlong(&Sfsize,"Scroll file size",argc,argv);
  201. }
  202. struct session *
  203. newsession(name,type,makecur)
  204. char *name;
  205. int type;
  206. int makecur;
  207. {
  208. register struct session *sp;
  209. int i;
  210. /* Search for a free slot in the session table */
  211. for(i=0;i < Nsessions;i++)
  212. if(Sessions[i] == NULL)
  213. break;
  214. if(i == Nsessions)
  215. return NULL; /* All full */
  216. sp = Sessions[i] = (struct session *)calloc(1,sizeof(struct session));
  217. sp->index = i;
  218. sp->type = type;
  219. if(name != NULL)
  220. sp->name = strdup(name);
  221. sp->proc = Curproc;
  222. /* Create standard input and output sockets. Output is
  223.  * in text mode by default
  224.  */
  225. fclose(stdin);
  226. stdin =  sp->input = pipeopen();
  227. setvbuf(stdin,NULL,_IONBF,0);
  228. fclose(stdout);
  229. stdout = sp->output = displayopen("wt",0,Sfsize);
  230. /* on by default */
  231. sp->ttystate.crnl = sp->ttystate.edit = sp->ttystate.echo = 1;
  232. sp->parent = Current;
  233. if(makecur){
  234. Current = sp;
  235. alert(Display,1);
  236. }
  237. return sp;
  238. }
  239. void
  240. freesession(sp)
  241. struct session *sp;
  242. {
  243. int i;
  244. if(sp == NULL || sp != Sessions[sp->index])
  245. return; /* Not on session list */
  246. kwait(NULL); /* Wait for any pending output to go */
  247. for(i=0;i<Nsessions;i++){
  248. if(Sessions[i]->parent == sp)
  249. Sessions[i]->parent = sp->parent;
  250. }
  251. Sessions[sp->index] = NULL;
  252. if(sp->proc1 != NULL)
  253. killproc(sp->proc1);
  254. if(sp->proc2 != NULL)
  255. killproc(sp->proc2);
  256. free(sp->ttystate.line);
  257. if(sp->network != NULL)
  258. fclose(sp->network);
  259. if(sp->record != NULL)
  260. fclose(sp->record);
  261. if(sp->upload != NULL)
  262. fclose(sp->upload);
  263. free(sp->name);
  264. if(Lastcurr == sp)
  265. Lastcurr = sp->parent;
  266. if(Current == sp){
  267. Current = sp->parent;
  268. alert(Display,1);
  269. }
  270. free(sp);
  271. }
  272. /* Control session recording */
  273. int
  274. dorecord(argc,argv,p)
  275. int argc;
  276. char *argv[];
  277. void *p;
  278. {
  279. struct session *sp;
  280. char *mode;
  281. sp = (struct session *)p;
  282. if(sp == NULL){
  283. printf("No current sessionn");
  284. return 1;
  285. }
  286. if(argc > 1){
  287. if(sp->record != NULL){
  288. fclose(sp->record);
  289. sp->record = NULL;
  290. }
  291. /* Open new record file, unless file name is "off", which means
  292.  * disable recording
  293.  */
  294. if(strcmp(argv[1],"off") != 0){
  295. if(fmode(sp->output,-1) == STREAM_ASCII)
  296. mode = APPEND_TEXT;
  297. else
  298. mode = APPEND_BINARY;
  299. if((sp->record = fopen(argv[1],mode)) == NULL)
  300. printf("Can't open %s: %sn",argv[1],sys_errlist[errno]);
  301. }
  302. }
  303. if(sp->record != NULL)
  304. printf("Recording into %sn",fpname(sp->record));
  305. else
  306. printf("Recording offn");
  307. return 0;
  308. }
  309. /* Control file transmission */
  310. int
  311. doupload(argc,argv,p)
  312. int argc;
  313. char *argv[];
  314. void *p;
  315. {
  316. register struct session *sp;
  317. sp = (struct session *)p;
  318. if(sp == NULL){
  319. printf("No current sessionn");
  320. return 1;
  321. }
  322. if(argc < 2){
  323. if(sp->upload != NULL)
  324. printf("Uploading %sn",fpname(sp->upload));
  325. else
  326. printf("Uploading offn");
  327. return 0;
  328. }
  329. if(strcmp(argv[1],"stop") == 0 && sp->upload != NULL){
  330. /* Abort upload */
  331. fclose(sp->upload);
  332. sp->upload = NULL;
  333. killproc(sp->proc2);
  334. sp->proc2 = NULL;
  335. return 0;
  336. }
  337. /* Open upload file */
  338. if((sp->upload = fopen(argv[1],READ_TEXT)) == NULL){
  339. printf("Can't read %s: %sn",argv[1],sys_errlist[errno]);
  340. return 1;
  341. }
  342. /* All set, invoke the upload process */
  343. sp->proc2 = newproc("upload",1024,upload,0,sp,NULL,0);
  344. return 0;
  345. }
  346. /* File uploading task */
  347. void
  348. upload(unused,sp1,p)
  349. int unused;
  350. void *sp1;
  351. void *p;
  352. {
  353. struct session *sp;
  354. char *buf;
  355. sp = (struct session *)sp1;
  356. buf = mallocw(BUFSIZ);
  357. while(fgets(buf,BUFSIZ,sp->upload) != NULL)
  358. if(fputs(buf,sp->network) == EOF)
  359. break;
  360. free(buf);
  361. fflush(sp->network);
  362. fclose(sp->upload);
  363. sp->upload = NULL;
  364. sp->proc2 = NULL;
  365. }
  366. /* Print prompt and read one character */
  367. int
  368. keywait(prompt,flush)
  369. char *prompt; /* Optional prompt */
  370. int flush; /* Flush queued input? */
  371. {
  372. int c;
  373. int i;
  374. if(prompt == NULL)
  375. prompt = "Hit enter to continue"; 
  376. printf(prompt);
  377. fflush(stdout);
  378. c = _fgetc(stdin);
  379. /* Get rid of the prompt */
  380. for(i=strlen(prompt);i != 0;i--)
  381. putchar('b');
  382. for(i=strlen(prompt);i != 0;i--)
  383. putchar(' ');
  384. for(i=strlen(prompt);i != 0;i--)
  385. putchar('b');
  386. fflush(stdout);
  387. return (int)c;
  388. }
  389. /* Flush the current session's standard output. Called on every clock tick */
  390. void
  391. sesflush()
  392. {
  393. if(Current != NULL)
  394. fflush(Current->output);
  395. }