static int adb_receive(Plug plug, int urgent, char *data, int len) { Adb adb = (Adb) plug; if (adb->state == STATE_SENT_HELLO) { if (data[0]=='O') { // OKAY sk_write(adb->s,"0006shell:",10); adb->state = STATE_ASKED_FOR_SHELL; // wait for shell start response } else { if (data[0]=='F') { handle_fail(adb, data, len); } else { connection_fatal(adb->frontend, "Bad response after initial send"); } return 0; } } else if (adb->state == STATE_ASKED_FOR_SHELL) { if (data[0]=='O') { //OKAY adb->state = STATE_CONNECTED; // shell started, switch to terminal mode } else { if (data[0]=='F') { handle_fail(adb, data, len); } else { connection_fatal(adb->frontend, "Bad response waiting for shell start"); } return 0; } } else if (adb->state == STATE_WAITING_FOR_ERROR_MESSAGE) { do_fatal(adb, data, len); } else { c_write(adb, data, len); } return 1; }
/** the error might not be available when the error occurs; wait * a bit for more data to show up then assume that's the error message. */ static void handle_fail(Adb adb, char *data, int len) { // FAIL0003abc char message_length_hex[5]; unsigned long expected; memcpy(message_length_hex, data+4, 4); message_length_hex[4] = 0; expected = strtoul(message_length_hex, NULL, 16); if (len == expected + 8) do_fatal(adb, data+8, expected); else adb->state = STATE_WAITING_FOR_ERROR_MESSAGE; }
void handler(int sig) { pid_t pid = getpid(); int status, i; pid = wait(&status); kids--; for (i = 0; i < num_targets; i++) { if (target[i].pid == pid) { if (target[i].state == INACTIVE) { /* thread got an I/O error */ if (target[i].err_type == 0) { do_warn( _("%s: write error on target %d \"%s\" at offset %lld\n"), progname, i, target[i].name, target[i].position); } else { do_warn( _("%s: lseek64 error on target %d \"%s\" at offset %lld\n"), progname, i, target[i].name, target[i].position); } do_vfatal(target[i].error, _("Aborting target %d - reason"), i); if (kids == 0) { do_log( _("Aborting XFS copy - no more targets.\n")); check_errors(); pthread_exit(NULL); } signal(SIGCHLD, handler); return; } else { /* it just croaked it bigtime, log it */ do_warn( _("%s: thread %d died unexpectedly, target \"%s\" incomplete\n"), progname, i, target[i].name); do_warn(_("%s: offset was probably %lld\n"), progname, target[i].position); do_fatal(target[i].error, _("Aborting XFS copy - reason")); pthread_exit(NULL); } } } /* unknown child -- something very wrong */ do_warn(_("%s: Unknown child died (should never happen!)\n"), progname); die_perror(); pthread_exit(NULL); signal(SIGCHLD, handler); }