From owner-p4-projects@FreeBSD.ORG Sat Jul 14 12:11:52 2012 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 986291065670; Sat, 14 Jul 2012 12:11:48 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 4C0EB1065674 for ; Sat, 14 Jul 2012 12:11:48 +0000 (UTC) (envelope-from bb+lists.freebsd.perforce@cyrus.watson.org) Received: from skunkworks.freebsd.org (skunkworks.freebsd.org [IPv6:2001:4f8:fff6::2d]) by mx1.freebsd.org (Postfix) with ESMTP id 32D708FC08 for ; Sat, 14 Jul 2012 12:11:48 +0000 (UTC) Received: from skunkworks.freebsd.org (localhost [127.0.0.1]) by skunkworks.freebsd.org (8.14.4/8.14.4) with ESMTP id q6ECBmC2064358 for ; Sat, 14 Jul 2012 12:11:48 GMT (envelope-from bb+lists.freebsd.perforce@cyrus.watson.org) Received: (from perforce@localhost) by skunkworks.freebsd.org (8.14.4/8.14.4/Submit) id q6ECBlCA064355 for perforce@freebsd.org; Sat, 14 Jul 2012 12:11:47 GMT (envelope-from bb+lists.freebsd.perforce@cyrus.watson.org) Date: Sat, 14 Jul 2012 12:11:47 GMT Message-Id: <201207141211.q6ECBlCA064355@skunkworks.freebsd.org> X-Authentication-Warning: skunkworks.freebsd.org: perforce set sender to bb+lists.freebsd.perforce@cyrus.watson.org using -f From: Robert Watson To: Perforce Change Reviews Precedence: bulk Cc: Subject: PERFORCE change 214374 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 14 Jul 2012 12:11:52 -0000 http://p4web.freebsd.org/@@214374?ac=10 Change 214374 by rwatson@rwatson_svr_ctsrd_mipsbuild on 2012/07/14 12:11:38 Integrate CheriBSD branch to pick up demo fixes/improvements, DE4 heartbeat LED, BERI ROM device node. Affected files ... .. //depot/projects/ctsrd/cheribsd/src/ctsrd-lib/libde4tc/de4tc.c#3 integrate .. //depot/projects/ctsrd/cheribsd/src/ctsrd-lib/libde4tc/de4tc.h#3 integrate .. //depot/projects/ctsrd/cheribsd/src/ctsrd-lib/libde4tc/syscons-fonts.c#2 integrate .. //depot/projects/ctsrd/cheribsd/src/ctsrd/Makefile#4 integrate .. //depot/projects/ctsrd/cheribsd/src/ctsrd/browser/browser.c#3 integrate .. //depot/projects/ctsrd/cheribsd/src/ctsrd/mtlctl/Makefile#1 branch .. //depot/projects/ctsrd/cheribsd/src/ctsrd/mtlctl/mtlctl.c#1 branch .. //depot/projects/ctsrd/cheribsd/src/ctsrd/wr/Makefile#1 branch .. //depot/projects/ctsrd/cheribsd/src/ctsrd/wr/wr.c#1 branch .. //depot/projects/ctsrd/cheribsd/src/etc/rc.d/tmp#2 integrate .. //depot/projects/ctsrd/cheribsd/src/sys/dev/terasic/de4led/terasic_de4led.c#3 integrate .. //depot/projects/ctsrd/cheribsd/src/sys/mips/conf/BERI_DE4.hints#3 integrate .. //depot/projects/ctsrd/cheribsd/src/sys/mips/conf/BERI_TEMPLATE#2 integrate Differences ... ==== //depot/projects/ctsrd/cheribsd/src/ctsrd-lib/libde4tc/de4tc.c#3 (text+ko) ==== @@ -29,6 +29,7 @@ */ #include +#include #include #include #include @@ -54,7 +55,7 @@ static int fademode=0; volatile u_int32_t *pfbp; static volatile u_int16_t *tfbp; -static volatile u_int32_t *mtlctrl; +volatile u_int32_t *mtlctrl; // fade timing (for crude timing loop) static const int fb_cross_fade_time = 500; @@ -144,6 +145,50 @@ } while(touch_count!=0); } +/***************************************************************************** + * Revised touch screen polling interface + *****************************************************************************/ + +struct tsstate* +ts_poll(void) +{ + struct timespec stime = {0, 0.1}; + static struct tsstate *sp; + int init = 0; + struct tsstate tmp_s; + + if (sp == NULL) { + sp = malloc(sizeof(struct tsstate)); + if (sp == NULL) + err(1, "malloc of tstate"); + init = 1; + } + + for (;;) { + tmp_s.ts_x1 = le32toh(mtlctrl[3]); + tmp_s.ts_y1 = le32toh(mtlctrl[4]); + tmp_s.ts_x2 = le32toh(mtlctrl[5]); + tmp_s.ts_y2 = le32toh(mtlctrl[6]); + tmp_s.ts_gesture = le32toh(mtlctrl[7]); + if (tmp_s.ts_gesture < 0) { + nanosleep(&stime, NULL); + continue; + } + tmp_s.ts_count = tmp_s.ts_gesture >> 8; + tmp_s.ts_gesture &= 0xFF; + + if (init || + tmp_s.ts_x1 != sp->ts_x1 || tmp_s.ts_y1 != sp->ts_y1 || + tmp_s.ts_x2 != sp->ts_x2 || tmp_s.ts_y2 != sp->ts_y2 || + tmp_s.ts_count != sp->ts_count || + tmp_s.ts_gesture != sp->ts_gesture) { + *sp = tmp_s; + return (sp); + } + nanosleep(&stime, NULL); + } +} + /***************************************************************************** * frame buffer routines @@ -222,6 +267,16 @@ void +fb_fill_buf(u_int32_t *buf, u_int32_t color, int width, int height) +{ + int i; + + for (i = 0; i < width * height; i++) + buf[i] = color; +} + + +void fb_post(u_int32_t *buf) { int addr; @@ -242,6 +297,16 @@ void +fb_save(u_int32_t *buf) +{ + int i; + + for (i = 0; i < fb_height * fb_width; i++) + buf[i] = pfbp[i]; +} + + +void fb_blend(int blend_text_bg, int blend_text_fg, int blend_pixel, int wash __unused) { mtlctrl[0] = @@ -466,3 +531,133 @@ for(x=0; x textwidth) ? linewidth : + textwidth; + linewidth = 0; + } else + linewidth++; + } + textlines++; + textwidth = (linewidth > textwidth) ? linewidth : textwidth; + textwidth *= fb_get_font_width() * 2; + textheight = fb_get_font_height() * 2; + + maxwidth = (textwidth > titlewidth) ? textwidth : titlewidth; + + dwidth = FBD_BORDER_WIDTH + maxwidth + FBD_BORDER_WIDTH; + if (dwidth > fb_width) + errx(1, "text too wide"); + + dheight = FBD_BORDER_WIDTH + titleheight + FBD_BORDER_WIDTH + + textheight * textlines + FBD_BORDER_WIDTH; + if (dheight > fb_height) + errx(1, "text too tall"); + + x0 = (fb_width - dwidth) / 2; + y0 = (fb_height - dheight) / 2; + + lines = malloc(textlines * sizeof(char *)); + if (lines == NULL) + err(1, "malloc"); + textdup = strdup(text); + if (textdup == NULL) + err(1, "strdup"); + textlines = 0; + lines[textlines] = textdup; + for (i = 0; textdup[i] != '\0'; i++) { + if (textdup[i] == '\n') { + textdup[i] = '\0'; + lines[++textlines] = &textdup[i+1]; + } + } + textlines++; + + bgimage = malloc(sizeof(u_int32_t) * fb_width * fb_height); + if (bgimage == NULL) + err(1, "malloc"); + fb_save(bgimage); + + fb_fill_region(bgcolor, x0, y0, dwidth, dheight); + for (x = x0 + FBD_BORDER_SPACE; x < x0 + dwidth - FBD_BORDER_SPACE; + x++) { + for (y = 0; y < FBD_BORDER_LWIDTH; y++) { + fb_putpixel(x, y0 + FBD_BORDER_SPACE + y, bcolor); + fb_putpixel(x, y0 + FBD_BORDER_SPACE + y + + FBD_BORDER_WIDTH + titleheight, bcolor); + fb_putpixel(x, y0 + FBD_BORDER_SPACE + y + dheight - + FBD_BORDER_WIDTH, bcolor); + } + } + for (y = y0 + FBD_BORDER_SPACE; y < y0 + dheight - FBD_BORDER_SPACE; + y++) { + for (x = 0; x < FBD_BORDER_LWIDTH; x++) { + fb_putpixel(x0 + FBD_BORDER_SPACE + x, y, bcolor); + fb_putpixel(x0 + dwidth + FBD_BORDER_SPACE + x - + FBD_BORDER_WIDTH, y, bcolor); + } + } + + titlebuf = malloc(sizeof(u_int32_t) * titlewidth * titleheight); + if (titlebuf == NULL) + err(1, "malloc"); + fb_render_text(title, 2, tcolor, bgcolor, titlebuf, + titlewidth, titleheight); + fb_post_region(titlebuf, + x0 + (dwidth - titlewidth) / 2, y0 + FBD_BORDER_WIDTH, + titlewidth, titleheight); + free(titlebuf); + + printf("text width %d height %d\n", textwidth, textheight); + textbuf = malloc(sizeof(u_int32_t) * textwidth * textheight); + if (textbuf == NULL) + err(1, "malloc"); + for(i = 0; i < textlines; i++) { + printf("writing text '%s'\n", lines[i]); + fb_fill_buf(textbuf, bgcolor, textwidth, textheight); + fb_render_text(lines[i], 2, tcolor, bgcolor, textbuf, + textwidth, textheight); + fb_post_region(textbuf, x0 + FBD_BORDER_WIDTH, + y0 + 2 * FBD_BORDER_WIDTH + titleheight + i * textheight, + textwidth, textheight); + } + free(textbuf); + free(lines); + + switch (type) { + case FBDT_PINCH2CLOSE: + for (;;) { + ts = ts_poll(); + if (ts->ts_gesture == TSG2_ZOOM_OUT) { + fb_post(bgimage); + return(FBDA_OK); + } + } + default: + err(1, "Unhandled dialog type"); + } +} ==== //depot/projects/ctsrd/cheribsd/src/ctsrd-lib/libde4tc/de4tc.h#3 (text+ko) ==== @@ -32,6 +32,56 @@ #ifndef _DE4TC_H_ #define _DE4TC_H_ +#define TSG_NONE 0x00 +#define TSG_NORTH 0x10 +#define TSG_NORTHEAST 0x12 +#define TSG_EAST 0x14 +#define TSG_SOUTHEAST 0x16 +#define TSG_SOUTH 0x18 +#define TSG_SOUTHWEST 0x1A +#define TSG_WEST 0x1C +#define TSG_NORTHWEST 0x1E +#define TSG_ROTATE_CW 0x28 /* Clockwise */ +#define TSG_ROTATE_CCW 0x29 /* Counter Clockwise */ +#define TSG_CLICK 0x20 +#define TSG_DCLICK 0x22 /* Double Click */ +#define TSG2_NORTH 0x30 +#define TSG2_NORTHEAST 0x32 +#define TSG2_EAST 0x34 +#define TSG2_SOUTHEAST 0x36 +#define TSG2_SOUTH 0x38 +#define TSG2_SOUTHWEST 0x3A +#define TSG2_WEST 0x3C +#define TSG2_NORTHWEST 0x3E +#define TSG2_CLICK 0x40 +#define TSG2_ZOOM_IN 0x48 +#define TSG2_ZOOM_OUT 0x49 + +typedef enum { + FBDA_CANCEL, + FBDA_OK, + FBDA_YES, + FBDA_NO +} fb_dialog_action; + +typedef enum { + FBDT_PINCH2CLOSE, +#ifdef NOTYET + FBDT_OK, + FBDT_OKCANCEL, + FBDT_YESNO +#endif +} fb_dialog_type; + +struct tsstate { + int ts_x1; + int ts_y1; + int ts_x2; + int ts_y2; + int ts_count; + int ts_gesture; +}; + extern int touch_x0; extern int touch_y0; extern int touch_x1; @@ -42,22 +92,29 @@ extern const int fb_height; extern const int fb_width; +extern volatile u_int32_t *pfbp; +extern volatile u_int32_t *mtlctrl; + void multitouch_pole(void); void multitouch_filter(void); void multitouch_release_event(void); +struct tsstate* ts_poll(void); void fb_init(void); void fb_fini(void); u_int32_t fb_colour(int r, int g, int b); void fb_putpixel(int px, int py, int colour); void fb_fill(int col); void fb_fill_region(u_int32_t colour, int x, int y, int w, int h); +void fb_fill_buf(u_int32_t *buf, u_int32_t color, int width, int height); void fb_post(u_int32_t *buf); void fb_post_region(u_int32_t *buf, int x, int y, int w, int h); +void fb_save(u_int32_t *buf); void fb_blend(int blend_text_bg, int blend_text_fg, int blend_pixel, int wash); void fb_text_cursor(int x, int y); void fb_fade2off(void); void fb_fade2on(void); void fb_fade2text(int textbg_alpha); + void plot_line(int x1, int y1, int x2, int y2, unsigned int colour); void read_png_file(const char* file_name, u_int32_t* imgbuf, int maxwidth, int maxheight); @@ -66,5 +123,7 @@ int fb_get_font_width(void); void fb_render_text(const char *string, int expand, u_int32_t con, u_int32_t coff, u_int32_t *buffer, int w, int h); +fb_dialog_action fb_dialog(fb_dialog_type type, u_int32_t bcolor, + u_int32_t bgcolor, u_int32_t tcolor, const char *title, const char *text); #endif /* !_DE4TC_H_ */ ==== //depot/projects/ctsrd/cheribsd/src/ctsrd-lib/libde4tc/syscons-fonts.c#2 (text+ko) ==== @@ -52,8 +52,6 @@ const int font_width = 8; static int font_height; -extern volatile u_int32_t *pfbp; - /* * Guess which file to open. Try to open each combination of a specified set * of file name components. ==== //depot/projects/ctsrd/cheribsd/src/ctsrd/Makefile#4 (text+ko) ==== @@ -4,9 +4,11 @@ cycle_led \ flashit \ minifile \ + mtlctl \ pictview \ showimage \ - spinner + spinner \ + wr .include ==== //depot/projects/ctsrd/cheribsd/src/ctsrd/browser/browser.c#3 (text+ko) ==== @@ -31,9 +31,11 @@ #include #include +#include #include #include +#include #include #include #include @@ -43,25 +45,29 @@ #include #include #include +#include +#include +#define _WITH_DPRINTF #include #include #include #include #include #include +#include -#define BASEIMG "/usr/share/images/browser.png" -#define ICONS "/usr/share/images/icons.png" +#define BASEIMG "/usr/share/images/browser.png" +#define ICONS "/usr/share/images/icons.png" -#define vwhite(v) fb_colour((v), (v), (v)) -#define vred(v) fb_colour((v), 0, 0) -#define vgreen(v) fb_colour(0, (v), 0) -#define vblue(v) fb_colour(0, 0, (v)) -#define black vwhite(0) -#define white vwhite(0xFF) -#define red vred(0xFF) -#define green vgreen(0xFF) -#define blue vblue(0xFF) +#define vwhite(v) fb_colour((v), (v), (v)) +#define vred(v) fb_colour((v), 0, 0) +#define vgreen(v) fb_colour(0, (v), 0) +#define vblue(v) fb_colour(0, 0, (v)) +#define black vwhite(0) +#define white vwhite(0xFF) +#define red vred(0xFF) +#define green vgreen(0xFF) +#define blue vblue(0xFF) /* * Each file is displayed in a 266x40 box: @@ -75,37 +81,52 @@ * +--------------------------------------------------------------------------+ * |----------------------------------(800/3 = 266) pixels--------------------| */ -#define FROW 41 -#define NCOL 3 -#define NROW 10 -#define NSLOTS (NCOL * NROW) -#define CWIDTH 266 -#define RHEIGHT 40 -#define ICON_WH 32 -#define BORDER 4 -#define CHAR_HEIGHT 32 -#define CHAR_WIDTH 16 -#define TEXT_OFFSET (BORDER + ICON_WH + BORDER) -#define _TEXTSPACE (CWIDTH - (TEXT_OFFSET + BORDER)) -#define TEXTSPACE (_TEXTSPACE - _TEXTSPACE % CHAR_WIDTH) +#define FROW 41 +#define NCOL 3 +#define NROW 10 +#define NSLOTS (NCOL * NROW) +#define CWIDTH 266 +#define RHEIGHT 40 +#define ICON_WH 32 +#define BORDER 4 +#define CHAR_HEIGHT 32 +#define CHAR_WIDTH 16 +#define TEXT_OFFSET (BORDER + ICON_WH + BORDER) +#define _TEXTSPACE (CWIDTH - (TEXT_OFFSET + BORDER)) +#define TEXTSPACE (_TEXTSPACE - _TEXTSPACE % CHAR_WIDTH) +/* + * The get_action() function polls for input and returns a slot number + * (either a line on the console or a space on the screen) or one of + * these actions. Internally it handles changing protection modes. + */ +#define ACT_NEXT 100 +#define ACT_PREV 101 +#define ACT_QUIT 102 +#define ACT_REFRESH 103 /* Beginning and ending colums of each sandbox type's name */ -#define SB_IMG_SPACING 20 -#define SB_IMG_NONE_BCOL 145 -#define SB_IMG_CAPSICUM_BCOL 223 -#define SB_IMG_CHERI_BCOL 350 -#define SB_IMG_NONE_ECOL (SB_IMG_CAPSICUM_BCOL - SB_IMG_SPACING) -#define SB_IMG_CAPSICUM_ECOL (SB_IMG_CHERI_BCOL - SB_IMG_SPACING) -#define SB_IMG_CHERI_ECOL 445 -#define SB_MINCOL SB_IMG_NONE_BCOL -#define SB_MAXCOL SB_IMG_CHERI_ECOL -#define SB_MINROW (fb_height - 39) -#define SB_MAXROW (fb_height - 1) +#define SB_IMG_SPACING 20 +#define SB_IMG_NONE_BCOL 145 +#define SB_IMG_CAPSICUM_BCOL 223 +#define SB_IMG_CHERI_BCOL 350 +#define SB_IMG_NONE_ECOL (SB_IMG_CAPSICUM_BCOL - SB_IMG_SPACING) +#define SB_IMG_CAPSICUM_ECOL (SB_IMG_CHERI_BCOL - SB_IMG_SPACING) +#define SB_IMG_CHERI_ECOL 445 +#define SB_MINCOL SB_IMG_NONE_BCOL +#define SB_MAXCOL SB_IMG_CHERI_ECOL +#define SB_MINROW (fb_height - 39) +#define SB_MAXROW (fb_height - 1) /* Start offsets for browser columns */ const int colstart[] = {0, 267, 534}; +struct dent { + struct dirent *entry; + char *desc; + u_int32_t *icon; +}; + /* * List of mappings between icons in the icons.png file and values from * the get_desc() function. Processing is first match so most specific @@ -147,25 +168,30 @@ struct _sbdata { enum _sbtype sbtype; + int enabled; int bcol; int ecol; } sbdata[] = { - { SB_NONE, SB_IMG_NONE_BCOL, SB_IMG_NONE_ECOL }, - { SB_CAPSICUM, SB_IMG_CAPSICUM_BCOL, SB_IMG_CAPSICUM_ECOL }, - { SB_CHERI, SB_IMG_CHERI_BCOL, SB_IMG_CHERI_ECOL }, - { 0, 0, 0 } + { SB_NONE, 1, SB_IMG_NONE_BCOL, SB_IMG_NONE_ECOL }, + { SB_CAPSICUM, 1, SB_IMG_CAPSICUM_BCOL, SB_IMG_CAPSICUM_ECOL }, + { SB_CHERI, 0, SB_IMG_CHERI_BCOL, SB_IMG_CHERI_ECOL }, + { 0, 0, 0, 0 } }; static u_int32_t *bgimage; static u_int32_t *icons; static magic_t magic; +static int zombies_waiting = 0; static void usage(void) { - printf("usage: browser \n"); - printf(" browser -T \n"); + printf("usage: browser [-f] \n"); + printf(" browser [-f] -T \n"); + printf("\n"); + printf(" -f Fork and monitor a child instance\n"); + printf(" -T Don't open a tty\n"); exit(1); } @@ -191,6 +217,118 @@ } static void +handle_sigchld(int sig __unused) +{ + + zombies_waiting = 1; +} + +static void +writeall(int fd, const char *buf, ssize_t len) +{ + ssize_t wlen = 0, n; + + while (wlen != len) { + n = write(fd, buf + wlen, len - wlen); + if (n < 0) { + syslog(LOG_ALERT, "write failed: %s", strerror(errno)); + err(1, "write"); + } + wlen += n; + } +} + +static void +fork_child(void) +{ + int pmaster, pslave, status; + ssize_t rlen; + pid_t pid; + struct sigaction act; + struct pollfd pfd[1]; + char buf[1024]; + +restart: + if (openpty(&pmaster, &pslave, NULL, NULL, NULL) == -1) + err(1, "openpty"); + pid = fork(); + if (pid < 0) + err(1, "fork()"); + else if (pid == 0) { + close(pmaster); + if (login_tty(pslave) < 0) { + syslog(LOG_ALERT, "login_tty failed in child: %s", strerror(errno)); + err(1, "tty_login"); + } + /* return to begin normal processing */ + return; + } + + memset (&act, 0, sizeof(act)); + act.sa_handler = handle_sigchld; + + if (sigaction(SIGCHLD, &act, 0)) + err(1, "sigacation"); + + close(pslave); + /* + * We poll for data from the child's pty. Don't bother looking for + * tty input since the child couldn't do anything with it. + */ + pfd[0].fd = pmaster; + pfd[0].events = POLLIN; + for (;;) { + if (poll(pfd, 2, INFTIM) < 0) { + if (errno == EINTR) + continue; + syslog(LOG_ALERT, "poll failed with %s", + strerror(errno)); + err(1, "poll"); + } + if (zombies_waiting) { + printf("zombie!\n"); + wait4(pid, &status, 0, NULL); + if (WIFEXITED(status) && WEXITSTATUS(status) != 0) { + warnx("child exited with %d", + WEXITSTATUS(status)); + if (WEXITSTATUS(status) == 99) { + warnx("child was exploited"); + fb_dialog(FBDT_PINCH2CLOSE, black, + white, black, + "Browser Exited", +"Browser vulnerability exploited\n" +"\n" +"Pinch to close dialog and restart" + ); + } + } else if(WIFSIGNALED(status)) { + warn("child killed by signal %d", + WTERMSIG(status)); + } else { + printf("child exited cleanly, exiting\n"); + exit(0); + } + printf("child exited badly, restarting\n"); + zombies_waiting = 0; + close(pmaster); /* XXX: should we drain it first? */ + fb_fill_region(vwhite(128), 0, 0, fb_width, fb_height); + goto restart; + } + + if (pfd[0].revents & POLLIN) { + rlen = read(pmaster, buf, sizeof(buf)); + if (rlen < 0) { + err(1, "read"); + } else if (rlen > 0) + writeall(1, buf, rlen); + } + } + + + +} + +static void init_magic(void) { magic = magic_open(MAGIC_MIME_TYPE); if (magic == NULL) @@ -202,6 +340,104 @@ } } +static const char * +get_magic(int fd) +{ + pid_t pid; + ssize_t rlen; + char buf[4096], *desc; + const char *cdesc; + int pfd[2], status; + + rlen = read(fd, buf, sizeof(buf)); + if (rlen == -1) + return "read-error"; + if (rlen == 0) + return "empty"; + + switch (sbtype) { + case SB_NONE: + return magic_buffer(magic, buf, rlen); + case SB_CAPSICUM: + if (pipe(pfd) == -1) + err(1, "pipe()"); + pid = fork(); + if (pid < 0) + err(1, "fork()"); + else if (pid == 0) { + close(fd); + close(pfd[0]); + fb_fini(); + /* XXX: do more cleanup here */ + cap_enter(); + + cdesc = magic_buffer(magic, buf, rlen); + if (cdesc == NULL) + dprintf(pfd[1], "badmagic"); + else + dprintf(pfd[1], "%s", cdesc); + close(pfd[1]); + exit(0); + } else { + close(pfd[1]); + while (wait4(pid, &status, 0, NULL) == -1) + if (errno != EINTR) + err(1, "wait4()"); + if (WIFEXITED(status) && + WEXITSTATUS(status) != 0) { + warnx("child exited with %d", + WEXITSTATUS(status)); + close(pfd[0]); + return "badmagic"; + } + else if(WIFSIGNALED(status)) { + warn("child killed by signal %d", + WTERMSIG(status)); + close(pfd[0]); + return "badmagic"; + } else { + rlen = read(pfd[0], buf, 128); + close(pfd[0]); + if (rlen == -1) + return "read error"; + if (rlen == 0 || rlen == 1) + return "unknown"; + /* Don't trust the result */ + desc = buf + rlen; + strvisx(desc, buf, rlen - 1, 0); + return (desc); + } + } + break; + case SB_CHERI: + return "devil"; + default: + errx(1, "invalid sandbox type"); + } +} + +static void +init_bgimage(void) +{ + int i, j, pixel, sb; + + bgimage = malloc(sizeof(u_int32_t) * fb_height * fb_width); + if (bgimage == NULL) + err(1, "malloc"); + read_png_file(BASEIMG, bgimage, fb_width, fb_height); + + for (sb = 0; sbdata[sb].sbtype != 0; sb++) { + if (sbdata[sb].enabled) + continue; + for (j = SB_MINROW; j < SB_MAXROW; j++) { + for (i = sbdata[sb].bcol; i <= sbdata[sb].ecol; i++) { + pixel = (j * fb_width) + i; + bgimage[pixel] = vwhite(((bgimage[pixel] >> 24) & 0xFF) / 2); + } + } + } +} + static void update_sandbox(enum _sbtype type) { @@ -221,7 +457,7 @@ pixel = (j * fb_width) + i; if (bgimage[pixel] != black) { /* XXX: Assuming we're either blue or white */ - value = (bgimage[pixel] >> 8) & 0xFF; + value = (bgimage[pixel] >> 24) & 0xFF; if (value == 0) { printf("unexpected zero value, pixel %08x\n", bgimage[pixel]); @@ -236,21 +472,6 @@ } static const char * -get_magic(int fd) -{ - switch (sbtype) { - case SB_NONE: - return magic_descriptor(magic, fd); - case SB_CAPSICUM: - return "devil"; - case SB_CHERI: - return "devil"; - default: - return "unknown"; - } -} - -static const char * get_desc(int dfd, struct dirent *entry) { int fd, type; @@ -314,177 +535,191 @@ return (NULL); } +static void +update_slot(int s, u_int32_t *icon, const char *text) +{ + u_int32_t textbuf[TEXTSPACE*CHAR_HEIGHT]; + + memset(textbuf, 0, sizeof(textbuf)); + fb_render_text(text, 2, blue, black, textbuf, + TEXTSPACE, CHAR_HEIGHT); + fb_post_region(textbuf, colstart[(s/NROW)] + TEXT_OFFSET, + FROW + (RHEIGHT * (s % NROW)) + BORDER, TEXTSPACE, + CHAR_HEIGHT); + fb_post_region(icon, colstart[(s/NROW)] + BORDER, + FROW + (RHEIGHT * (s % NROW)) + BORDER, ICON_WH, ICON_WH); +} + +static int +get_action(void) +{ + struct tsstate *ts; + int col, i, row; + + printf("entering get_action\n"); + + for (;;) { + ts = ts_poll(); + printf("gesture = %x\n", ts->ts_gesture); + if (ts->ts_gesture == TSG_CLICK) { + if (ts->ts_y1 < FROW) { + if (ts->ts_x1 > fb_width - 40) + return (ACT_QUIT); + } else if (ts->ts_y1 <= FROW + (NROW * RHEIGHT)) { + row = (ts->ts_y1 - FROW) / RHEIGHT; + for (col = NCOL - 1; + col > 0 && ts->ts_x1 < colstart[col]; col--) + /* do nothing */; + printf("row = %d, col = %d\n", row, col); + return (col * NROW + row); + } else { + if (ts->ts_x1 >= SB_MINCOL && + ts->ts_x1 <= SB_MAXCOL) { + for (i =0 ; ts->ts_x1 < sbdata[i].bcol || + ts->ts_x1 > sbdata[i].ecol; i++) + /* do nothing */; + assert(sbdata[i].sbtype != 0); + if (sbdata[i].sbtype == sbtype || + !sbdata[i].enabled) + continue; + update_sandbox(sbdata[i].sbtype); + return (ACT_REFRESH); + } + } + } + if (ts->ts_gesture == TSG_EAST) + return (ACT_PREV); + if (ts->ts_gesture == TSG_WEST) + return (ACT_NEXT); + } + /* NOTREACHED */ + return (ACT_QUIT); +} + static int browsedir(int dfd) { - int f, i, j, s; - long curloc, nextloc; + int action, topslot, j, curslot, maxdents, nfd, ndents, retfd; DIR *dirp; - struct dirent *entry, *entry2; - u_int32_t *icon, textbuf[TEXTSPACE*CHAR_HEIGHT]; - char line[256]; - const char *desc; + struct dirent *entry; + struct dent **dents, *dent; if ((dirp = fdopendir(dfd)) == NULL) err(1, "fdopendir()"); + ndents = 0; + maxdents = 1024; + dents = malloc(sizeof(struct dent *) * maxdents); + if (dents == NULL) + err(1, "malloc dents"); + + while ((entry = readdir(dirp)) != NULL) { + if (ndents == maxdents) { + maxdents *= 2; + dents = realloc(dents, sizeof(struct dent) * maxdents); + if (dents == NULL) + err(1, "realloc dents"); + } + if (strcmp(".", entry->d_name) == 0) + continue; + dents[ndents] = malloc(sizeof(struct dent)); + if (dents[ndents] == NULL) + err(1, "malloc dent[%d]", ndents); + memcpy(&(dents[ndents]->entry), &entry, sizeof(entry)); + dents[ndents]->desc = NULL; + dents[ndents]->icon = NULL; + ndents++; + } + + + topslot = 0; +render: fb_fill_region(black, colstart[0], FROW, fb_width, NROW * RHEIGHT); - - curloc = telldir(dirp); - nextloc = 0; - i = 0; -start: - seekdir(dirp, curloc); - /* telldir() return values are only good once so make a new copy! */ - curloc = telldir(dirp); - s = 0; - if (i > 0) { - printf("p %20s\n", "previous page"); - memset(textbuf, 0, sizeof(textbuf)); - fb_render_text("previous page", 2, white, black, textbuf, - TEXTSPACE, CHAR_HEIGHT); - fb_post_region(textbuf, colstart[(s/NROW)] + TEXT_OFFSET, - FROW + (RHEIGHT * (s % NROW)) + BORDER, TEXTSPACE, - CHAR_HEIGHT); - icon = get_icon("prev"); - fb_post_region(icon, colstart[(s/NROW)] + BORDER, - FROW + (RHEIGHT * (s % NROW)) + BORDER, ICON_WH, ICON_WH); - s = 1; + for(curslot = 0; curslot < NSLOTS && topslot + curslot < ndents; + curslot++) { + dent = dents[topslot + curslot]; + if (dent->desc == NULL) + dent->desc = strdup(get_desc(dfd, dent->entry)); + if (dent->icon == NULL) + dent->icon = get_icon(dent->desc); + + printf("%2d %20s %s\n", curslot, dent->entry->d_name, + dent->desc); + update_slot(curslot, dent->icon, dent->entry->d_name); } - entry = NULL; /* XXX: gcc warning */ - while(s < NSLOTS - 1 && (entry = readdir(dirp)) != NULL) { - desc = get_desc(dfd, entry); - printf("%2d %20s %s\n", s, entry->d_name, desc); - memset(textbuf, 0, sizeof(textbuf)); - fb_render_text(entry->d_name, 2, white, black, textbuf, - TEXTSPACE, CHAR_HEIGHT); - fb_post_region(textbuf, colstart[(s/NROW)]+TEXT_OFFSET, - FROW + (RHEIGHT * (s % NROW)) + BORDER, TEXTSPACE, CHAR_HEIGHT); - icon = get_icon(desc); - fb_post_region(icon, colstart[(s/NROW)] + BORDER, - FROW + (RHEIGHT * (s % NROW)) + BORDER, ICON_WH, ICON_WH); - s++; - } + if (curslot == NSLOTS) + curslot--; - nextloc = telldir(dirp); - if (s == NSLOTS - 1 && entry != NULL) { - /* - * If there are at least two more files then we don't want to - * display a "next" button and instead want either nothing or - * the final entry. - */ - entry = readdir(dirp); - if (entry == NULL) - nextloc = 0; - else { - entry2 = readdir(dirp); - if (entry2 == NULL) { - desc = get_desc(dfd, entry); - printf("%2d %20s %s\n", s, - entry->d_name, desc); - memset(textbuf, 0, sizeof(textbuf)); - fb_render_text(entry->d_name, 2, white, black, - textbuf, TEXTSPACE, CHAR_HEIGHT); - fb_post_region(textbuf, - colstart[(s/NROW)]+TEXT_OFFSET, - FROW + (RHEIGHT * (s % NROW)) + BORDER, - TEXTSPACE, CHAR_HEIGHT); - icon = get_icon(desc); - fb_post_region(icon, - colstart[(s/NROW)] + BORDER, - FROW + (RHEIGHT * (s % NROW)) + BORDER, - ICON_WH, ICON_WH); >>> TRUNCATED FOR MAIL (1000 lines) <<<