main.c

来自「wm PNE 3.3 source code, running at more 」· C语言 代码 · 共 2,443 行 · 第 1/5 页

C
2,443
字号
    sty_puts(sty, "readme          type happy message\n");    break;   case help_long:    sty_puts(sty, "\The \"readme\" command types out a canned sales pitch explaining\n\what this program is supposed to be doing.\n");    break;  }  return 1;}static char *quotes[] = {  "\Jeez, got me.  Unix is sorta like Heroin, It feels good for about 5 minutes\n\a day and horrible the rest of the time.\n\                                        -- Jim O'Dell\n",  "\Bawden is misinformed.  Common Lisp has no philosophy.  We are held\n\together only by a shared disgust for all the alternatives.\n\    -- Scott Fahlman, explaining why Common Lisp is the way it is....\n",  "\Well, it's assembly language, you know.  You don't want to have too much\n\taste...\n\                                -- Dave Moon\n",  "\    The Hitchhiker's Guide to the Galaxy, in a moment of reasoned lucidity\n\which is almost unique among its current tally of five million, nine\n\hundred and seventy-five thousand, five hundred and nine pages, says of the\n\Sirius Cybernetics Corporation products that `it is very easy to be blinded\n\to the essential uselessness of them by the sense of achivement that you\n\get from getting them to work at all.\n\    `In other words -- and this is the rock solid principle on which the\n\whole of the Corporation's Galaxy-wide success is founded -- their\n\fundamental design flaws are completely hidden by their superficial design\n\flaws.'\n",};static boolean_t cmd_quote  (struct sty *sty, enum help_level help, int argc, char **argv){  static int quote_index;  switch (help) {   case help_none:    sty_puts(sty, quotes[quote_index++]);    if (quote_index >= sizeof(quotes)/sizeof(*quotes))      quote_index = 0;    break;   case help_short:    sty_puts(sty, "quote           type pithy message\n");    break;   case help_long:    sty_puts(sty, "The \"quote\" command types out something very witty.\n");    break;  }  return 1;}struct blat_state {  struct timer tm;  struct sty *sty;  unsigned count;  bits32_t delay;  size_t size;  char buffer[1];};static void blat_loop(struct timer *tm, void *cookie){  struct blat_state *state = cookie;  if ((state->sty->flags & (STY_FLAG_ABORTED|STY_FLAG_INTERRUPTED)) != 0) {    state->sty->flags &= ~(STY_FLAG_ABORTED|STY_FLAG_INTERRUPTED);    state->count = 0;  }  if (state->count > 0) {    sty_write(state->sty, state->buffer, state->size);    state->count--;  }  if (state->count > 0) {    etc_tm_set(tm, state->delay);  } else {    sty_read(state->sty, do_cmd, prompt, 0);    GLUE_FREE(state);  }}static boolean_t cmd_blat  (struct sty *sty, enum help_level help, int argc, char **argv){  struct blat_state *state;  size_t size = 512;  switch (help) {   case help_none:    if (argc > 1) {      /* Don't ask, you don't want to know. */      unsigned long size_ = (unsigned long) size;      sscanf(argv[1], "%lu", &size_);      size = (size_t) size_;    }    if ((state = GLUE_ALLOC(sizeof(*state)+size)) == 0) {      sty_puts(sty, "Not enough memory to allocate state block, sorry.\n");      break;    }    etc_tm_init(&state->tm);    state->tm.handler = blat_loop;    state->tm.cookie = state;    state->sty = sty;    state->count = 30;    if (argc > 2)      sscanf(argv[2], "%u", &state->count);    state->delay = 5000;    if (argc > 3)      sscanf(argv[3], "%lu", &state->delay);    state->size = size;    MEMSET(state->buffer, '.', size-1);    state->buffer[size-1] = '\n';    state->buffer[size] = '\0';    etc_tm_set(&state->tm, 0);    return 0;			/* DON'T reschedule command scanner yet */   case help_short:    sty_puts(sty, "blat            size blocks delay\n");    break;   case help_long:    sty_puts(sty, "\The \"blat\" command writes blocks of text to the screen with\n\a fixed delay between each block.  This is sometimes useful for testing.\n");    break;  }  return 1;}#if INSTALL_SNARK_ALICE#ifndef ALICE_DEBUG#define	ALICE_DEBUG 0#endifstruct alice_state {  struct task task;  struct sty *sty;  FILE *file;  unsigned long count;  unsigned long chunk;};static void alice_loop(struct task *alice_task, void *cookie){  struct alice_state *state = cookie;  struct sty *sty = state->sty;  char buffer[1000];  size_t howmany = (size_t) (ep_weak_prng(sizeof(buffer)) + 1);  if ((sty->flags & (STY_FLAG_ABORTED|STY_FLAG_INTERRUPTED)) != 0) {    (void) fseek(state->file, 0, 2);    if ((sty->flags & STY_FLAG_ABORTED) != 0)      sty_puts(sty, "...");    sty->flags &= ~(STY_FLAG_ABORTED|STY_FLAG_INTERRUPTED);  } else if ((sty->flags & STY_FLAG_BLOCKED) == 0) {    if ((howmany = fread(buffer, 1, howmany, state->file)) == 0) {#if ALICE_DEBUG      printf("%lu: end of alice file, chunk %lu, count = %lu\n",	     GLUE_NOW(), state->chunk, state->count);#endif      fclose(state->file);      GLUE_FREE(state);      TCP_SHOW_TCBS();      sty_read(sty, do_cmd, prompt, 0);      return;    }#if ALICE_DEBUG    printf("%lu: sending chunk %lu (%d bytes) to connection 0x%x\n",	   GLUE_NOW(), state->chunk++, howmany, sty);#endif    state->count += howmany;    sty_write(sty, buffer, howmany);  } else {#if ALICE_DEBUG    printf("%lu: delaying chunk %lu to connection 0x%x\n",	   GLUE_NOW(), state->chunk, sty);#endif  }  TCP_SHOW_TCBS();  task_enq(alice_task);  return;}static boolean_t cmd_alice  (struct sty *sty, enum help_level help, int argc, char **argv){  static char alice_env[] = "ALICE", *alice_name;  struct alice_state *state;  switch (help) {   case help_none:    if (alice_name == 0 && (alice_name = getenv(alice_env)) == 0) {      sty_printf(sty, "Environment variable \"%s\" not defined.\n", alice_env);      break;    }    if ((state = GLUE_ALLOC(sizeof(*state))) == 0) {      sty_puts(sty, "Not enough memory to allocate state block, sorry.\n");      break;    }    if ((state->file = fopen(alice_name, "r")) == 0) {      sty_printf(sty, "Can't open file \"%s\".\n", alice_name);      GLUE_FREE(state);      break;    }    state->sty = sty;    state->count = 0;    state->chunk = 1;    task_ini(&state->task);    task_add(&state->task, "Alice's PDP-10", alice_loop, state);    return 0;			/* DON'T reschedule command scanner yet */   case help_short:    sty_puts(sty, "alice           you can hack anything you want....\n");    break;   case help_long:    sty_puts(sty, "\The \"alice\" command tells you the story of Alice's PDP-10,\n\with full orchestration and five part harmony.\n");    break;  }  return 1;}#endif#if INSTALL_ATTACHE_TELNET && INSTALL_ATTACHE_DNS#define	TELNET_ESCAPE_CHAR	(']' & 077)static void telnet_read(struct sty *, char *, void *);struct telnet_state {  struct sty *sty;  struct tn_connection *tn;  boolean_t remote_echoing;  bits16_t port;};static void telnet_escape(struct sty *sty, char *c, void *cookie){  struct telnet_state *state = cookie;  switch (*c) {   case TELNET_ESCAPE_CHAR:    tn_send_text(state->tn, (unsigned char *) c, 1);    break;   case 'c': case 'C':    tn_send_close(state->tn);    break;   case 'a': case 'A':    tn_send_ayt(state->tn);    break;   case '?':    sty_puts(sty, "\nc  close connection\na  send AYT\n?  type this cruft\n");    break;   default:    sty_printf(sty, "\nUnknown escape character '%c'\n", *c);    break;  }  sty_read(sty, telnet_read, 0, cookie);}static void telnet_read(struct sty *sty, char *c, void *cookie){  struct telnet_state *state = cookie;  if (*c == TELNET_ESCAPE_CHAR) {    sty_read(sty, telnet_escape, 0, cookie);  } else {    tn_send_text(state->tn, (unsigned char *) c, 1);    sty_read(sty, telnet_read, 0, cookie);  }}static void telnet_text  (struct tn_connection *tn, unsigned char text[], unsigned length){  struct telnet_state *state = tn_get_cookie(tn);  sty_write(state->sty, (char *) text, length);}static void telnet_open(struct tn_connection *tn){  struct telnet_state *state = tn_get_cookie(tn);  sty_printf(state->sty, "open\nEscape character is '%s%c'\n",	     (TELNET_ESCAPE_CHAR < 0100 ? "^" : ""),	     (TELNET_ESCAPE_CHAR < 0100 ? 0100 : 0) | TELNET_ESCAPE_CHAR);  state->sty->flags |= STY_FLAG_RAWMODE;  sty_read(state->sty, telnet_read, 0, state);}static void telnet_close(struct tn_connection *tn){  struct telnet_state *state = tn_get_cookie(tn);  struct sty *sty;  if (!state)    return;  sty = state->sty;  sty_puts(sty, "\nConnection closed\n");  sty->flags &= ~STY_FLAG_RAWMODE;  if (state->remote_echoing)    sty->flags |= STY_FLAG_ECHOING;  GLUE_FREE(state);  sty_read(sty, do_cmd, prompt, 0);}static void telnet_error(struct tn_connection *tn, enum tn_error code){  struct telnet_state *state = tn_get_cookie(tn);  struct sty *sty = state->sty;  int i = 0;  while (i < TN_ERRTAB && tn_errtab[i].code != code)    ++i;  if (tn_connection_established(tn))    sty_puts(sty, "\n[telnet error: ");  if (i < TN_ERRTAB)    sty_puts(sty, tn_errtab[i].name);  else    sty_printf(sty, "unknown error %d", (int) code);  if (tn_connection_established(tn))    sty_puts(sty, "]\n");}static int telnet_echo  (struct tn_connection *tn,   enum tn_ctl control,   enum tn_opt option,   unsigned char *text,   unsigned text_length,   int entire){  struct telnet_state *state = tn_get_cookie(tn);  switch (control) {   case TN_CTL_WILL:    /*     * Peer is offering to take responsibility for echo.     * Give it to her if it's ours to give.     */    if (state->sty->flags & STY_FLAG_ECHOING) {      state->sty->flags &= ~STY_FLAG_ECHOING;      state->remote_echoing = 1;      return 1;    }    return 0;   case TN_CTL_WONT:    /*     * Peer is refusing responsibility for echo.     * Turn it back on locally if we had it in the first place.     */    if (state->remote_echoing) {      state->sty->flags |= STY_FLAG_ECHOING;      state->remote_echoing = 0;    }    return 0;   default:    /*     * Refuse any other request.     */    return 0;  }}static tn_option_dispatch_vector telnet_options = {  tn_handle_transmit_binary,	/* TN_OPT_TRANSMIT_BINARY */  telnet_echo,			/* TN_OPT_ECHO */  0,     			/* TN_OPT_RCP */  tn_handle_suppress_go_ahead,	/* TN_OPT_SUPPRESS_GO_AHEAD */  0,     			/* TN_OPT_NAMS */  tn_handle_status,		/* TN_OPT_STATUS */  0,     			/* TN_OPT_TIMING_MARK */  0,     			/* TN_OPT_RCTE */  0,     			/* TN_OPT_NAOL */  0,     			/* TN_OPT_NAOP */  0,     			/* TN_OPT_NAOCRD */  0,     			/* TN_OPT_NAOHTS */  0,     			/* TN_OPT_HAOHTD */  0,     			/* TN_OPT_NAOFFD */  0,     			/* TN_OPT_NAOVTS */  0,     			/* TN_OPT_NAOVTD */  0,     			/* TN_OPT_NAOLFD */  0,     			/* TN_OPT_EXTEND_ASCII */  0,     			/* TN_OPT_LOGOUT */  0,     			/* TN_OPT_BM */  0,     			/* TN_OPT_DET */  0,     			/* TN_OPT_SUPDUP */  0,     			/* TN_OPT_SUPDUP_OUTPUT */  0,     			/* TN_OPT_SEND_LOCATION */  0,     			/* TN_OPT_TERMINAL_TYPE */  tn_handle_end_of_record,	/* TN_OPT_END_OF_RECORD */  0,     			/* TN_OPT_TUID */  0,     			/* TN_OPT_OUTMRK */  0,     			/* TN_OPT_TTYLOC */  0,     			/* TN_OPT_3270_REGIME */  0,     			/* TN_OPT_X3_PAD */  0,     			/* TN_OPT_NAWS */  0,     			/* TN_OPT_TERMINAL_SPEED */  0,     			/* TN_OPT_TOGGLE_FLOW_CONTROL */  0,     			/* TN_OPT_LINEMODE */  0     			/* TN_OPT_XDISPLOC */};static struct tn_dispatch telnet_dispatch = {  telnet_text,			/* Text */  0,				/* IP */  0,				/* AO */  0,				/* AYT */  0,				/* EL */  0,				/* EC */  0,				/* EOR */  0,				/* BRK */  0,				/* GA */  telnet_open,			/* Open */  telnet_close,			/* Close */  telnet_error,			/* Error */  telnet_options		/* Option dispatch vector */};static void telnet_dns_won  (struct dns_query *query, char *dname, int n, ipaddr_t addrs[], void *cookie){  struct telnet_state *state = cookie;  struct tcb *tcb = 0;  struct tn_connection *tn = 0;  sty_printf(state->sty, "ok\nConnecting to host %s (%s)...",	     dname, ipaddr_to_string(&addrs[0], 0, 0));  state->remote_echoing = 0;  if ((tcb = tcp_create()) == 0) {    sty_puts(state->sty, "failed, couldn't allocate TCB\n");    goto lose;  }  if ((tn = tn_create_connection(tcb, &telnet_dispatch, 0)) == 0) {    sty_puts(state->sty, "failed, couldn't allocate tn_connection\n");    goto lose;  }  tcp_set_remote_ipaddr(tcb, &addrs[0]);  tcp_set_remote_port(tcb, state->port);  if (tcp_start(tcb, TCP_ACTIVE) != TCP_START_OK) {    sty_puts(state->sty, "failed, couldn't start TCP connection\n");    goto lose;  }  state->tn = tn;  tn_set_cookie(state->tn, state);  return; lose:  if (tcb)    tcp_abort(tcb);  if (tn)    GLUE_FREE(tn);  GLUE_FREE(state);  sty_read(state->sty, do_cmd, prompt, 0);}#if INSTALL_SNARK_ATTACHE_34_DNS_COMPATstatic void telnet_dns_won_compat  (struct dns_query *query, char *dname, int n, inaddr_t addrs[], void *cookie){  snark_attache_dns_34_compat(telnet_dns_won, query, dname, n, addrs, cookie);}#endif /* INSTALL_SNARK_ATTACHE_34_DNS_COMPAT */static void telnet_dns_err  (struct dns_query *query, enum dns_error error, void *cookie){  struct telnet_state *state = cookie;  display_dns_error(state->sty, query, error);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?