📄 chat.c
字号:
break; n += nr; } fclose(f); /* use the string we got as the string to send, but trim off the final newline if any. */ if (n > 0 && file_data[n-1] == '\n') --n; file_data[n] = 0; s = file_data; } } if (strcmp(s, "EOT") == 0) s = "^D\\c"; else if (strcmp(s, "BREAK") == 0) s = "\\K\\c"; if (!put_string(s)) fatal(1, "Failed");}int get_char(){ int status; char c; status = read(0, &c, 1); switch (status) { case 1: return ((int)c & 0x7F); default: logf("warning: read() on stdin returned %d", status); case -1: if ((status = fcntl(0, F_GETFL, 0)) == -1) fatal(2, "Can't get file mode flags on stdin: %m"); if (fcntl(0, F_SETFL, status & ~O_NONBLOCK) == -1) fatal(2, "Can't set file mode flags on stdin: %m"); return (-1); }}int put_char(c)int c;{ int status; char ch = c; usleep(10000); /* inter-character typing delay (?) */ status = write(1, &ch, 1); switch (status) { case 1: return (0); default: logf("warning: write() on stdout returned %d", status); case -1: if ((status = fcntl(0, F_GETFL, 0)) == -1) fatal(2, "Can't get file mode flags on stdin, %m"); if (fcntl(0, F_SETFL, status & ~O_NONBLOCK) == -1) fatal(2, "Can't set file mode flags on stdin: %m"); return (-1); }}int write_char (c)int c;{ if (alarmed || put_char(c) < 0) { alarm(0); alarmed = 0; if (verbose) { if (errno == EINTR || errno == EWOULDBLOCK) logf(" -- write timed out"); else logf(" -- write failed: %m"); } return (0); } return (1);}int put_string (s)register char *s;{ quiet = 0; s = clean(s, 1); if (verbose) { if (quiet) logf("send (??????)"); else logf("send (%v)", s); } alarm(timeout); alarmed = 0; while (*s) { register char c = *s++; if (c != '\\') { if (!write_char (c)) return 0; continue; } c = *s++; switch (c) { case 'd': sleep(1); break; case 'K': break_sequence(); break; case 'p': usleep(10000); /* 1/100th of a second (arg is microseconds) */ break; default: if (!write_char (c)) return 0; break; } } alarm(0); alarmed = 0; return (1);}/* * Echo a character to stderr. * When called with -1, a '\n' character is generated when * the cursor is not at the beginning of a line. */void echo_stderr(n)int n;{ static int need_lf; char *s; switch (n) { case '\r': /* ignore '\r' */ break; case -1: if (need_lf == 0) break; /* fall through */ case '\n': write(2, "\n", 1); need_lf = 0; break; default: s = character(n); write(2, s, strlen(s)); need_lf = 1; break; }}/* * 'Wait for' this string to appear on this file descriptor. */int get_string(string)register char *string;{ char temp[STR_LEN]; int c, printed = 0, len, minlen; register char *s = temp, *end = s + STR_LEN; char *logged = temp; fail_reason = (char *)0; string = clean(string, 0); len = strlen(string); minlen = (len > sizeof(fail_buffer)? len: sizeof(fail_buffer)) - 1; if (verbose) logf("expect (%v)", string); if (len > STR_LEN) { logf("expect string is too long"); exit_code = 1; return 0; } if (len == 0) { if (verbose) logf("got it"); return (1); } alarm(timeout); alarmed = 0; while ( ! alarmed && (c = get_char()) >= 0) { int n, abort_len, report_len; if (echo) echo_stderr(c); if (verbose && c == '\n') { if (s == logged) logf(""); /* blank line */ else logf("%0.*v", s - logged, logged); logged = s + 1; } *s++ = c; if (verbose && s >= logged + 80) { logf("%0.*v", s - logged, logged); logged = s; } if (Verbose) { if (c == '\n') fputc( '\n', stderr ); else if (c != '\r') fprintf( stderr, "%s", character(c) ); } if (!report_gathering) { for (n = 0; n < n_reports; ++n) { if ((report_string[n] != (char*) NULL) && s - temp >= (report_len = strlen(report_string[n])) && strncmp(s - report_len, report_string[n], report_len) == 0) { time_t time_now = time ((time_t*) NULL); struct tm* tm_now = localtime (&time_now); strftime (report_buffer, 20, "%b %d %H:%M:%S ", tm_now); strcat (report_buffer, report_string[n]); report_string[n] = (char *) NULL; report_gathering = 1; break; } } } else { if (!iscntrl (c)) { int rep_len = strlen (report_buffer); report_buffer[rep_len] = c; report_buffer[rep_len + 1] = '\0'; } else { report_gathering = 0; fprintf (report_fp, "chat: %s\n", report_buffer); } } if (s - temp >= len && c == string[len - 1] && strncmp(s - len, string, len) == 0) { if (verbose) { if (s > logged) logf("%0.*v", s - logged, logged); logf(" -- got it\n"); } alarm(0); alarmed = 0; return (1); } for (n = 0; n < n_aborts; ++n) { if (s - temp >= (abort_len = strlen(abort_string[n])) && strncmp(s - abort_len, abort_string[n], abort_len) == 0) { if (verbose) { if (s > logged) logf("%0.*v", s - logged, logged); logf(" -- failed"); } alarm(0); alarmed = 0; exit_code = n + 4; strcpy(fail_reason = fail_buffer, abort_string[n]); return (0); } } if (s >= end) { if (logged < s - minlen) { if (verbose) logf("%0.*v", s - logged, logged); logged = s; } s -= minlen; memmove(temp, s, minlen); logged = temp + (logged - s); s = temp + minlen; } if (alarmed && verbose) logf("warning: alarm synchronization problem"); } alarm(0); if (verbose && printed) { if (alarmed) logf(" -- read timed out"); else logf(" -- read failed: %m"); } exit_code = 3; alarmed = 0; return (0);}/* * Gross kludge to handle Solaris versions >= 2.6 having usleep. */#ifdef SOL2#include <sys/param.h>#if MAXUID > 65536 /* then this is Solaris 2.6 or later */#undef NO_USLEEP#endif#endif /* SOL2 */#ifdef NO_USLEEP#include <sys/types.h>#include <sys/time.h>/* usleep -- support routine for 4.2BSD system call emulations last edit: 29-Oct-1984 D A Gwyn */extern int select();intusleep( usec ) /* returns 0 if ok, else -1 */ long usec; /* delay in microseconds */{ static struct { /* `timeval' */ long tv_sec; /* seconds */ long tv_usec; /* microsecs */ } delay; /* _select() timeout */ delay.tv_sec = usec / 1000000L; delay.tv_usec = usec % 1000000L; return select(0, (long *)0, (long *)0, (long *)0, &delay);}#endifvoidpack_array (array, end) char **array; /* The address of the array of string pointers */ int end; /* The index of the next free entry before CLR_ */{ int i, j; for (i = 0; i < end; i++) { if (array[i] == NULL) { for (j = i+1; j < end; ++j) if (array[j] != NULL) array[i++] = array[j]; for (; i < end; ++i) array[i] = NULL; break; } }}/* * vfmtmsg - format a message into a buffer. Like vsprintf except we * also specify the length of the output buffer, and we handle the * %m (error message) format. * Doesn't do floating-point formats. * Returns the number of chars put into buf. */#define OUTCHAR(c) (buflen > 0? (--buflen, *buf++ = (c)): 0)intvfmtmsg(buf, buflen, fmt, args) char *buf; int buflen; const char *fmt; va_list args;{ int c, i, n; int width, prec, fillch; int base, len, neg, quoted; unsigned long val = 0; char *str, *buf0; const char *f; unsigned char *p; char num[32]; static char hexchars[] = "0123456789abcdef"; buf0 = buf; --buflen; while (buflen > 0) { for (f = fmt; *f != '%' && *f != 0; ++f) ; if (f > fmt) { len = f - fmt; if (len > buflen) len = buflen; memcpy(buf, fmt, len); buf += len; buflen -= len; fmt = f; } if (*fmt == 0) break; c = *++fmt; width = prec = 0; fillch = ' '; if (c == '0') { fillch = '0'; c = *++fmt; } if (c == '*') { width = va_arg(args, int); c = *++fmt; } else { while (isdigit(c)) { width = width * 10 + c - '0'; c = *++fmt; } } if (c == '.') { c = *++fmt; if (c == '*') { prec = va_arg(args, int); c = *++fmt; } else { while (isdigit(c)) { prec = prec * 10 + c - '0'; c = *++fmt; } } } str = 0; base = 0; neg = 0; ++fmt; switch (c) { case 'd': i = va_arg(args, int); if (i < 0) { neg = 1; val = -i; } else val = i; base = 10; break; case 'o': val = va_arg(args, unsigned int); base = 8; break; case 'x': val = va_arg(args, unsigned int); base = 16; break; case 'p': val = (unsigned long) va_arg(args, void *); base = 16; neg = 2; break; case 's': str = va_arg(args, char *); break; case 'c': num[0] = va_arg(args, int); num[1] = 0; str = num; break; case 'm': str = strerror(errno); break; case 'v': /* "visible" string */ case 'q': /* quoted string */ quoted = c == 'q'; p = va_arg(args, unsigned char *); if (fillch == '0' && prec > 0) { n = prec; } else { n = strlen((char *)p); if (prec > 0 && prec < n) n = prec; } while (n > 0 && buflen > 0) { c = *p++; --n; if (!quoted && c >= 0x80) { OUTCHAR('M'); OUTCHAR('-'); c -= 0x80; } if (quoted && (c == '"' || c == '\\')) OUTCHAR('\\'); if (c < 0x20 || (0x7f <= c && c < 0xa0)) { if (quoted) { OUTCHAR('\\'); switch (c) { case '\t': OUTCHAR('t'); break; case '\n': OUTCHAR('n'); break; case '\b': OUTCHAR('b'); break; case '\f': OUTCHAR('f'); break; default: OUTCHAR('x'); OUTCHAR(hexchars[c >> 4]); OUTCHAR(hexchars[c & 0xf]); } } else { if (c == '\t') OUTCHAR(c); else { OUTCHAR('^'); OUTCHAR(c ^ 0x40); } } } else OUTCHAR(c); } continue; default: *buf++ = '%'; if (c != '%') --fmt; /* so %z outputs %z etc. */ --buflen; continue; } if (base != 0) { str = num + sizeof(num); *--str = 0; while (str > num + neg) { *--str = hexchars[val % base]; val = val / base; if (--prec <= 0 && val == 0) break; } switch (neg) { case 1: *--str = '-'; break; case 2: *--str = 'x'; *--str = '0'; break; } len = num + sizeof(num) - 1 - str; } else { len = strlen(str); if (prec > 0 && len > prec) len = prec; } if (width > 0) { if (width > buflen) width = buflen; if ((n = width - len) > 0) { buflen -= n; for (; n > 0; --n) *buf++ = fillch; } } if (len > buflen) len = buflen; memcpy(buf, str, len); buf += len; buflen -= len; } *buf = 0; return buf - buf0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -