/************************************************************************ Write log messages to the console. ************************************************************************/ void con_log(enum log_level level, const char *message) { if (console_rfcstyle) { con_write(C_LOG_BASE + level, "%s", message); } else { con_write(C_LOG_BASE + level, "%d: %s", level, message); } }
int printk(const char *fmt, ...) { char buf[1024]; va_list args; int i; va_start(args,fmt); i = vsprintf(buf, fmt, args); va_end(args); con_write(buf, i); /* __asm__("push %%fs\n\t" "push %%ds\n\t" "pop %%fs\n\t" "push %0 \n\t" "push $buf\n\t" "call con_write\n\t" "addl $4, %%esp\n\t" "pop %0\n\t" "pop %%fs" ::"r"(i)); */ return i; }
void cput_queue(unsigned int eax, unsigned int ebx, unsigned char mode) { const char* p = (char*)&eax; const char* q = (char*)&ebx; _put(p, 0); _put(p, 1); _put(p, 2); _put(p, 3); _put(q, 0); _put(q, 1); _put(q, 2); _put(q, 3); con_write(&tty); // printf("(%x,%x)\t", eax, ebx); // printf("(mode %x)\n", mode); }
/* * 向3号控制台打印内核消息 * stdarg.h中的dmesg、panic均为对此函数的封装 */ int printk(u8 attr, const char *fmt, ...) { va_list args; int i,j; va_start(args, fmt); i=vsprintf(buf,fmt,args); va_end(args); for (j = 0; j < i; j++) { writebuf[j*2] = buf[j]; writebuf[j*2+1] = attr; } con_write(&kfile_table[fcon3], writebuf, i*2); con_seek(&kfile_table[fcon3], 80*2 - (kfile_table[fcon3].f_pos[0] % (80*2)), SEEK_CUR ); return i; }
int main(int argc, char* argv[]) { int opt; bool vns_console = false; char* command_file = NULL; char* pid_file = NULL; int i, ifcount = 0; struct vnlif iflist[vnlif_maxcount]; int command_fd, command_eth = -1; FILE* pid_fd; struct pollfd pollfds[2+2*vnlif_maxcount]; int pollres; char buffer[MSGSIZE]; int len; char* pktbuffer = buffer + MSGHDRSIZE; c_base* vnsbasehdr = (c_base*)buffer; c_hwinfo* vnshwinfo = (c_hwinfo*)buffer; c_packet_header* vnspkthdr = (c_packet_header*)buffer; // ---------------- parse command options ---------------- while ((opt = getopt(argc, argv, "si:c:p:")) != -1) { switch (opt) { case 's': vns_console = true; break; case 'i': if (ifcount < vnlif_maxcount) { if (!vnlif_parse(iflist + ifcount, optarg)) die("vnlif_parse"); } else { die("cmdline vnlif_maxcount"); } ++ifcount; break; case 'c': command_file = optarg; break; case 'p': pid_file = optarg; break; } } if (ifcount == 0 || command_file == NULL || pid_file == NULL) { printf("vnlsvc: Virtual Network Lab Service\nTAP-UDP: vnlsvc -i eth0/tap0/1a:8e:22:b1:da:f1/198.51.100.1#255.255.255.0/192.0.2.1:2001/192.0.2.2:2001/ -c /tmp/command.pipe -p /tmp/vnltun.pid\nVNSconsole-UDP: vnlsvc -s -i eth0//1a:8e:22:b1:da:f1/198.51.100.1#255.255.255.0/192.0.2.1:2001/192.0.2.2:2001/ -c /tmp/command.pipe -p /tmp/vnltun.pid\n"); exit(1); } // ---------------- open files and sockets ---------------- command_fd = open(command_file, O_RDONLY | O_NONBLOCK); if (command_fd < 0) die("command open"); pollfds[0].fd = 0; pollfds[0].events = vns_console ? POLLIN : 0; pollfds[1].fd = command_fd; pollfds[1].events = POLLIN; for (i = 0; i < ifcount; ++i) { pollfds[2+i].fd = iflist[i].udp_fd = udp_open(&(iflist[i].tip), &(iflist[i].rtip)); pollfds[2+i].events = POLLIN; if (!vns_console) { pollfds[2+ifcount+i].fd = iflist[i].tap_fd = tap_open(iflist[i].tapname); pollfds[2+ifcount+i].events = POLLIN; } } //pollfds: 0=stdin, 1=command pipe, 2..2+ifcount-1=UDP, 2+ifcount..2+2*ifcount-1=TAP // ---------------- initialize ---------------- pid_fd = fopen(pid_file, "w"); if (pid_fd == NULL) die("pid output"); fprintf(pid_fd, "%d", getpid()); fclose(pid_fd); srand(time(NULL)); if (vns_console) { con_init(); vns_wAuthReq(buffer); con_write(buffer); } // ---------------- main poll loop ---------------- while (1) { pollres = poll(pollfds, 2+(vns_console?1:2)*ifcount, -1); if (pollres == -1) die("poll"); else if (pollres == 0) { perror("poll timeout"); continue; } /* for (i = 0; i < 2+(vns_console?1:2)*ifcount; ++i) { if (pollfds[i].revents & (POLLERR | POLLHUP | POLLNVAL)) { FILE* dbglog = fopen("/tmp/vnlsvc.debug.log","a"); fprintf(dbglog,"%d %d %d %x\n",time(NULL),getpid(),i,pollfds[i].revents); fclose(dbglog); } } */ // ---------------- VNS protocol, console to UDP ---------------- if (vns_console && (pollfds[0].revents & POLLIN)) { if (con_read(buffer)) { switch (vns_getType(buffer)) { case VNS_AUTH_REPLY: vns_wAuthStatus(buffer); con_write(buffer); break; case VNSOPEN: iflist_hwinfo(vnshwinfo, iflist, ifcount); con_write(buffer); break; case VNSPACKET: i = iflist_find(iflist, ifcount, vnspkthdr->mInterfaceName); if (i < 0) break; len = ntohl(vnspkthdr->mLen) - sizeof(c_packet_header); if (lossy_filter(iflist[i].lossy)) { udp_write(iflist[i].udp_fd, pktbuffer, len, &(iflist[i].rtip)); } break; } } } // ---------------- console error ---------------- if (vns_console && (pollfds[0].revents & (POLLERR | POLLHUP))) { die("console error"); } // ---------------- setlossy command ---------------- if (pollfds[1].revents & POLLIN) { if (command_eth < 0 && 1 == read(command_fd, buffer, 1)) { command_eth = buffer[0]; } if (1 == read(command_fd, buffer, 1) && command_eth < ifcount) { iflist[command_eth].lossy = buffer[0]; } } if (pollfds[1].revents & POLLHUP) { command_eth = -1; close(command_fd); pollfds[1].fd = command_fd = open(command_file, O_RDONLY | O_NONBLOCK); if (command_fd < 0) die("command reopen"); } for (i = 0; i < ifcount; ++i) { // ---------------- UDP to console/TAP ---------------- if (pollfds[2+i].revents & POLLIN) { len = udp_read(iflist[i].udp_fd, pktbuffer, &(iflist[i].rtip)); if (len > 0) { if (vns_console) { vns_wPacketHdr(buffer, len, iflist[i].ifname); con_write(buffer); } else { tap_write(iflist[i].tap_fd, pktbuffer, len); } } } // ---------------- UDP error ---------------- if (pollfds[2+i].revents & POLLERR) { int sockerror; socklen_t socklen = sizeof(int); getsockopt(iflist[i].udp_fd, SOL_SOCKET, SO_ERROR, &sockerror, &socklen); } // ---------------- TAP to UDP ---------------- if (!vns_console && (pollfds[2+ifcount+i].revents & POLLIN)) { len = tap_read(iflist[i].tap_fd, pktbuffer); if (len > 0 && lossy_filter(iflist[i].lossy)) { udp_write(iflist[i].udp_fd, pktbuffer, len, &(iflist[i].rtip)); } } } } }
void do_newuser(int argc, char *argv[]) { int i, l, n, nuid; char *p, *md, *q; Rune *r; Userid *s; Uid *ui, *u2; nuid = 10000; md = 0; if(argc == 2) { nuid = 1; argv[2] = ":"; } for(r = ichar; *r; r++) if(utfrune(argv[1], *r)) { print("illegal character in name\n"); return; } if(strlen(argv[1]) > NAMELEN-1) { print("name %s too long\n", argv[1]); return; } p = argv[2]; switch(*p) { case '?': ui = chkuid(argv[1], 1); if(ui == 0) return; pentry(buf, ui); n = strlen(buf); p = buf; while(n > PRINTSIZE-5) { q = p; p += PRINTSIZE-5; n -= PRINTSIZE-5; i = *p; *p = 0; print("%s", q); *p = i; } print("%s\n", p); return; case ':': if(chkuid(argv[1], 0)) return; while(uidtop(nuid) != 0) nuid++; if(cons.nuid >= conf.nuid) { print("conf.nuid too small (%ld)\n", conf.nuid); return; } wlock(&uidgc.uidlock); ui = &uid[cons.nuid++]; ui->uid = nuid; ui->lead = 0; if(nuid < 10000) { ui->lead = ui->uid; md = argv[1]; } strcpy(ui->name, argv[1]); ui->ngrp = 0; qsort(uid, cons.nuid, sizeof(uid[0]), byuid); wunlock(&uidgc.uidlock); break; case '=': ui = chkuid(argv[1], 1); if(ui == 0) return; p++; if(*p == '\0') { ui->lead = 0; break; } u2 = chkuid(p, 1); if(u2 == 0) return; ui->lead = u2->uid; break; case '+': ui = chkuid(argv[1], 1); if(ui == 0) return; p++; u2 = chkuid(p, 1); if(u2 == 0) return; if(u2->uid == ui->uid) return; if(cons.ngid+ui->ngrp+1 >= conf.gidspace) { print("conf.gidspace too small (%ld)\n", conf.gidspace); return; } for(i = 0; i < ui->ngrp; i++) { if(ui->gtab[i] == u2->uid) { print("member already in group\n"); return; } } wlock(&uidgc.uidlock); s = gidspace+cons.ngid; memmove(s, ui->gtab, ui->ngrp*sizeof(*s)); ui->gtab = s; s[ui->ngrp++] = u2->uid; cons.ngid += ui->ngrp+1; wunlock(&uidgc.uidlock); break; case '-': ui = chkuid(argv[1], 1); if(ui == 0) return; p++; u2 = chkuid(p, 1); if(u2 == 0) return; for(i = 0; i < ui->ngrp; i++) if(ui->gtab[i] == u2->uid) break; if(i == ui->ngrp) { print("%s not in group\n", p); return; } wlock(&uidgc.uidlock); s = ui->gtab+i; ui->ngrp--; memmove(s, s+1, (ui->ngrp-i)*sizeof(*s)); wunlock(&uidgc.uidlock); break; default: if(chkuid(argv[2], 0)) return; for(r = ichar; *r; r++) if(utfrune(argv[2], *r)) { print("illegal character in name\n"); return; } ui = chkuid(argv[1], 1); if(ui == 0) return; if(strlen(argv[2]) > NAMELEN-1) { print("name %s too long\n", argv[2]); return; } wlock(&uidgc.uidlock); strcpy(ui->name, argv[2]); wunlock(&uidgc.uidlock); break; } if(walkto("/adm/users") || con_open(FID2, OWRITE|OTRUNC)) { print("can't open /adm/users for write\n"); return; } cons.offset = 0; for(i = 0; i < cons.nuid; i++) { pentry(buf, &uid[i]); l = strlen(buf); n = con_write(FID2, buf, cons.offset, l); if(l != n) print("short write on /adm/users\n"); cons.offset += n; } if(md != 0) { sprint(buf, "create /usr/%s %s %s 755 d", md, md, md); print("%s\n", buf); cmd_exec(buf); } }
int adduser(char *user, int isgroup) { char stat[DIRREC]; char msg[100]; Uid *u; int i, c, nu; /* * check uniq of name * and get next uid */ cmd_exec("cfs"); cmd_exec("user"); if(isgroup) nu = 9000; else nu = 0; for(i=0, u=uid; i<conf.nuid; i++,u++) { c = u->uid; if(c == 0) break; if(strcmp(uidspace+u->offset, user) == 0) return 1; if(c >= 9000 && !isgroup) continue; if(c > nu) nu = c; } nu++; if(isgroup){ if(nu >= 0x10000) { cprint("out of group ids\n"); return 0; } } else { if(nu >= 9000) { cprint("out of user ids\n"); return 0; } } /* * write onto adm/users */ if(con_clone(FID1, FID2) || con_path(FID2, "/adm/users") || con_open(FID2, 1)) { cprint("can't open /adm/users\n"); return 0; } sprint(msg, "%d:%s:%s:\n", nu, user, user); cprint("add user %s", msg); c = strlen(msg); i = con_stat(FID2, stat); if(i){ cprint("can't stat /adm/users: %s\n", errstring[i]); return 0; } i = con_write(FID2, msg, statlen(stat), c); if(i != c){ cprint("short write on /adm/users: %d %d\n", c, i); return 0; } return 1; }
int con_vout(const char *fmt, va_list va) { return con_write(console.handle_out, fmt, va); }
int con_verr(const char *fmt, va_list va) { return con_write(console.handle_err, fmt, va); }