PERFORCE change 214374 for review
Robert Watson
rwatson at FreeBSD.org
Sat Jul 14 12:11:52 UTC 2012
http://p4web.freebsd.org/@@214374?ac=10
Change 214374 by rwatson at 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 <sys/types.h>
+#include <sys/endian.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
@@ -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<maxwidth; x++)
imgbuf[x+y*maxwidth] = 0;
}
+
+#define FBD_BORDER_LWIDTH 2
+#define FBD_BORDER_SPACE 3
+#define FBD_BORDER_WIDTH (FBD_BORDER_LWIDTH + FBD_BORDER_SPACE * 2)
+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)
+{
+ int dheight, dwidth, x0, y0, x, y;
+ int i, textlines, linewidth, maxwidth;
+ int textheight, textwidth, titleheight, titlewidth;
+ char **lines;
+ char *textdup;
+ u_int32_t *textbuf, *titlebuf, *bgimage;
+ struct tsstate *ts;
+
+ titlewidth = strlen(title) * fb_get_font_width() * 2;
+ titleheight = fb_get_font_height() * 2;
+
+ textlines = 0;
+ linewidth = 0;
+ textwidth = 0;
+ for (i = 0; text[i] != '\0'; i++) {
+ if (text[i] == '\n') {
+ textlines++;
+ textwidth = (linewidth > 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 <bsd.arch.inc.mk>
==== //depot/projects/ctsrd/cheribsd/src/ctsrd/browser/browser.c#3 (text+ko) ====
@@ -31,9 +31,11 @@
#include <sys/types.h>
#include <sys/param.h>
+#include <sys/capability.h>
#include <sys/stat.h>
#include <sys/wait.h>
+#include <assert.h>
#include <ctype.h>
#include <de4tc.h>
#include <dirent.h>
@@ -43,25 +45,29 @@
#include <fnmatch.h>
#include <libutil.h>
#include <magic.h>
+#include <poll.h>
+#include <signal.h>
+#define _WITH_DPRINTF
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <time.h>
#include <unistd.h>
+#include <vis.h>
-#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 <dir> <tty>\n");
- printf(" browser -T <dir>\n");
+ printf("usage: browser [-f] <dir> <tty>\n");
+ printf(" browser [-f] -T <dir>\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) <<<
More information about the p4-projects
mailing list