Пример #1
0
int main(int argc, char **argv) {
    struct sigaction act;

    memset(&act, 0, sizeof(act));
    act.sa_handler = sigint_handler;

    DIE_IF_ERR(io_loop_init(&loop));
    DIE_IF_ERR(io_tcp_server(&loop, &server, "0.0.0.0", "5000"));
    DIE_IF_ERR(io_listen_start(&server, incoming_connection));
    DIE_IF_ERR(sigaction(SIGINT, &act, NULL));
    puts("echo server is up...");
    DIE_IF_ERR(io_loop_run(&loop));
    return 0;
}
Пример #2
0
int main(int argc, char **argv) {
   struct sigaction act;
   io_handle_t serv1, serv2, serv3, servr, watcher;
   sdp_session_t *session;

   memset(&act, 0, sizeof(act));
   act.sa_handler = sigint_handler;
   
   DIE_IF_ERR(storage_segregate(&storage, 12, 512));

   DIE_IF_ERR(io_loop_init(&loop));
   DIE_IF_ERR(io_file(&loop, &backup, "backup.txt", O_RDWR));
   DIE_IF_ERR(io_inotify(&loop, &watcher));
   DIE_IF_ERR(io_tcp_server(&loop, &serv1, "0.0.0.0", "3000"));
   DIE_IF_ERR(io_tcp_server(&loop, &serv2, "0.0.0.0", "4000"));
   DIE_IF_ERR(io_tcp_server(&loop, &serv3, "0.0.0.0", "5000"));
   DIE_IF_ERR(io_rfcomm_server(&loop, &servr, BDADDR_ANY, 4));
   
   lseek(backup.fd, 0, SEEK_END);

   DIE_IF_ERR(io_watch_start(&watcher, "/dev", IN_CREATE | IN_DELETE, file_changed));
   DIE_IF_ERR(io_channel(&channel));
   DIE_IF_ERR(io_channel_join(&channel, &backup, backup_updated));
   DIE_IF_ERR(io_channel_join(&channel, &tcp1, serl_updated));

   if(try_serial(&loop, &serl) == -1) puts("warning: arduino not connected.");
   else DIE_IF_ERR(io_publish_start(&serl, &channel, data_published));

   DIE_IF_ERR(io_listen_start(&serv1, new_tcp1_conn));
   DIE_IF_ERR(io_listen_start(&serv2, new_tcp2_conn));
   DIE_IF_ERR(io_listen_start(&serv3, new_tcp3_conn));
   DIE_IF_ERR(io_listen_start(&servr, new_rfcm_conn));

   session = io_rfcomm_advertise(4, name, desc, uuid128);
   DIE_IF_ERR(sigaction(SIGINT, &act, NULL));
   puts("pi server is up...");
   DIE_IF_ERR(io_loop_run(&loop));

   io_channel_close(&channel);
   storage_collapse(&storage);
   io_rfcomm_unadvertise(session);
   return 0;
}
Пример #3
0
static struct child*
start_child(struct msg_shex_hello* shex_hello)
{
    if (shex_hello->nr_argv < 2)
        die(ECOMM, "insufficient arguments given");

    SCOPED_RESLIST(rl_args);
    char** child_args = read_child_arglist(shex_hello->nr_argv);
    reslist_pop_nodestroy(rl_args);
    struct child_start_info csi = {
        .flags = CHILD_SETSID,
        .exename = child_args[0],
        .argv = (const char* const *) child_args + 1,
        .pty_setup = setup_pty,
        .pty_setup_data = shex_hello,
        .deathsig = -SIGHUP,
    };

    if (shex_hello->si[0].pty_p)
        csi.flags |= CHILD_PTY_STDIN;
    if (shex_hello->si[1].pty_p)
        csi.flags |= CHILD_PTY_STDOUT;
    if (shex_hello->si[2].pty_p)
        csi.flags |= CHILD_PTY_STDERR;

    return child_start(&csi);
}

static void __attribute__((noreturn))
re_exec_as_root()
{
    execlp("su", "su", "-c", xaprintf("%s stub", orig_argv0), NULL);
    die_errno("execlp of su");
}

