xtmain.c
上传用户:duobangkj
上传日期:2007-01-07
资源大小:70k
文件大小:11k
源码类别:

Telnet客户端

开发平台:

Unix_Linux

  1. /* xtmain.c -- main module for XT
  2. This file uses 4-character tabstops
  3. */
  4. #include <stdio.h>
  5. #include <string.h>
  6. #include <sys/types.h>
  7. #include <signal.h>
  8. #include <ctype.h>
  9. #include <termio.h>
  10. #include <setjmp.h>
  11. #include "xt.h"
  12. #define Resume_Not_Allowed 1
  13. short
  14. autoflag = FALSE, /* Automatic capturing */
  15. cismode = FALSE, /* Automatic response to CIS "ENQ" */
  16. cr_add = TRUE, /* Add cr to nl in B+ uploads */
  17.   menuflag = TRUE, /* Show mini-menu */
  18. nl2cr = TRUE, /* Map nl to cr when transmitting ASCII */
  19. reterm = FALSE, /* Jump into terminal mode */
  20. statflag = FALSE, /* Flag for status display */
  21. eofflag = FALSE; /* Flag to quit a script */
  22. int s_cis(), s_set(), s_exit(), s_shell();
  23. char Msg[80], directory[128], hostname[40], ddsname[SM_BUFF];
  24. unchar BS, LK;
  25. FILE *tfp;
  26. struct termio newmode, oldmode, sigmode;
  27. static char *statfmt = "rtt%-8s %25s %srn",
  28. version[]="@(#)XT 1.2 JPRadley 8 July 1997",
  29. oldshell[SM_BUFF],
  30. *babble[] = {
  31. "rnUsage: xt [-n site] | [-s file]",
  32. "t-n sitetSitename to contact with telnet",
  33. "t-s scripttExecute 'script' immediately",
  34. NIL(char)
  35. };
  36. static s_script(), s_term(), s_help(), s_host(), 
  37. SET_cr(), SET_cis(), SET_nl(), SET_xcape(),
  38. SET_menu(), SET_autocapt(), SET_cfile(), SET_dir();
  39. extern short scriptflag;
  40. extern int sfd;
  41. extern void B_Transfer(), dbglog(), sattach(), get_ttype();
  42. jmp_buf erret; /* non-local error return */
  43. struct kw { /* Used by command parsing routines */
  44. char *keyword;
  45. int (*rtn)();
  46. };
  47. static struct kw cmds[] = {
  48. {"c", s_cis},
  49. {"cis", s_cis},
  50. {"n", s_host},
  51. {"nethost", s_host},
  52. {"s", s_script},
  53. {"script", s_script},
  54. {"t", s_term},
  55. {"term", s_term},
  56. {"bindings",show_bindings},
  57. {"set", s_set},
  58. {"q", s_exit},
  59. {"quit", s_exit},
  60. {"exit", s_exit},
  61. {"x", s_exit},
  62. {"!", s_shell},
  63. {"!!", s_shell},
  64. {"$", s_shell},
  65. {"~", s_shell},
  66. {"help", s_help},
  67. {"?", s_help},
  68. {NIL(char), 0}
  69. };
  70. static struct kw setlist[] = {
  71. {"auto", SET_autocapt},
  72. {"cfile", SET_cfile},
  73. {"cis", SET_cis},
  74. {"cr", SET_cr},
  75. {"dir", SET_dir},
  76. {"menu", SET_menu},
  77. {"nl", SET_nl},
  78. {"escape", SET_xcape},
  79. {"xcape", SET_xcape},
  80. {NIL(char), 0}
  81. };
  82. /* Print the status of the program */
  83. static void
  84. status()
  85. {
  86. struct kw *ptr;
  87. char p[40];
  88. int (*fct)() = 0;
  89. statflag = TRUE;
  90. cls();
  91. cur_off();
  92. if (*hostname)
  93. sprintf(p,"      Telnet => %s",hostname);
  94. else
  95. p[0]='';
  96. drawline(0, 0, CO);
  97. sprintf(Msg,"%s%s",&version[4], p);
  98. ttgoto(1,(CO-(int)strlen(Msg))/2 -1);
  99. S1(Msg);
  100. drawline(2, 0, CO);
  101. ttgoto(3, 0);
  102. fprintf(tfp, statfmt, "Keyword", "Description", "Status");
  103. fprintf(tfp, statfmt,"--------","-------------------------","-----------");
  104. for (ptr = setlist; ptr->keyword; ptr++)
  105. if (ptr->rtn != fct){
  106. fct = ptr->rtn;
  107. (*fct)();
  108. }
  109. ttgoto(14, 25);
  110. S1("Type "help" or ? for help");
  111. statflag = FALSE;
  112. cur_on();
  113. }
  114. /* Catch a signal and jump to main. Reset signal and do a longjmp */
  115. static RETSIGTYPE
  116. catch(junk)
  117. int junk;
  118. {
  119. if (! isatty(2))
  120. s_exit();
  121. S2("XT: Interrupt");
  122. signal(SIGINT,catch);
  123. signal(SIGQUIT,catch);
  124. longjmp(erret,1);
  125. }
  126. static void
  127. usage()
  128. {
  129. char **ptr;
  130. for (ptr = babble; *ptr; ptr++)
  131. fprintf(tfp, "%srn", *ptr);
  132. }
  133. main(argc, argv)
  134. int argc;
  135. char **argv;
  136. {
  137. char *script = NIL(char);
  138. extern char *optarg;
  139. int c;
  140. extern int optind;
  141. struct kw *ptr;
  142. tfp = stderr;
  143. if (isatty(2))
  144. get_ttype();
  145. ioctl(0, TCGETA, &oldmode); /* get current tty mode */
  146. /* trap for SIGHUP and SIGTERM, make sure LCKfile gets killed */
  147. signal(SIGHUP,(RETSIGTYPE (*)())s_exit);
  148. signal(SIGTERM,(RETSIGTYPE (*)())s_exit);
  149. newmode = oldmode;
  150. newmode.c_iflag &= ~(IXON | IXOFF | IXANY);
  151. newmode.c_lflag &= ~(ICANON | ISIG | ECHO);
  152. newmode.c_oflag = OPOST | ONLCR;
  153. newmode.c_cc[VMIN] = 1;
  154. newmode.c_cc[VTIME] = 1;
  155. BS = newmode.c_cc[VERASE];
  156. LK = newmode.c_cc[VKILL];
  157. mode(NEWMODE);
  158. sigmode = newmode;
  159. sigmode.c_lflag |= ISIG;
  160. oldshell[0] = ''; /* set last command to blank */
  161. if (setjmp(erret)) /* set error handler to exit */
  162. exit(0); /*  while parsing command line */
  163. signal(SIGINT,catch); /* catch break & quit signals/keys */
  164. signal(SIGQUIT,catch);
  165. default_bindings();
  166. while ((c = getopt(argc, argv, "s:n:")) != -1)
  167. switch (c){
  168. case 's': /* Execute SCRIPT file */
  169. script = optarg;
  170. break;
  171. case 'n': /* network connection using telnet */
  172. sprintf(hostname,"%s",optarg);
  173. break;
  174. default: /* Bad command .. print help */
  175. usage();
  176. mode(OLDMODE);
  177. exit(1);
  178. }
  179. getcwd(directory, 64);
  180. do_script(STARTUP);
  181. #if LOG
  182. dbglog();
  183. #endif
  184. if (!script)
  185. status();
  186. for (;;){
  187. setjmp(erret);
  188. signal(SIGQUIT,(RETSIGTYPE (*)())s_exit);
  189. mode(SIGMODE);
  190. if (script)
  191. do_script(script),
  192. reterm = TRUE,
  193. script = NIL(char);
  194. if (sfd < 0 && *hostname)
  195. reterm = xttn();
  196. if (reterm && sfd > 0 && isatty(2)){
  197. s_term();
  198. continue;
  199. }
  200. reterm = FALSE;
  201. fputc('r',tfp),
  202. fputc('n',tfp);
  203.   if (menuflag)
  204. fputc('t',tfp),
  205.   S1("[t]erminal mode  [q]uit  [s]cript  [?]help");
  206. show(-1,"<XT>");
  207. fputc(' ',tfp);
  208. lptr = line;
  209. getline();
  210. fputc('r',tfp),
  211. fputc('n',tfp);
  212. getword();
  213. lc_word(word);
  214. if (word[0] == '') /* If blank line... reprompt */
  215. continue;
  216. for (ptr = cmds; ptr->keyword; ptr++)
  217. if (!strcmp(word, ptr->keyword))
  218. break;
  219. if (ptr->keyword)
  220. (*ptr->rtn)();
  221. else
  222. sprintf(Msg,"Unrecognized command: %s",word),
  223. S;
  224. }
  225. }
  226. static
  227. s_script()
  228. {
  229. getword();
  230. if (word[0] == ''){
  231. S1("Script file not specified");
  232. return;
  233. }
  234. sprintf(ddsname,"%s",word);
  235. do_script(ddsname);
  236. reterm = TRUE;
  237. }
  238. static
  239. s_host()
  240. {
  241. getword();
  242. if (word[0] == ''){
  243. S1("Hostname not specified");
  244. return;
  245. }
  246. sprintf(hostname,"%s",word);
  247. reterm = xttn();
  248. }
  249. static
  250. s_term()
  251. {
  252. reterm = tnterm();
  253. if (cismode != 2)
  254. return;
  255. cismode = 1;
  256. s_cis();
  257. }
  258. s_cis()
  259. {
  260. mode(SIGMODE);
  261. B_Transfer();
  262. }
  263. s_shell()
  264. {
  265. int stat_loc = 0;
  266. char c = word[0];
  267. static char *shell = NIL(char);
  268. RETSIGTYPE (*oldvec)();
  269. #if NOSHELL
  270. return(0);
  271. #endif
  272. if (word[0] == word[1])
  273. strcpy(wptr = word, oldshell);
  274. else {
  275. getword();
  276. if (*wptr)
  277. strcpy(oldshell, wptr);
  278. }
  279. if (!shell){
  280. shell = getenv("SHELL");
  281. if (!shell)
  282. shell = "/bin/sh";
  283. }
  284. #if 0 
  285. fputc('r',tfp),
  286. fputc('n',tfp);
  287. #endif
  288. mode(OLDMODE);
  289. if (!forkem()){
  290. if (c == '$') /* Attach modem to stdin, stdout */
  291. sattach();
  292. signal(SIGCLD,SIG_DFL);
  293. signal(SIGINT,SIG_DFL);
  294. signal(SIGQUIT,SIG_DFL);
  295. if (word[0] == '')
  296. execl(shell, shell, "-i", NIL(char));
  297. else
  298. execl(shell, shell, "-c", wptr, NIL(char));
  299. S1("Exec failed!");
  300. exit(2);
  301. }
  302. oldvec = signal(SIGINT,SIG_IGN);
  303. wait(&stat_loc);
  304. signal(SIGINT,oldvec);
  305. strcpy(oldshell, wptr);
  306. return(!!stat_loc);
  307. }
  308. static char *cmdlist[] = {
  309. "tXT Command Summary",
  310. "",
  311. "tc",
  312. "tcisttInitiate CIS B+ File Transfer (Upload and Download)",
  313. "",
  314. "tx",
  315. "tq",
  316. "texit",
  317. "tquitttExit XT",
  318. "",
  319. "tsetttDisplay XT parameters",
  320. "tset kwttDisplay XT parameter for 'kw'",
  321. "tset kw valtSet XT keyword 'kw' to 'val'",
  322. "",
  323. "tn host",
  324. "tnethost hosttTelnet to 'host'",
  325. "",
  326. "ts file",
  327. "tscript filetExecute XT script 'file'",
  328. "",
  329. #if !NOSHELL
  330. "t!ttExecute a local interactive shell",
  331. "t! cmdttExecute shell command string on the local system",
  332. "t!!ttRe-execute the last shell command string",
  333. "",
  334. "t$ cmdttShell command with stdin and stdout redirected to modem",
  335. "",
  336. #endif
  337. "tt",
  338. "ttermttEnter Terminal mode",
  339. "",
  340. "t?",
  341. "thelpttPrint (this) help text",
  342. " ",
  343. "tSET Keywords:",
  344. "",
  345. "tsettttDisplay current XT status",
  346. "",
  347. "tset auto on|offttSet|Unset automatic capturing",
  348. "",
  349. "tset cfile namettChange name of capture file",
  350. "",
  351. "tset cis onttSet CIS <ENQ> mode (Auto up/download)",
  352. "tset cis offttDo not respond to <ENQ>",
  353. "",
  354. "tset cr on|offttSet|Unset Carriage Return Injection mode",
  355. "",
  356. "tset dir namettChange current directory",
  357. "",
  358. "tset xcape char",
  359. "tset escape charttSet the Terminal mode escape character",
  360. "",
  361.   "tset menu on|offttDo|Don't show mini-menu before XT prompt",
  362. "",
  363. "tset nl on|offttSet|Unset newline translation",
  364. "",
  365. " ",
  366. NIL(char) };
  367. static
  368. s_help()
  369. {
  370. char **ptr = cmdlist;
  371. int curline = 0;
  372. mode(OLDMODE);
  373. cls();
  374. cur_off();
  375. for ( ; *ptr; ptr++) {
  376. if (**ptr != ' ') {
  377. if (curline >= LI-2){
  378. S0("PRESS ENTER");
  379. getline();
  380. cls();
  381. curline = 0;
  382. }
  383. fprintf(tfp, "%srn", *ptr);
  384. curline++;
  385. } else {
  386. S0("PRESS ENTER");
  387. getline();
  388. cls();
  389. curline = 0;
  390. }
  391. }
  392. show_bindings();
  393. S0("PRESS ENTER");
  394. getline();
  395. cls();
  396. status();
  397. }
  398. s_set()
  399. {
  400. struct kw *ptr;
  401. getword();
  402. if (word[0] == '' && !scriptflag){
  403. status();
  404. return;
  405. } else if (word[0] == ''){
  406. S1("SET keyword requires an argument");
  407. eofflag++;
  408. return;
  409. }
  410. lc_word(word);
  411. for (ptr = setlist; ptr->keyword; ptr++)
  412. if (!strcmp(ptr->keyword, word)){
  413. (*ptr->rtn)();
  414. return;
  415. }
  416. sprintf(Msg,"Invalid SET keyword: %s", word);
  417. S;
  418. eofflag++;
  419. }
  420. void
  421. set_onoff(flag)
  422. short *flag;
  423. {
  424. char *ptr = strdup(word);
  425. uc_word(ptr);
  426. getword();
  427. lc_word(word);
  428. if (!strcmp(word, "on"))
  429. *flag = TRUE;
  430. else if (!strcmp(word, "off"))
  431. *flag = FALSE;
  432. else
  433. sprintf(Msg,"Set '%s' value must be 'on' or 'off'",ptr),
  434. S,
  435. eofflag++;
  436. free(ptr);
  437. }
  438. static
  439. SET_dir()
  440. {
  441. if (statflag){
  442. fprintf(tfp, statfmt, "dir", "We are in", directory);
  443. return;
  444. }
  445. getword();
  446. strcpy(directory, word);
  447. if (chdir(directory))
  448. sprintf(Msg,"Can't move to %s", directory),
  449. S;
  450. if (!scriptflag)
  451. sprintf(Msg, "We are in %s", directory),
  452. S;
  453. }
  454. static
  455. SET_cr()
  456. {
  457. if (statflag){
  458. fprintf(tfp, statfmt, "cr", "Carriage Return Injection",
  459. cr_add ? "ON" : "OFF");
  460. return;
  461. }
  462. set_onoff(&cr_add);
  463. if (!scriptflag)
  464. sprintf(Msg,"Carriage Returns %s injected in B+ ASCII uploads",
  465. cr_add ? "ARE" : "are NOT"),
  466. S;
  467. }
  468. static
  469. SET_xcape()
  470. {
  471. if (statflag) {
  472. fprintf(tfp, statfmt, "xcape", "Terminal Escape Character",
  473.  unctrl(my_escape));
  474. return;
  475. }
  476. getword();
  477. if (word[0] == '') {
  478. show(1,"Set ESCAPE must specify escape character");
  479. eofflag++;
  480. return;
  481. }
  482. my_escape = word[0];
  483. if (!scriptflag)
  484. sprintf(Msg,"Terminal mode escape character set to '%s'",
  485. unctrl(my_escape)),
  486. S;
  487. }
  488. static
  489. SET_nl()
  490. {
  491. if (statflag){
  492. fprintf(tfp, statfmt, "nl", "Newline Translation",
  493. nl2cr ? "ON" : "OFF");
  494. return;
  495. }
  496. set_onoff(&nl2cr);
  497. if (!scriptflag)
  498. sprintf(Msg,"Newlines %s changed to Carriage Returns",
  499. nl2cr ? "ARE" : "are NOT"),
  500. S;
  501. }
  502. static
  503. SET_cis()
  504. {
  505. if (statflag){
  506. fprintf(tfp, statfmt, "cis", "CIS <ENQ> Auto Download",
  507. cismode ? "ON" : "OFF");
  508. return;
  509. }
  510. set_onoff(&cismode);
  511. if (!scriptflag)
  512. sprintf(Msg,"CIS <ENQ> Auto Download is %s", cismode ? "ON" : "OFF"),
  513. S;
  514. }
  515. static
  516. SET_menu()
  517. {
  518.   if (statflag){
  519.   fprintf(tfp, statfmt, "menu", "Mini-menu mode",
  520.   menuflag ? "ON" : "OFF");
  521.   return;
  522. }
  523.  
  524.   set_onoff(&menuflag);
  525.  
  526.   if (!scriptflag)
  527.   sprintf(Msg,"Mini-menu is %s shown", menuflag ? "" : "NOT"),
  528. S;
  529. }
  530. static
  531. SET_autocapt()
  532. {
  533. if (statflag){
  534. fprintf(tfp, statfmt, "auto", "Auto Capture",
  535. autoflag ? "ON" : "OFF");
  536. return;
  537. }
  538. set_onoff(&autoflag);
  539. if (!scriptflag)
  540. sprintf(Msg,"Auto Capture is %s", autoflag ? "ON" : "OFF"),
  541. S;
  542. }
  543. static
  544. SET_cfile()
  545. {
  546. if (statflag){
  547. fprintf(tfp, statfmt, "cfile", "Capture File", captfile);
  548. return;
  549. }
  550. getword();
  551. if (word[0] == ''){
  552. S1("Set CFILE must have file name");
  553. eofflag++;
  554. return;
  555. }
  556. strcpy(captfile, word);
  557. if (!scriptflag)
  558. sprintf(Msg,"Capture file set to '%s'",captfile),
  559. S;
  560. }
  561. s_exit()
  562. {
  563. signal(SIGHUP,SIG_IGN);
  564. signal(SIGINT,SIG_IGN);
  565. signal(SIGQUIT,SIG_IGN);
  566. signal(SIGTERM,SIG_IGN);
  567. mode(OLDMODE);
  568. exit(0);
  569. }