/* * a write to a closed pipe causes a note to be sent to * the process. */ static int32_t pipewrite(Chan *c, void *va, int32_t n, int64_t mm) { Proc *up = externup(); Pipe *p; if(0)if(!islo()) print("pipewrite hi %#p\n", getcallerpc()); // devmnt? if(waserror()) { /* avoid notes when pipe is a mounted queue */ if((c->flag & CMSG) == 0) postnote(up, 1, "sys: write on closed pipe", NUser); nexterror(); } p = c->aux; switch(PIPETYPE(c->qid.path)){ case Qdata0: n = qwrite(p->q[1], va, n); break; case Qdata1: n = qwrite(p->q[0], va, n); break; default: panic("pipewrite"); } poperror(); return n; }
/* * a write to a closed pipe causes a note to be sent to * the process. */ static long pipewrite(Chan *c, void *va, long n, vlong) { Pipe *p; if(!islo()) print("pipewrite hi %#p\n", getcallerpc(&c)); if(waserror()) { /* avoid notes when pipe is a mounted queue */ if((c->flag & CMSG) == 0) postnote(up, 1, "sys: write on closed pipe", NUser); nexterror(); } p = c->aux; switch(NETTYPE(c->qid.path)){ case Qdata0: n = qwrite(p->q[1], va, n); break; case Qdata1: n = qwrite(p->q[0], va, n); break; default: panic("pipewrite"); } poperror(); return n; }
/* * A write to a closed pipe causes an EPIPE error to be thrown. */ static long pipewrite(struct chan *c, void *va, long n, int64_t ignored) { Pipe *p; //Prog *r; p = c->aux; switch (NETTYPE(c->qid.path)) { case Qdata0: if (c->flag & O_NONBLOCK) n = qwrite_nonblock(p->q[1], va, n); else n = qwrite(p->q[1], va, n); break; case Qdata1: if (c->flag & O_NONBLOCK) n = qwrite_nonblock(p->q[0], va, n); else n = qwrite(p->q[0], va, n); break; default: panic("pipewrite"); } return n; }
/* * Print a string on the console. Convert \n to \r\n for serial * line consoles. Locking of the queues is left up to the screen * or uart code. Multi-line messages to serial consoles may get * interspersed with other messages. */ static void putstrn0(char *str, int n, int usewrite) { if(!islo()) usewrite = 0; /* * how many different output devices do we need? */ kmesgputs(str, n); /* * if someone is reading /dev/kprint, * put the message there. * if not and there's an attached bit mapped display, * put the message there. * * if there's a serial line being used as a console, * put the message there. */ if(kprintoq != nil && !qisclosed(kprintoq)){ if(usewrite) qwrite(kprintoq, str, n); else qiwrite(kprintoq, str, n); }else if(screenputs != nil) screenputs(str, n); uartputs(str, n); #if 0 // Plan 9 VX if(serialoq == nil){ uartputs(str, n); return; } while(n > 0) { t = memchr(str, '\n', n); if(t && !kbd.raw) { m = t-str; if(usewrite){ qwrite(serialoq, str, m); qwrite(serialoq, "\r\n", 2); } else { qiwrite(serialoq, str, m); qiwrite(serialoq, "\r\n", 2); } n -= m+1; str = t+1; } else { if(usewrite) qwrite(serialoq, str, n); else qiwrite(serialoq, str, n); break; } } #endif }
void idaapi dump_type_info(int file_id, const VTBL_info_t& vtbl_info, const qstring& type_name, const std::map<ea_t, VTBL_info_t>& vtbl_map) { struc_t * struc_type = get_struc(get_struc_id(type_name.c_str())); if (!struc_type) return; qstring file_entry_key; qstring key_hash; bool filtered = false; get_struct_key(struc_type, vtbl_info, file_entry_key, filtered, vtbl_map); get_hash_of_string(file_entry_key, key_hash); if (filtered) return; qstring file_entry_val; tinfo_t new_type = create_typedef(type_name.c_str()); if (new_type.is_correct() && new_type.print(&file_entry_val, NULL, PRTYPE_DEF | PRTYPE_1LINE)) { qstring line; line = key_hash + ";" + file_entry_key + ";"; line.cat_sprnt("%a;", vtbl_info.ea_begin); line += file_entry_val + ";"; if (rtti_vftables.count(vtbl_info.ea_begin) != 0) { VTBL_info_t vi = rtti_vftables[vtbl_info.ea_begin]; line += vi.vtbl_name; } line.rtrim(); line += "\r\n"; qwrite(file_id, line.c_str(), line.length()); } }
static long uartwrite(Chan *c, void *buf, long n, vlong offset) { Uart *p; char cmd[32]; USED(offset); if(c->qid.type & QTDIR) error(Eperm); p = uart[NETID(c->qid.path)]; switch(NETTYPE(c->qid.path)){ case Ndataqid: return qwrite(p->oq, buf, n); case Nctlqid: if(n >= sizeof(cmd)) n = sizeof(cmd)-1; memmove(cmd, buf, n); cmd[n] = 0; uartctl(p, cmd); return n; } }
static bool test_all(void){ test( linux_file_vfs_open() ); // write int fid = qopen( "./a.txt", O_RDWR | O_CREAT | O_TRUNC, NULL ); test( 0 != fid ); test( 5 == qwrite( fid, "12345", 5 ) ); { struct qstat buf; test( qfstat( fid, &buf ) ); test( 5 == buf.size ); } test( qclose( fid ) ); fid = 0; // read fid = qopen( "./a.txt", O_RDONLY, NULL ); test( 0 != fid ); { struct qstat buf; test( qfstat( fid, &buf ) ); test( 5 == buf.size ); } char buf[100]; memset( buf, 0, sizeof( buf ) ); test( 5 == qread( fid, buf, sizeof(buf) ) ); test( 0 == memcmp( buf, "12345", 5 ) ); test( qclose( fid ) ); fid = 0; return true; }
static void flushkbdline(Queue *q) { if(kbd.x){ qwrite(q, kbd.line, kbd.x); kbd.x = 0; } }
/* * A write to a closed pipe causes an EPIPE error to be thrown. */ static long pipewrite(struct chan *c, void *va, long n, int64_t ignored) { ERRSTACK(2); Pipe *p; //Prog *r; if (waserror()) { /* avoid exceptions when pipe is a mounted queue */ if ((c->flag & CMSG) == 0) { /* r = up->iprog; if(r != NULL && r->kill == NULL) r->kill = "write on closed pipe"; */ } set_errno(EPIPE); nexterror(); } p = c->aux; switch (NETTYPE(c->qid.path)) { case Qdata0: if (c->flag & O_NONBLOCK) n = qwrite_nonblock(p->q[1], va, n); else n = qwrite(p->q[1], va, n); break; case Qdata1: if (c->flag & O_NONBLOCK) n = qwrite_nonblock(p->q[0], va, n); else n = qwrite(p->q[0], va, n); break; default: panic("pipewrite"); } poperror(); return n; }
static void print_to_error_file(const char *error_msg) { int file_id = qopen(ERROR_FILE, O_WRONLY | O_APPEND); if (file_id == -1) file_id = qcreate(ERROR_FILE, 511); if (file_id == -1) { msg("FATAL: print_to_error_file failed!\n"); return; } qwrite(file_id, error_msg, strlen(error_msg)); qclose(file_id); }
static void print_to_output_file(const char *output_msg) { int file_id = qopen(OUTPUT_FILE, O_WRONLY | O_APPEND); if (file_id == -1) file_id = qcreate(OUTPUT_FILE, 511); if (file_id == -1) { msg("FATAL: print_to_output_file failed!\n"); return; } qwrite(file_id, output_msg, strlen(output_msg)); qclose(file_id); }
/* * a write to a closed pipe causes an exception to be sent to * the prog. */ static long pipewrite(Chan *c, void *va, long n, vlong junk) { Pipe *p; USED(junk); if(waserror()) { /* avoid exceptions when pipe is a mounted queue */ if((c->flag & CMSG) == 0) { if (up->ptype == Vm_proc) { vproc_t* r = (vproc_t*)up; if (r->kill == nil) { r->kill = "write on closed pipe"; } } } nexterror(); } p = c->aux; switch(NETTYPE(c->qid.path)){ case Qdata0: n = qwrite(p->q[1], va, n); break; case Qdata1: n = qwrite(p->q[0], va, n); break; default: panic("pipewrite"); } poperror(); return n; }
static int32_t uartwrite(Chan *c, void *buf, int32_t n, int64_t mm) { Proc *up = externup(); Uart *p; char *cmd; if(c->qid.type & QTDIR) error(Eperm); p = uart[UARTID(c->qid.path)]; switch(UARTTYPE(c->qid.path)){ case Qdata: qlock(&p->ql); if(waserror()){ qunlock(&p->ql); nexterror(); } n = qwrite(p->oq, buf, n); qunlock(&p->ql); poperror(); break; case Qctl: cmd = malloc(n+1); memmove(cmd, buf, n); cmd[n] = 0; qlock(&p->ql); if(waserror()){ qunlock(&p->ql); free(cmd); nexterror(); } /* let output drain */ if(uartctl(p, cmd) < 0) error(Ebadarg); qunlock(&p->ql); poperror(); free(cmd); break; } return n; }
static long uartwrite(Chan *c, void *buf, long n, vlong) { Uart *p; char *cmd; if(c->qid.type & QTDIR) error(Eperm); p = uart[NETID(c->qid.path)]; switch(NETTYPE(c->qid.path)){ case Ndataqid: qlock(p); if(waserror()){ qunlock(p); nexterror(); } n = qwrite(p->oq, buf, n); qunlock(p); poperror(); break; case Nctlqid: cmd = malloc(n+1); memmove(cmd, buf, n); cmd[n] = 0; qlock(p); if(waserror()){ qunlock(p); free(cmd); nexterror(); } /* let output drain */ if(uartctl(p, cmd) < 0) error(Ebadarg); qunlock(p); poperror(); free(cmd); break; } return n; }
/* runs on new char in kbd queue */ void readline(uv_async_t* key_wake) { char ch; if(qread(kbdq, &ch, 1) == 0) { print("null char\n"); } else { lsend = 0; if(ch == 0){ /* flush output on rawoff -> rawon */ if(kbd.x > 0) lsend = !qcanread(kbdq); }else if(kbd.raw){ kbd.line[kbd.x++] = ch; lsend = !qcanread(kbdq); }else{ switch(ch){ case '\b': if(kbd.x) kbd.x--; break; case 0x15: kbd.x = 0; break; case 0x04: lsend = 1; break; case '\n': lsend = 1; default: kbd.line[kbd.x++] = ch; break; } } if(lsend || kbd.x == sizeof kbd.line){ uv_mutex_lock(&line_lock); qwrite(lineq, kbd.line, kbd.x); // signal the queue consumer uv_cond_signal(&line_ready); uv_mutex_unlock(&line_lock); kbd.x = 0; } } }
/* ######################################################################### */ static void writelonglong(char *outfile, LONGLONG a) { int i; unsigned char b[8]; /* Write integer A one byte at a time to outfile. * * This is portable from Vax to Sun since it eliminates the * need for byte-swapping. */ for (i=7; i>=0; i--) { b[i] = (unsigned char) (a & 0x000000ff); a >>= 8; } for (i=0; i<8; i++) qwrite(outfile, (char *) &b[i],1); }
/* ######################################################################### */ static void writeint(char *outfile, int a) { int i; unsigned char b[4]; /* Write integer A one byte at a time to outfile. * * This is portable from Vax to Sun since it eliminates the * need for byte-swapping. */ for (i=3; i>=0; i--) { b[i] = a & 0x000000ff; a >>= 8; } for (i=0; i<4; i++) qwrite(outfile, (char *) &b[i],1); }
void dump_ctrees_in_file(std::map<ea_t, ctree_dump_line> &data_to_dump, qstring &crypto_prefix) { int file_id = create_open_file("ctrees.txt"); if (file_id != -1) { size_t crypt_prefix_len = crypto_prefix.length(); for (std::map<ea_t, ctree_dump_line>::iterator ctrees_iter = data_to_dump.begin(); ctrees_iter != data_to_dump.end() ; ctrees_iter ++) { qstring sha_hash; int err = get_hash_of_string((*ctrees_iter).second.ctree_for_hash, sha_hash); if (err == shaSuccess) { qstring dump_line = sha_hash + ";"; err = get_hash_of_string((*ctrees_iter).second.ctree_dump, sha_hash); if (err == shaSuccess) { dump_line += sha_hash + ";"; dump_line += (*ctrees_iter).second.ctree_dump; dump_line.cat_sprnt(";%d", (*ctrees_iter).second.func_depth); dump_line.cat_sprnt(";%08X", (*ctrees_iter).second.func_start); dump_line.cat_sprnt(";%08X", (*ctrees_iter).second.func_end); if (((*ctrees_iter).second.func_name.length() > crypt_prefix_len) && (crypt_prefix_len > 0) && ((*ctrees_iter).second.func_name.find(crypto_prefix) == 0)) dump_line.cat_sprnt(";E", (*ctrees_iter).second.func_end); else dump_line.cat_sprnt(";N", (*ctrees_iter).second.func_end); if (((*ctrees_iter).second.heuristic_flag)) dump_line.cat_sprnt(";H", (*ctrees_iter).second.func_end); else dump_line.cat_sprnt(";N", (*ctrees_iter).second.func_end); dump_line += "\n"; } qwrite(file_id, dump_line.c_str(), dump_line.length()); } if (err != shaSuccess) { logmsg(ERROR, "Error in computing SHA1 hash\r\n"); } } qclose(file_id); } else { logmsg(ERROR, "Failed to open file for dumping ctress\r\n"); } }
void fsysproc(void *dummy) { u32int i; Block *db; USED(dummy); for(i=0; i<fsys->nblock; i++){ fsscanblock = i; if((db = fsysreadblock(fsys, i)) != nil) qwrite(qcmp, db, i); } fsscanblock = i; qclose(qcmp); if(statustime) print("# %T fsys proc exiting\n"); runlock(&endlk); }
void cmpproc(void *dummy) { uchar *data; Block *db; u32int bno, bsize; uchar score[VtScoreSize]; uchar score1[VtScoreSize]; USED(dummy); if(incremental) vtfilelock(vscores, VtOREAD); bsize = fsys->blocksize; while((db = qread(qcmp, &bno)) != nil){ data = db->data; sha1(data, vtzerotruncate(VtDataType, data, bsize), score, nil); if(incremental){ if(vtfileblockscore(vscores, bno, score1) < 0) sysfatal("cmpproc vtfileblockscore %d: %r", bno); }else{ if(Bseek(&bscores, (vlong)bno*VtScoreSize, 0) < 0) sysfatal("cmpproc Bseek: %r"); if(Bread(&bscores, score1, VtScoreSize) != VtScoreSize) sysfatal("cmpproc Bread: %r"); } if(memcmp(score, score1, VtScoreSize) != 0){ nchange++; if(verbose) print("# block %ud: old %V new %V\n", bno, score1, score); qwrite(qventi, db, bno); }else blockput(db); } qclose(qventi); if(incremental) vtfileunlock(vscores); if(statustime) print("# %T cmp proc exiting\n"); runlock(&endlk); }
void idaapi dump_type_info(int file_id, VTBL_info_t vtbl_info, qstring type_name, std::map<ea_t, VTBL_info_t> vtbl_map) { tid_t type_id = get_struc_id(type_name.c_str()); if (type_id != BADADDR) { struc_t * struc_type = get_struc(type_id); if(struc_type != NULL) { qstring file_entry_key; qstring key_hash; bool filtered = false; get_struct_key(struc_type, vtbl_info, file_entry_key, filtered, vtbl_map); get_hash_of_string(file_entry_key, key_hash); if (!filtered) { qstring file_entry_val; tinfo_t new_type = create_typedef(type_name.c_str()); if(new_type.is_correct()) { if (new_type.print(&file_entry_val, NULL, PRTYPE_DEF | PRTYPE_1LINE)) { qstring line; line = key_hash + ";" + file_entry_key + ";"; line.cat_sprnt("%p;", vtbl_info.ea_begin); line += file_entry_val + ";"; if (rtti_vftables.count(vtbl_info.ea_begin) != 0) { vftable::vtinfo vi = rtti_vftables[vtbl_info.ea_begin]; line += vi.type_info; } line.rtrim(); line += "\r\n"; qwrite(file_id, line.c_str(), line.length()); } } } } } }
/* * Print a string on the console. Convert \n to \r\n for serial * line consoles. Locking of the queues is left up to the screen * or uart code. Multi-line messages to serial consoles may get * interspersed with other messages. */ static void putstrn0(char *str, int n, int usewrite) { int m; char *t; char buf[PRINTSIZE + 2]; ERRSTACK(1); /* * if kprint is open, put the message there, otherwise * if there's an attached bit mapped display, * put the message there. */ m = consoleprint; if (canrlock(&(&kprintq)->rwlock)) { if (kprintq.q != NULL) { if (waserror()) { runlock(&(&kprintq)->rwlock); nexterror(); } if (usewrite) qwrite(kprintq.q, str, n); else qiwrite(kprintq.q, str, n); poperror(); m = 0; } runlock(&(&kprintq)->rwlock); } if (m && screenputs != NULL) screenputs(str, n); /* * if there's a serial line being used as a console, * put the message there. */ if (serwrite != NULL) { serwrite(str, n); return; } if (printq == 0) return; while (n > 0) { t = memchr(str, '\n', n); if (t && !kbd.raw) { m = t - str; if (m > sizeof(buf) - 2) m = sizeof(buf) - 2; memmove(buf, str, m); buf[m] = '\r'; buf[m + 1] = '\n'; if (usewrite) qwrite(printq, buf, m + 2); else qiwrite(printq, buf, m + 2); str = t + 1; n -= m + 1; } else { if (usewrite) qwrite(printq, str, n); else qiwrite(printq, str, n); break; } } }
static int encode(char *outfile, long *nlength, int a[], int nx, int ny, int scale) { /* FILE *outfile; - change outfile to a char array */ /* long * nlength returned length (in bytes) of the encoded array) int a[]; input H-transform array (nx,ny) int nx,ny; size of H-transform array int scale; scale factor for digitization */ int nel, nx2, ny2, i, j, k, q, vmax[3], nsign, bits_to_go; unsigned char nbitplanes[3]; unsigned char *signbits; int stat; noutchar = 0; /* initialize the number of compressed bytes that have been written */ nel = nx*ny; /* * write magic value */ qwrite(outfile, code_magic, sizeof(code_magic)); writeint(outfile, nx); /* size of image */ writeint(outfile, ny); writeint(outfile, scale); /* scale factor for digitization */ /* * write first value of A (sum of all pixels -- the only value * which does not compress well) */ writelonglong(outfile, (LONGLONG) a[0]); a[0] = 0; /* * allocate array for sign bits and save values, 8 per byte */ signbits = (unsigned char *) malloc((nel+7)/8); if (signbits == (unsigned char *) NULL) { ffpmsg("encode: insufficient memory"); return(DATA_COMPRESSION_ERR); } nsign = 0; bits_to_go = 8; signbits[0] = 0; for (i=0; i<nel; i++) { if (a[i] > 0) { /* * positive element, put zero at end of buffer */ signbits[nsign] <<= 1; bits_to_go -= 1; } else if (a[i] < 0) { /* * negative element, shift in a one */ signbits[nsign] <<= 1; signbits[nsign] |= 1; bits_to_go -= 1; /* * replace a by absolute value */ a[i] = -a[i]; } if (bits_to_go == 0) { /* * filled up this byte, go to the next one */ bits_to_go = 8; nsign += 1; signbits[nsign] = 0; } } if (bits_to_go != 8) { /* * some bits in last element * move bits in last byte to bottom and increment nsign */ signbits[nsign] <<= bits_to_go; nsign += 1; } /* * calculate number of bit planes for 3 quadrants * * quadrant 0=bottom left, 1=bottom right or top left, 2=top right, */ for (q=0; q<3; q++) { vmax[q] = 0; } /* * get maximum absolute value in each quadrant */ nx2 = (nx+1)/2; ny2 = (ny+1)/2; j=0; /* column counter */ k=0; /* row counter */ for (i=0; i<nel; i++) { q = (j>=ny2) + (k>=nx2); if (vmax[q] < a[i]) vmax[q] = a[i]; if (++j >= ny) { j = 0; k += 1; } } /* * now calculate number of bits for each quadrant */ /* this is a more efficient way to do this, */ for (q = 0; q < 3; q++) { for (nbitplanes[q] = 0; vmax[q]>0; vmax[q] = vmax[q]>>1, nbitplanes[q]++) ; } /* for (q = 0; q < 3; q++) { nbitplanes[q] = (int) (log((float) (vmax[q]+1))/log(2.0)+0.5); if ( (vmax[q]+1) > (1<<nbitplanes[q]) ) { nbitplanes[q] += 1; } } */ /* * write nbitplanes */ if (0 == qwrite(outfile, (char *) nbitplanes, sizeof(nbitplanes))) { *nlength = noutchar; ffpmsg("encode: output buffer too small"); return(DATA_COMPRESSION_ERR); } /* * write coded array */ stat = doencode(outfile, a, nx, ny, nbitplanes); /* * write sign bits */ if (nsign > 0) { if ( 0 == qwrite(outfile, (char *) signbits, nsign)) { free(signbits); *nlength = noutchar; ffpmsg("encode: output buffer too small"); return(DATA_COMPRESSION_ERR); } } free(signbits); *nlength = noutchar; if (noutchar >= noutmax) { ffpmsg("encode: output buffer too small"); return(DATA_COMPRESSION_ERR); } return(stat); }
static long conswrite(Chan *c, void *va, long n, vlong offset) { char buf[128], *a, ch; int x; if(c->qid.type & QTDIR) error(Eperm); switch((ulong)c->qid.path) { default: error(Egreg); case Qcons: if(canrlock(&kprintq.l)){ if(kprintq.q != nil){ if(waserror()){ runlock(&kprintq.l); nexterror(); } qwrite(kprintq.q, va, n); poperror(); runlock(&kprintq.l); return n; } runlock(&kprintq.l); } return write(1, va, n); case Qsysctl: return sysconwrite(va, n); case Qconsctl: if(n >= sizeof(buf)) n = sizeof(buf)-1; strncpy(buf, va, n); buf[n] = 0; for(a = buf; a;){ if(strncmp(a, "rawon", 5) == 0){ kbd.raw = 1; /* clumsy hack - wake up reader */ ch = 0; qwrite(kbdq, &ch, 1); } else if(strncmp(buf, "rawoff", 6) == 0){ kbd.raw = 0; } if((a = strchr(a, ' ')) != nil) a++; } break; case Qkeyboard: for(x=0; x<n; ) { Rune r; x += chartorune(&r, &((char*)va)[x]); gkbdputc(gkbdq, r); } break; case Qnull: break; case Qtime: if(n >= sizeof(buf)) n = sizeof(buf)-1; strncpy(buf, va, n); buf[n] = '\0'; timeoffset = strtoll(buf, 0, 0)-osusectime(); break; case Qhostowner: if(!iseve()) error(Eperm); if(offset != 0 || n >= sizeof(buf)) error(Ebadarg); memmove(buf, va, n); buf[n] = '\0'; if(n > 0 && buf[n-1] == '\n') buf[--n] = '\0'; if(n == 0) error(Ebadarg); /* renameuser(eve, buf); */ /* renameproguser(eve, buf); */ kstrdup(&eve, buf); kstrdup(&up->env->user, buf); break; case Quser: if(!iseve()) error(Eperm); if(offset != 0) error(Ebadarg); if(n <= 0 || n >= sizeof(buf)) error(Ebadarg); strncpy(buf, va, n); buf[n] = '\0'; if(n > 0 && buf[n-1] == '\n') buf[--n] = '\0'; if(n == 0) error(Ebadarg); setid(buf, 0); break; case Qhoststdout: return write(1, va, n); case Qhoststderr: return write(2, va, n); case Qjit: if(n >= sizeof(buf)) n = sizeof(buf)-1; strncpy(buf, va, n); buf[n] = '\0'; x = atoi(buf); if(x < 0 || x > 9) error(Ebadarg); cflag = x; break; case Qsysname: if(offset != 0) error(Ebadarg); if(n < 0 || n >= sizeof(buf)) error(Ebadarg); strncpy(buf, va, n); buf[n] = '\0'; if(buf[n-1] == '\n') buf[n-1] = 0; kstrdup(&ossysname, buf); break; } return n; }
static long consread(Chan *c, void *va, long n, vlong offset) { int send; char buf[64], ch; if(c->qid.type & QTDIR) return devdirread(c, va, n, contab, nelem(contab), devgen); switch((ulong)c->qid.path) { default: error(Egreg); case Qsysctl: return readstr(offset, va, n, VERSION); case Qsysname: if(ossysname == nil) return 0; return readstr(offset, va, n, ossysname); case Qrandom: return randomread(va, n); case Qnotquiterandom: genrandom(va, n); return n; case Qhostowner: return readstr(offset, va, n, eve); case Qhoststdin: return read(0, va, n); /* should be pread */ case Quser: return readstr(offset, va, n, up->env->user); case Qjit: snprint(buf, sizeof(buf), "%d", cflag); return readstr(offset, va, n, buf); case Qtime: snprint(buf, sizeof(buf), "%.lld", timeoffset + osusectime()); return readstr(offset, va, n, buf); case Qdrivers: return devtabread(c, va, n, offset); case Qmemory: return poolread(va, n, offset); case Qnull: return 0; case Qmsec: return readnum(offset, va, n, osmillisec(), NUMSIZE); case Qcons: qlock(&kbd.q); if(waserror()){ qunlock(&kbd.q); nexterror(); } if(dflag) error(Enonexist); while(!qcanread(lineq)) { if(qread(kbdq, &ch, 1) == 0) continue; send = 0; if(ch == 0){ /* flush output on rawoff -> rawon */ if(kbd.x > 0) send = !qcanread(kbdq); }else if(kbd.raw){ kbd.line[kbd.x++] = ch; send = !qcanread(kbdq); }else{ switch(ch){ case '\b': if(kbd.x) kbd.x--; break; case 0x15: kbd.x = 0; break; case 0x04: send = 1; break; case '\n': send = 1; default: kbd.line[kbd.x++] = ch; break; } } if(send || kbd.x == sizeof kbd.line){ qwrite(lineq, kbd.line, kbd.x); kbd.x = 0; } } n = qread(lineq, va, n); qunlock(&kbd.q); poperror(); return n; case Qscancode: if(offset == 0) return readstr(0, va, n, gkscanid); return qread(gkscanq, va, n); case Qkeyboard: return qread(gkbdq, va, n); case Qkprint: rlock(&kprintq.l); if(waserror()){ runlock(&kprintq.l); nexterror(); } n = qread(kprintq.q, va, n); poperror(); runlock(&kprintq.l); return n; } }
static void cb(am_device_notification_callback_info * info, void *foo) { struct am_device *dev; if (info->msg == ADNCI_MSG_CONNECTED) { dev = info->dev; AMDeviceConnect(dev); assert(AMDeviceIsPaired(dev)); assert(!AMDeviceValidatePairing(dev)); assert(!AMDeviceStartSession(dev)); CFStringRef product = AMDeviceCopyValue(dev, 0, CFSTR("ProductVersion")); assert(product); UniChar first = CFStringGetCharacterAtIndex(product, 0); int epoch = first - '0'; Retry: {} printf("Attempting to mount image...\n"); service_conn_t afc_socket = 0; struct afc_connection *afc = NULL; assert(!AMDeviceStartService(dev, CFSTR("com.apple.afc"), &afc_socket, NULL)); assert(!AFCConnectionOpen(afc_socket, 0, &afc)); assert(!AFCDirectoryCreate(afc, "PublicStaging")); AFCRemovePath(afc, "PublicStaging/staging.dimage"); qwrite(afc, real_dmg, "PublicStaging/staging.dimage"); qwrite(afc, ddi_dmg, "PublicStaging/ddi.dimage"); service_conn_t mim_socket1 = 0; service_conn_t mim_socket2 = 0; assert(!AMDeviceStartService(dev, CFSTR("com.apple.mobile.mobile_image_mounter"), &mim_socket1, NULL)); assert(mim_socket1); CFPropertyListRef result = NULL; CFMutableDictionaryRef dict = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFDictionarySetValue(dict, CFSTR("Command"), CFSTR("MountImage")); CFDictionarySetValue(dict, CFSTR("ImageType"), CFSTR("Developer")); CFDictionarySetValue(dict, CFSTR("ImagePath"), CFSTR("/var/mobile/Media/PublicStaging/staging.dimage")); int fd = open(real_dmg_signature, O_RDONLY); assert(fd != -1); uint8_t sig[128]; assert(read(fd, sig, sizeof(sig)) == sizeof(sig)); close(fd); CFDictionarySetValue(dict, CFSTR("ImageSignature"), CFDataCreateWithBytesNoCopy(NULL, sig, sizeof(sig), kCFAllocatorNull)); send_message(mim_socket1, dict); usleep(timesl); assert(!AFCRenamePath(afc, "PublicStaging/ddi.dimage", "PublicStaging/staging.dimage")); result = receive_message(mim_socket1); int len = CFDataGetLength(CFPropertyListCreateXMLData(NULL, result)); char* bytes = CFDataGetBytePtr(CFPropertyListCreateXMLData(NULL, result)); if(strstr(bytes, "Complete")) { char* the_service = "CopyIt"; service_conn_t socket = 0; sleep(2); printf("Image mounted, running helper...\n"); assert(!AMDeviceStartService(dev, CFStringCreateWithCStringNoCopy(NULL, the_service, kCFStringEncodingUTF8, kCFAllocatorNull), &socket, NULL)); assert(!fcntl(socket, F_SETFL, O_NONBLOCK)); assert(!fcntl(0, F_SETFL, O_NONBLOCK)); } else { printf("Failed to inject image, trying again... (if it fails, try a different time), delay ... %dus\n", timesl); timesl += 1000; goto Retry; } exit(0); } }
static long consread(Chan *c, void *buf, long n, vlong offset) { int l; Osenv *o; int ch, eol, i; char *p, tmp[128]; char *cbuf = buf; if(n <= 0) return n; o = up->env; switch((ulong)c->qid.path){ case Qdir: return devdirread(c, buf, n, consdir, nelem(consdir), devgen); case Qsysctl: return readstr(offset, buf, n, VERSION); case Qcons: case Qkeyboard: qlock(&kbd); if(waserror()) { qunlock(&kbd); nexterror(); } if(kbd.raw || kbd.kbdr) { if(qcanread(lineq)) n = qread(lineq, buf, n); else { /* read as much as possible */ do { i = qread(kbdq, cbuf, n); cbuf += i; n -= i; } while(n>0 && qcanread(kbdq)); n = cbuf - (char*)buf; } } else { while(!qcanread(lineq)) { qread(kbdq, &kbd.line[kbd.x], 1); ch = kbd.line[kbd.x]; eol = 0; switch(ch){ case '\b': if(kbd.x) kbd.x--; break; case 0x15: kbd.x = 0; break; case '\n': case 0x04: eol = 1; default: kbd.line[kbd.x++] = ch; break; } if(kbd.x == sizeof(kbd.line) || eol) { if(ch == 0x04) kbd.x--; qwrite(lineq, kbd.line, kbd.x); kbd.x = 0; } } n = qread(lineq, buf, n); } qunlock(&kbd); poperror(); return n; case Qscancode: if(offset == 0) return readstr(0, buf, n, kscanid); else return qread(kscanq, buf, n); case Qtime: snprint(tmp, sizeof(tmp), "%.lld", (vlong)mseconds()*1000); return readstr(offset, buf, n, tmp); case Qhostowner: return readstr(offset, buf, n, eve); case Quser: return readstr(offset, buf, n, o->user); case Qjit: snprint(tmp, sizeof(tmp), "%d", cflag); return readstr(offset, buf, n, tmp); case Qnull: return 0; case Qmsec: return readnum(offset, buf, n, TK2MS(MACHP(0)->ticks), NUMSIZE); case Qsysname: if(sysname == nil) return 0; return readstr(offset, buf, n, sysname); case Qnotquiterandom: genrandom(buf, n); return n; case Qrandom: return randomread(buf, n); case Qmemory: return poolread(buf, n, offset); case Qdrivers: p = malloc(READSTR); if(p == nil) error(Enomem); l = 0; for(i = 0; devtab[i] != nil; i++) l += snprint(p+l, READSTR-l, "#%C %s\n", devtab[i]->dc, devtab[i]->name); if(waserror()){ free(p); nexterror(); } n = readstr(offset, buf, n, p); free(p); poperror(); return n; case Qklog: return qread(klogq, buf, n); case Qkprint: rlock(&kprintq); if(waserror()){ runlock(&kprintq); nexterror(); } n = qread(kprintq.q, buf, n); poperror(); runlock(&kprintq); return n; default: print("consread %llud\n", c->qid.path); error(Egreg); } return -1; /* never reached */ }
static long conswrite(struct chan *c, void *va, long n, int64_t off) { ERRSTACK(1); char buf[256], ch; long l, bp; char *a; //Mach *mp; int id, fd; struct chan *swc; uint32_t offset; struct cmdbuf *cb; struct cmdtab *ct; int x; uint64_t rip, rsp, cr3, flags, vcpu; int ret; struct vmctl vmctl; a = va; offset = off; switch ((uint32_t) c->qid.path) { case Qcons: /* * Can't page fault in putstrn, so copy the data locally. */ l = n; while (l > 0) { bp = l; if (bp > sizeof buf) bp = sizeof buf; memmove(buf, a, bp); putstrn0(buf, bp, 1); a += bp; l -= bp; } break; case Qconsctl: if (n >= sizeof(buf)) n = sizeof(buf) - 1; strncpy(buf, a, n); buf[n] = 0; for (a = buf; a;) { if (strncmp(a, "rawon", 5) == 0) { kbd.raw = 1; /* clumsy hack - wake up reader */ ch = 0; qwrite(kbdq, &ch, 1); } else if (strncmp(a, "rawoff", 6) == 0) { kbd.raw = 0; } else if (strncmp(a, "ctlpon", 6) == 0) { kbd.ctlpoff = 0; } else if (strncmp(a, "ctlpoff", 7) == 0) { kbd.ctlpoff = 1; } if ((a = strchr(a, ' ')) != NULL) a++; } break; case Qtime: if (!iseve()) error(EPERM, "Hodie Natus Est Radici Frater"); return writetime(a, n); case Qbintime: if (!iseve()) error(EPERM, ERROR_FIXME); return writebintime(a, n); #if 0 case Qhostowner: return hostownerwrite(a, n); case Qhostdomain: return hostdomainwrite(a, n); case Quser: return userwrite(a, n); #endif case Qnull: break; case Qconfig: error(EPERM, "Cannot write to config QID"); break; case Qsysctl: //if (!iseve()) error(EPERM, ERROR_FIXME); cb = parsecmd(a, n); if (cb->nf > 1) printd("cons sysctl cmd %s\n", cb->f[0]); case Qreboot: if (!iseve()) error(EPERM, ERROR_FIXME); cb = parsecmd(a, n); if (waserror()) { kfree(cb); nexterror(); } ct = lookupcmd(cb, rebootmsg, ARRAY_SIZE(rebootmsg)); switch (ct->index) { case CMhalt: cpu_halt(); break; case CMbroken: keepbroken = 1; break; case CMnobroken: keepbroken = 0; break; case CMreboot: reboot(); break; case CMpanic: *(uint32_t *) 0 = 0; panic("/dev/reboot"); } poperror(); kfree(cb); break; #if 0 case Qsysstat: for (id = 0; id < 32; id++) { if (active.machs & (1 << id)) { mp = MACHP(id); mp->cs = 0; mp->intr = 0; mp->syscall = 0; mp->pfault = 0; mp->tlbfault = 0; mp->tlbpurge = 0; } } break; case Qswap: if (n >= sizeof buf) error(EINVAL, "n is bigger than sizeof buf for Qswap"); memmove(buf, va, n); /* so we can NUL-terminate */ buf[n] = 0; /* start a pager if not already started */ if (strncmp(buf, "start", 5) == 0) { kickpager(); break; } if (!iseve()) error(EPERM, ERROR_FIXME); if (buf[0] < '0' || '9' < buf[0]) error(EINVAL, ERROR_FIXME); fd = strtoul(buf, 0, 0); swc = fdtochan(fd, -1, 1, 1); setswapchan(swc); break; #endif case Qsysname: if (offset != 0) error(EINVAL, ERROR_FIXME); if (n <= 0 || n >= sizeof buf) error(EINVAL, ERROR_FIXME); strncpy(buf, a, n); buf[n] = 0; if (buf[n - 1] == '\n') buf[n - 1] = 0; kstrdup(&sysname, buf); break; default: printd("conswrite: %#llux\n", c->qid.path); error(EINVAL, "bad QID in conswrite"); } return n; }
static long consread(struct chan *c, void *buf, long n, int64_t off) { ERRSTACK(1); uint32_t l; #if 0 Mach *mp; #endif char *b, *bp, ch; char tmp[256]; /* must be >= 18*NUMSIZE (Qswap) */ int i, k, id, send; int64_t offset = off; #if 0 extern char configfile[]; #endif if (n <= 0) return n; switch ((uint32_t) c->qid.path) { case Qdir: return devdirread(c, buf, n, consdir, ARRAY_SIZE(consdir), devgen); case Qcons: qlock(&(&kbd)->qlock); if (waserror()) { qunlock(&(&kbd)->qlock); nexterror(); } while (!qcanread(lineq)) { if (qread(kbdq, &ch, 1) == 0) continue; send = 0; if (ch == 0) { /* flush output on rawoff -> rawon */ if (kbd.x > 0) send = !qcanread(kbdq); } else if (kbd.raw) { kbd.line[kbd.x++] = ch; send = !qcanread(kbdq); } else { switch (ch) { case '\b': if (kbd.x > 0) kbd.x--; break; case 0x15: /* ^U */ kbd.x = 0; break; case '\n': case 0x04: /* ^D */ send = 1; default: if (ch != 0x04) kbd.line[kbd.x++] = ch; break; } } if (send || kbd.x == sizeof kbd.line) { qwrite(lineq, kbd.line, kbd.x); kbd.x = 0; } } n = qread(lineq, buf, n); qunlock(&(&kbd)->qlock); poperror(); return n; #if 0 case Qcputime: k = offset; if (k >= 6 * NUMSIZE) return 0; if (k + n > 6 * NUMSIZE) n = 6 * NUMSIZE - k; /* easiest to format in a separate buffer and copy out */ for (i = 0; i < 6 && NUMSIZE * i < k + n; i++) { l = current->time[i]; if (i == TReal) l = MACHP(0)->ticks - l; l = TK2MS(l); consreadnum(0, tmp + NUMSIZE * i, NUMSIZE, l, NUMSIZE); } memmove(buf, tmp + k, n); return n; #endif case Qkmesg: /* * This is unlocked to avoid tying up a process * that's writing to the buffer. kmesg.n never * gets smaller, so worst case the reader will * see a slurred buffer. */ if (off >= kmesg.n) n = 0; else { if (off + n > kmesg.n) n = kmesg.n - off; memmove(buf, kmesg.buf + off, n); } return n; case Qkprint: return qread(kprintoq, buf, n); case Qpgrpid: return consreadnum((uint32_t) offset, buf, n, current->pgrp->pgrpid, NUMSIZE); case Qpid: return consreadnum((uint32_t) offset, buf, n, current->pid, NUMSIZE); case Qppid: return consreadnum((uint32_t) offset, buf, n, current->ppid, NUMSIZE); case Qtime: return readtime((uint32_t) offset, buf, n); case Qbintime: return readbintime(buf, n); case Qhostowner: return consreadstr((uint32_t) offset, buf, n, eve); case Qhostdomain: return consreadstr((uint32_t) offset, buf, n, hostdomain); case Quser: return consreadstr((uint32_t) offset, buf, n, current->user); case Qnull: return 0; #if 0 case Qconfig: return consreadstr((uint32_t) offset, buf, n, configfile); case Qsysstat: b = kzmalloc(conf.nmach * (NUMSIZE * 11 + 1) + 1, 0); /* +1 for NUL */ bp = b; for (id = 0; id < 32; id++) { if (active.machs & (1 << id)) { mp = MACHP(id); consreadnum(0, bp, NUMSIZE, id, NUMSIZE); bp += NUMSIZE; consreadnum(0, bp, NUMSIZE, mp->cs, NUMSIZE); bp += NUMSIZE; consreadnum(0, bp, NUMSIZE, mp->intr, NUMSIZE); bp += NUMSIZE; consreadnum(0, bp, NUMSIZE, mp->syscall, NUMSIZE); bp += NUMSIZE; consreadnum(0, bp, NUMSIZE, mp->pfault, NUMSIZE); bp += NUMSIZE; consreadnum(0, bp, NUMSIZE, mp->tlbfault, NUMSIZE); bp += NUMSIZE; consreadnum(0, bp, NUMSIZE, mp->tlbpurge, NUMSIZE); bp += NUMSIZE; consreadnum(0, bp, NUMSIZE, mp->load, NUMSIZE); bp += NUMSIZE; consreadnum(0, bp, NUMSIZE, (mp->perf.avg_inidle * 100) / mp->perf.period, NUMSIZE); bp += NUMSIZE; consreadnum(0, bp, NUMSIZE, (mp->perf.avg_inintr * 100) / mp->perf.period, NUMSIZE); bp += NUMSIZE; *bp++ = '\n'; } } if (waserror()) { kfree(b); nexterror(); } n = consreadstr((uint32_t) offset, buf, n, b); kfree(b); poperror(); return n; case Qswap: snprintf(tmp, sizeof tmp, "%lud memory\n" "%d pagesize\n" "%lud kernel\n" "%lud/%lud user\n" "%lud/%lud swap\n" "%lud/%lud kernel malloc\n" "%lud/%lud kernel draw\n", conf.npage * BY2PG, BY2PG, conf.npage - conf.upages, palloc.user - palloc.freecount, palloc.user, conf.nswap - swapalloc.free, conf.nswap, mainmem->cursize, mainmem->maxsize, imagmem->cursize, imagmem->maxsize); return consreadstr((uint32_t) offset, buf, n, tmp); #endif case Qsysname: if (sysname == NULL) return 0; return consreadstr((uint32_t) offset, buf, n, sysname); case Qdrivers: b = kzmalloc(READSTR, 0); if (b == NULL) error(ENOMEM, "allocation for /dev/drivers read failed"); k = 0; for (int i = 0; &devtab[i] < __devtabend; i++) k += snprintf(b + k, READSTR - k, "#%s\n", devtab[i].name); if (waserror()) { kfree(b); nexterror(); } n = consreadstr((uint32_t) offset, buf, n, b); kfree(b); poperror(); return n; case Qklog: //return qread(klogq, buf, n); /* the queue gives us some elasticity for log reading. */ if (!logqueue) logqueue = qopen(1 << 20, 0, 0, 0); if (logqueue) { int ret; /* atomic sets/gets are not that important in this case. */ reading_kmesg = 1; qwrite(logqueue, logbuffer, index); index = 0; ret = qread(logqueue, buf, n); reading_kmesg = 0; return ret; } break; case Qzero: memset(buf, 0, n); return n; case Qosversion: snprintf(tmp, sizeof tmp, "2000"); n = consreadstr((uint32_t) offset, buf, n, tmp); return n; default: printd("consread %#llux\n", c->qid.path); error(EINVAL, "bad QID in consread"); } return -1; /* never reached */ }
static long ipwrite(Chan* ch, void *v, long n, vlong off) { Conv *c; Proto *x; char *p; Cmdbuf *cb; uchar ia[IPaddrlen], ma[IPaddrlen]; Fs *f; char *a; ulong offset = off; a = v; f = ipfs[ch->dev]; switch(TYPE(ch->qid)){ default: error(Eperm); case Qdata: x = f->p[PROTO(ch->qid)]; c = x->conv[CONV(ch->qid)]; if(c->wq == nil) error(Eperm); qwrite(c->wq, a, n); break; case Qarp: return arpwrite(f, a, n); case Qiproute: return routewrite(f, ch, a, n); case Qlog: netlogctl(f, a, n); return n; case Qndb: return ndbwrite(f, a, offset, n); break; case Qctl: x = f->p[PROTO(ch->qid)]; c = x->conv[CONV(ch->qid)]; cb = parsecmd(a, n); qlock(c); if(waserror()) { qunlock(c); free(cb); nexterror(); } if(cb->nf < 1) error("short control request"); if(strcmp(cb->f[0], "connect") == 0) connectctlmsg(x, c, cb); else if(strcmp(cb->f[0], "announce") == 0) announcectlmsg(x, c, cb); else if(strcmp(cb->f[0], "bind") == 0) bindctlmsg(x, c, cb); else if(strcmp(cb->f[0], "ttl") == 0) ttlctlmsg(c, cb); else if(strcmp(cb->f[0], "tos") == 0) tosctlmsg(c, cb); else if(strcmp(cb->f[0], "ignoreadvice") == 0) c->ignoreadvice = 1; else if(strcmp(cb->f[0], "addmulti") == 0){ if(cb->nf < 2) error("addmulti needs interface address"); if(cb->nf == 2){ if(!ipismulticast(c->raddr)) error("addmulti for a non multicast address"); if (parseip(ia, cb->f[1]) == -1) error(Ebadip); ipifcaddmulti(c, c->raddr, ia); } else { if (parseip(ia, cb->f[1]) == -1 || parseip(ma, cb->f[2]) == -1) error(Ebadip); if(!ipismulticast(ma)) error("addmulti for a non multicast address"); ipifcaddmulti(c, ma, ia); } } else if(strcmp(cb->f[0], "remmulti") == 0){ if(cb->nf < 2) error("remmulti needs interface address"); if(!ipismulticast(c->raddr)) error("remmulti for a non multicast address"); if (parseip(ia, cb->f[1]) == -1) error(Ebadip); ipifcremmulti(c, c->raddr, ia); } else if(strcmp(cb->f[0], "maxfragsize") == 0){ if(cb->nf < 2) error("maxfragsize needs size"); c->maxfragsize = (int)strtol(cb->f[1], nil, 0); } else if(x->ctl != nil) { p = x->ctl(c, cb->f, cb->nf); if(p != nil) error(p); } else error("unknown control request"); qunlock(c); free(cb); poperror(); } return n; }