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 + -
显示快捷键?