Ignore:
Timestamp:
Jan 1, 2014, 12:47:38 AM (10 years ago)
Author:
Bruno Cornec
Message:
  • Update mindi-busybox to 1.21.1
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/3.2/mindi-busybox/miscutils/conspy.c

    r2725 r3232  
    1111 */
    1212
    13 //applet:IF_CONSPY(APPLET(conspy, _BB_DIR_BIN, _BB_SUID_DROP))
     13//applet:IF_CONSPY(APPLET(conspy, BB_DIR_BIN, BB_SUID_DROP))
    1414
    1515//kbuild:lib-$(CONFIG_CONSPY) += conspy.o
     
    1717//config:config CONSPY
    1818//config:   bool "conspy"
    19 //config:   default n
    20 //config:   depends on PLATFORM_LINUX
     19//config:   default y
     20//config:   select PLATFORM_LINUX
    2121//config:   help
    2222//config:     A text-mode VNC like program for Linux virtual terminals.
     
    2626
    2727//usage:#define conspy_trivial_usage
    28 //usage:    "[-vcsndf] [-x COL] [-y LINE] [CONSOLE_NO]"
     28//usage:    "[-vcsndfFQ] [-x COL] [-y LINE] [CONSOLE_NO]"
    2929//usage:#define conspy_full_usage "\n\n"
    3030//usage:     "A text-mode VNC like program for Linux virtual consoles."
    3131//usage:     "\nTo exit, quickly press ESC 3 times."
    3232//usage:     "\n"
    33 //usage:     "\nOptions:"
    3433//usage:     "\n    -v  Don't send keystrokes to the console"
    35 //usage:     "\n    -c  Create missing devices in /dev"
     34//usage:     "\n    -c  Create missing /dev/{tty,vcsa}N"
    3635//usage:     "\n    -s  Open a SHELL session"
    3736//usage:     "\n    -n  Black & white"
    3837//usage:     "\n    -d  Dump console to stdout"
    3938//usage:     "\n    -f  Follow cursor"
     39//usage:     "\n    -F  Assume console is on a framebuffer device"
     40//usage:     "\n    -Q  Disable exit on ESC-ESC-ESC"
    4041//usage:     "\n    -x COL  Starting column"
    4142//usage:     "\n    -y LINE Starting line"
     
    4445#include <sys/kd.h>
    4546
    46 
    4747#define ESC "\033"
     48#define CURSOR_ON   -1
     49#define CURSOR_OFF  1
     50
     51#define DEV_TTY     "/dev/tty"
     52#define DEV_VCSA    "/dev/vcsa"
    4853
    4954struct screen_info {
     
    7479    unsigned line;
    7580    smallint curoff; // unknown:0 cursor on:-1 cursor off:1
    76     char attrbuf[sizeof(ESC"[0;1;5;30;40m")];
     81    char attrbuf[sizeof("0;1;5;30;40m")];
    7782    // remote console
    7883    struct screen_info remote;
    7984    // saved local tty terminfo
    8085    struct termios term_orig;
    81     char vcsa_name[sizeof("/dev/vcsaNN")];
     86    char vcsa_name[sizeof(DEV_VCSA "NN")];
    8287};
    8388
     
    8590#define INIT_G() do { \
    8691    SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \
    87     G.attrbuf[0] = '\033'; \
    88     G.attrbuf[1] = '['; \
    8992    G.width = G.height = UINT_MAX; \
    9093    G.last_attr--; \
     
    9497    FLAG_v,  // view only
    9598    FLAG_c,  // create device if need
     99    FLAG_Q,  // never exit
    96100    FLAG_s,  // session
    97101    FLAG_n,  // no colors
    98102    FLAG_d,  // dump screen
    99103    FLAG_f,  // follow cursor
     104    FLAG_F,  // framebuffer
    100105};
    101106#define FLAG(x) (1 << FLAG_##x)
    102107#define BW (option_mask32 & FLAG(n))
    103108
     109static void putcsi(const char *s)
     110{
     111    fputs(ESC"[", stdout);
     112    fputs(s, stdout);
     113}
     114
    104115static void clrscr(void)
    105116{
    106117    // Home, clear till end of screen
    107     fputs(ESC"[1;1H" ESC"[J", stdout);
     118    putcsi("1;1H" ESC"[J");
    108119    G.col = G.line = 0;
    109120}
     
    113124    if (G.curoff != state) {
    114125        G.curoff = state;
    115         fputs(ESC"[?25", stdout);
     126        putcsi("?25");
    116127        bb_putchar("h?l"[1 + state]);
    117128    }
     
    127138}
    128139
     140static void cleanup(int code) NORETURN;
    129141static void cleanup(int code)
    130142{
    131     set_cursor(-1); // cursor on
     143    set_cursor(CURSOR_ON);
    132144    tcsetattr(G.kbd_fd, TCSANOW, &G.term_orig);
    133145    if (ENABLE_FEATURE_CLEAN_UP) {
     
    136148    // Reset attributes
    137149    if (!BW)
    138         fputs(ESC"[0m", stdout);
     150        putcsi("0m");
    139151    bb_putchar('\n');
    140     if (code > 1)
     152    if (code > EXIT_FAILURE)
    141153        kill_myself_with_sig(code);
    142154    exit(code);
     
    159171        G.data = xzalloc(2 * i);
    160172    }
    161     else if (G.size != i) {
    162         cleanup(1);
     173    if (G.size != i) {
     174        cleanup(EXIT_FAILURE);
    163175    }
    164176    data = G.data + G.current;
     
    170182            unsigned y = i - G.y; // if will catch i < G.y too
    171183
    172             if (CHAR(data) < ' ')
    173                 CHAR(data) = ' ';
    174184            if (y >= G.height || x >= G.width)
    175185                DATA(data) = 0;
     186            else {
     187                uint8_t ch = CHAR(data);
     188                if (ch < ' ')
     189                    CHAR(data) = ch | 0x40;
     190                else if (ch > 0x7e)
     191                    CHAR(data) = '?';
     192            }
    176193        }
    177194    }
     
    181198{
    182199    if (!BW) {
     200        uint8_t attr_diff;
    183201        uint8_t attr = ATTR(data);
    184         //uint8_t attr = ATTR(data) >> 1; // for framebuffer console
    185         uint8_t attr_diff = G.last_attr ^ attr;
    186 
     202
     203        if (option_mask32 & FLAG(F)) {
     204            attr >>= 1;
     205        }
     206        attr_diff = G.last_attr ^ attr;
    187207        if (attr_diff) {
    188208// Attribute layout for VGA compatible text videobuffer:
     
    215235            char *ptr;
    216236
    217             ptr = G.attrbuf + 2; // skip "ESC ["
     237            ptr = G.attrbuf;
    218238
    219239            // (G.last_attr & ~attr) has 1 only where
     
    246266                *ptr++ = '4';
    247267                *ptr++ = color[(attr & bg_mask) >> 4];
    248                 *ptr++ = ';';
    249             }
    250             if (ptr != G.attrbuf + 2) {
     268                ptr++; // last attribute
     269            }
     270            if (ptr != G.attrbuf) {
    251271                ptr[-1] = 'm';
    252272                *ptr = '\0';
    253                 fputs(G.attrbuf, stdout);
     273                putcsi(G.attrbuf);
    254274            }
    255275        }
     
    294314    unsigned cx = G.remote.cursor_x - G.x;
    295315    unsigned cy = G.remote.cursor_y - G.y;
    296     int cursor = 1;
     316    int cursor = CURSOR_OFF;
    297317
    298318    if (cx < G.width && cy < G.height) {
    299319        gotoxy(cx, cy);
    300         cursor = -1;
     320        cursor = CURSOR_ON;
    301321    }
    302322    set_cursor(cursor);
     
    317337    if (pid == 0) {
    318338        struct termios termchild;
    319         char *shell = getenv("SHELL");
    320 
    321         if (!shell)
    322             shell = (char *) DEFAULT_SHELL;
     339        const char *shell = get_shell_name();
     340
    323341        signal(SIGHUP, SIG_IGN);
    324342        // set tty as a controlling tty
     
    345363int conspy_main(int argc UNUSED_PARAM, char **argv)
    346364{
    347     char tty_name[sizeof("/dev/ttyNN")];
     365    char tty_name[sizeof(DEV_TTY "NN")];
    348366#define keybuf bb_common_bufsiz1
    349367    struct termios termbuf;
     
    355373        "viewonly\0"     No_argument "v"
    356374        "createdevice\0" No_argument "c"
     375        "neverquit\0"    No_argument "Q"
    357376        "session\0"      No_argument "s"
    358377        "nocolors\0"     No_argument "n"
    359378        "dump\0"         No_argument "d"
    360379        "follow\0"       No_argument "f"
     380        "framebuffer\0"  No_argument "F"
    361381        ;
    362382
     
    364384#endif
    365385    INIT_G();
    366     strcpy(G.vcsa_name, "/dev/vcsa");
     386    strcpy(G.vcsa_name, DEV_VCSA);
    367387
    368388    opt_complementary = "x+:y+"; // numeric params
    369     opts = getopt32(argv, "vcsndfx:y:", &G.x, &G.y);
     389    opts = getopt32(argv, "vcQsndfFx:y:", &G.x, &G.y);
    370390    argv += optind;
    371391    ttynum = 0;
    372392    if (argv[0]) {
    373393        ttynum = xatou_range(argv[0], 0, 63);
    374         sprintf(G.vcsa_name + sizeof("/dev/vcsa")-1, "%u", ttynum);
    375     }
    376     sprintf(tty_name, "%s%u", "/dev/tty", ttynum);
     394        sprintf(G.vcsa_name + sizeof(DEV_VCSA)-1, "%u", ttynum);
     395    }
     396    sprintf(tty_name, "%s%u", DEV_TTY, ttynum);
    377397    if (opts & FLAG(c)) {
    378398        if ((opts & (FLAG(s)|FLAG(v))) != FLAG(v))
     
    485505        case -1:
    486506            if (errno != EINTR)
    487                 cleanup(1);
     507                goto abort;
    488508            break;
    489509        case 0:
     
    496516            bytes_read = read(G.kbd_fd, k, sizeof(keybuf) - G.key_count);
    497517            if (bytes_read < 0)
    498                 cleanup(1);
     518                goto abort;
    499519
    500520            // Do exit processing
    501             for (i = 0; i < bytes_read; i++) {
    502                 if (k[i] != '\033')
    503                     G.escape_count = 0;
    504                 else if (++G.escape_count >= 3)
    505                     cleanup(0);
     521            if (!(option_mask32 & FLAG(Q))) {
     522                for (i = 0; i < bytes_read; i++) {
     523                    if (k[i] != '\033')
     524                        G.escape_count = -1;
     525                    if (++G.escape_count >= 3)
     526                        cleanup(EXIT_SUCCESS);
     527                }
    506528            }
    507529        }
    508530        poll_timeout_ms = 250;
     531        if (option_mask32 & FLAG(v)) continue;
    509532
    510533        // Insert all keys pressed into the virtual console's input
     
    512535        // code mode - giving ASCII characters to a program expecting
    513536        // scan codes will confuse it.
    514         if (!(option_mask32 & FLAG(v)) && G.escape_count == 0) {
     537        G.key_count += bytes_read;
     538        if (G.escape_count == 0) {
    515539            int handle, result;
    516540            long kbd_mode;
    517541
    518             G.key_count += bytes_read;
    519542            handle = xopen(tty_name, O_WRONLY);
    520543            result = ioctl(handle, KDGKBMODE, &kbd_mode);
     
    522545                char *p = keybuf;
    523546
     547                G.ioerror_count = 0;
    524548                if (kbd_mode != K_XLATE && kbd_mode != K_UNICODE) {
    525549                    G.key_count = 0; // scan code mode
     
    537561                }
    538562            }
     563            // We sometimes get spurious IO errors on the TTY
     564            // as programs close and re-open it
     565            else if (errno != EIO || ++G.ioerror_count > 4) {
     566                if (ENABLE_FEATURE_CLEAN_UP)
     567                    close(handle);
     568                goto abort;
     569            }
    539570            // Close & re-open tty in case they have
    540571            // swapped virtual consoles
    541572            close(handle);
    542 
    543             // We sometimes get spurious IO errors on the TTY
    544             // as programs close and re-open it
    545             if (result >= 0)
    546                 G.ioerror_count = 0;
    547             else if (errno != EIO || ++G.ioerror_count > 4)
    548                 cleanup(1);
    549573        }
    550574    } /* while (1) */
    551 }
     575  abort:
     576    cleanup(EXIT_FAILURE);
     577}
Note: See TracChangeset for help on using the changeset viewer.