int
stub_main(int argc, const char** argv)
{
    if (argc != 1)
        die(EINVAL, "this command is internal");

    /* XMKRAW_SKIP_CLEANUP so we never change from raw back to cooked
     * mode on exit.  The connection dies on exit anyway, and
     * resetting the pty can send some extra bytes that can confuse
     * our peer. */

    if (isatty(0))
        xmkraw(0, XMKRAW_SKIP_CLEANUP);

    if (isatty(1))
        xmkraw(1, XMKRAW_SKIP_CLEANUP);

    printf(FB_ADB_PROTO_START_LINE "\n", build_time, (int) getuid());
    fflush(stdout);

    struct msg_shex_hello* shex_hello;
    struct msg* mhdr = read_msg(0, read_all_adb_encoded);

    if (mhdr->type == MSG_EXEC_AS_ROOT)
        re_exec_as_root(); // Never returns

    if (mhdr->type != MSG_SHEX_HELLO ||
        mhdr->size < sizeof (struct msg_shex_hello))
    {
        die(ECOMM, "bad hello");
    }

    shex_hello = (struct msg_shex_hello*) mhdr;

    struct child* child = start_child(shex_hello);
    struct stub stub;
    memset(&stub, 0, sizeof (stub));
    stub.child = child;
    struct fb_adb_sh* sh = &stub.sh;

    sh->process_msg = stub_process_msg;
    sh->max_outgoing_msg = shex_hello->maxmsg;
    sh->nrch = 5;
    struct channel** ch = xalloc(sh->nrch * sizeof (*ch));

    ch[FROM_PEER] = channel_new(fdh_dup(0),
                                shex_hello->stub_recv_bufsz,
                                CHANNEL_FROM_FD);

    ch[FROM_PEER]->window = UINT32_MAX;
    ch[FROM_PEER]->adb_encoding_hack = true;
    replace_with_dev_null(0);

    ch[TO_PEER] = channel_new(fdh_dup(1),
                              shex_hello->stub_send_bufsz,
                              CHANNEL_TO_FD);
    replace_with_dev_null(1);

    ch[CHILD_STDIN] = channel_new(child->fd[0],
                                  shex_hello->si[0].bufsz,
                                  CHANNEL_TO_FD);

    ch[CHILD_STDIN]->track_bytes_written = true;
    ch[CHILD_STDIN]->bytes_written =
        ringbuf_room(ch[CHILD_STDIN]->rb);

    ch[CHILD_STDOUT] = channel_new(child->fd[1],
                                   shex_hello->si[1].bufsz,
                                   CHANNEL_FROM_FD);
    ch[CHILD_STDOUT]->track_window = true;

    ch[CHILD_STDERR] = channel_new(child->fd[2],
                                   shex_hello->si[2].bufsz,
                                   CHANNEL_FROM_FD);
    ch[CHILD_STDERR]->track_window = true;

    sh->ch = ch;
    io_loop_init(sh);

    PUMP_WHILE(sh, (!channel_dead_p(ch[FROM_PEER]) &&
                    !channel_dead_p(ch[TO_PEER]) &&
                    (!channel_dead_p(ch[CHILD_STDOUT]) ||
                     !channel_dead_p(ch[CHILD_STDERR]))));

    if (channel_dead_p(ch[FROM_PEER]) || channel_dead_p(ch[TO_PEER])) {
        //
        // If we lost our peer connection, make sure the child sees
        // SIGHUP instead of seeing its stdin close: just drain any
        // internally-buffered IO and exit.  When we lose the pty, the
        // child gets SIGHUP.
        //

        // Make sure we won't be getting any more commands.

        channel_close(ch[FROM_PEER]);
        channel_close(ch[TO_PEER]);

        PUMP_WHILE(sh, (!channel_dead_p(ch[FROM_PEER]) ||
                        !channel_dead_p(ch[TO_PEER])));

        // Drain output buffers
        channel_close(ch[CHILD_STDIN]);
        PUMP_WHILE(sh, !channel_dead_p(ch[CHILD_STDIN]));
        return 128 + SIGHUP;
    }

    //
    // Clean exit: close standard handles and drain IO.  Peer still
    // has no idea that we're exiting.  Get exit status, send that to
    // peer, then cleanly shut down the peer connection.
    //

    dbg("clean exit");

    channel_close(ch[CHILD_STDIN]);
    channel_close(ch[CHILD_STDOUT]);
    channel_close(ch[CHILD_STDERR]);

    PUMP_WHILE (sh, (!channel_dead_p(ch[CHILD_STDIN]) ||
                     !channel_dead_p(ch[CHILD_STDOUT]) ||
                     !channel_dead_p(ch[CHILD_STDERR])));

    send_exit_message(child_wait(child), sh);
    channel_close(ch[TO_PEER]);

    PUMP_WHILE(sh, !channel_dead_p(ch[TO_PEER]));
    channel_close(ch[FROM_PEER]);
    PUMP_WHILE(sh, !channel_dead_p(ch[FROM_PEER]));
    return 0;
}