/* * offsetwriter.c * * USAGE: offsetwriter filename message... * * eg: * offsetwriter /mnt/testfile hello world * * The filename provided will be created or overwritten. * * This outputs delay times between I/O writes for debugging. Should * be high, low (or negative) delay times will mess up the message, * and could be due to network congestion. * * Written by Fishworks for Analytics testing: * http://blogs.sun.com/brendan/entry/heat_map_analytics * This code is provided AS IS, and is NOT SUPPORTED in any way. */ #include #include #include #include #include #include #include #include #include #define NCHARS 128 /* number of chars in char set */ #define NLINES 7 /* number of lines in a banner character */ #define NPOS 8 /* number of char positions per banner char */ #define BLKSIZE 32 * 1024 #define BUFSIZE 8192 #define START 32 * 1024 static char ctbl[NCHARS][NLINES] = { 0, 000, 000, 000, 000, 000, 000, /* below 040 */ 0, 000, 000, 000, 000, 000, 000, /* below 040 */ 0, 000, 000, 000, 000, 000, 000, /* below 040 */ 0, 000, 000, 000, 000, 000, 000, /* below 040 */ 0, 000, 000, 000, 000, 000, 000, /* below 040 */ 0, 000, 000, 000, 000, 000, 000, /* below 040 */ 0, 000, 000, 000, 000, 000, 000, /* below 040 */ 0, 000, 000, 000, 000, 000, 000, /* below 040 */ 0, 000, 000, 000, 000, 000, 000, /* below 040 */ 0, 000, 000, 000, 000, 000, 000, /* below 040 */ 0, 000, 000, 000, 000, 000, 000, /* below 040 */ 0, 000, 000, 000, 000, 000, 000, /* below 040 */ 0, 000, 000, 000, 000, 000, 000, /* below 040 */ 0, 000, 000, 000, 000, 000, 000, /* below 040 */ 0, 000, 000, 000, 000, 000, 000, /* below 040 */ 0, 000, 000, 000, 000, 000, 000, /* below 040 */ 0, 000, 000, 000, 000, 000, 000, /* below 040 */ 0, 000, 000, 000, 000, 000, 000, /* below 040 */ 0, 000, 000, 000, 000, 000, 000, /* below 040 */ 0, 000, 000, 000, 000, 000, 000, /* below 040 */ 0, 000, 000, 000, 000, 000, 000, /* below 040 */ 0, 000, 000, 000, 000, 000, 000, /* below 040 */ 0, 000, 000, 000, 000, 000, 000, /* below 040 */ 0, 000, 000, 000, 000, 000, 000, /* below 040 */ 0, 000, 000, 000, 000, 000, 000, /* below 040 */ 0, 000, 000, 000, 000, 000, 000, /* below 040 */ 0, 000, 000, 000, 000, 000, 000, /* below 040 */ 0, 000, 000, 000, 000, 000, 000, /* below 040 */ 0, 000, 000, 000, 000, 000, 000, /* below 040 */ 0, 000, 000, 000, 000, 000, 000, /* below 040 */ 0, 000, 000, 000, 000, 000, 000, /* below 040 */ 0, 000, 000, 000, 000, 000, 000, /* below 040 */ 0, 000, 000, 000, 000, 000, 000, /* */ 034, 034, 034, 010, 0, 034, 034, /* ! */ 0167, 0167, 042, 0, 0, 0, 0, /* " */ 024, 024, 0177, 024, 0177, 024, 024, /* # */ 076, 0111, 0110, 076, 011, 0111, 076, /* $ */ 0161, 0122, 0164, 010, 027, 045, 0107, /* % */ 030, 044, 030, 070, 0105, 0102, 071, /* & */ 034, 034, 010, 020, 0, 0, 0, /* ' */ 014, 020, 040, 040, 040, 020, 014, /* ( */ 030, 4, 2, 2, 2, 4, 030, /* ) */ 0, 042, 024, 0177, 024, 042, 0, /* * */ 0, 010, 010, 076, 010, 010, 0, /* + */ 0, 0, 0, 034, 034, 010, 020, /* , */ 0, 0, 0, 076, 0, 0, 0, /* - */ 0, 0, 0, 0, 034, 034, 034, /* . */ 1, 2, 4, 010, 020, 040, 0100, /* / */ 034, 042, 0101, 0101, 0101, 042, 034, /* 0 */ 010, 030, 050, 010, 010, 010, 076, /* 1 */ 076, 0101, 1, 076, 0100, 0100, 0177, /* 2 */ 076, 0101, 1, 076, 1, 0101, 076, /* 3 */ 0100, 0102, 0102, 0102, 0177, 2, 2, /* 4 */ 0177, 0100, 0100, 0176, 1, 0101, 076, /* 5 */ 076, 0101, 0100, 0176, 0101, 0101, 076, /* 6 */ 0177, 0102, 04, 010, 020, 020, 020, /* 7 */ 076, 0101, 0101, 076, 0101, 0101, 076, /* 8 */ 076, 0101, 0101, 077, 1, 0101, 076, /* 9 */ 010, 034, 010, 0, 010, 034, 010, /* : */ 034, 034, 0, 034, 034, 010, 020, /* ; */ 4, 010, 020, 040, 020, 010, 4, /* < */ 0, 0, 076, 0, 076, 0, 0, /* = */ 020, 010, 4, 2, 4, 010, 020, /* > */ 076, 0101, 1, 016, 010, 0, 010, /* ? */ 076, 0101, 0135, 0135, 0136, 0100, 076, /* @ */ 010, 024, 042, 0101, 0177, 0101, 0101, /* A */ 0176, 0101, 0101, 0176, 0101, 0101, 0176, /* B */ 076, 0101, 0100, 0100, 0100, 0101, 076, /* C */ 0176, 0101, 0101, 0101, 0101, 0101, 0176, /* D */ 0177, 0100, 0100, 0174, 0100, 0100, 0177, /* E */ 0177, 0100, 0100, 0174, 0100, 0100, 0100, /* F */ 076, 0101, 0100, 0117, 0101, 0101, 076, /* G */ 0101, 0101, 0101, 0177, 0101, 0101, 0101, /* H */ 034, 010, 010, 010, 010, 010, 034, /* I */ 1, 1, 1, 1, 0101, 0101, 076, /* J */ 0102, 0104, 0110, 0160, 0110, 0104, 0102, /* K */ 0100, 0100, 0100, 0100, 0100, 0100, 0177, /* L */ 0101, 0143, 0125, 0111, 0101, 0101, 0101, /* M */ 0101, 0141, 0121, 0111, 0105, 0103, 0101, /* N */ 0177, 0101, 0101, 0101, 0101, 0101, 0177, /* O */ 0176, 0101, 0101, 0176, 0100, 0100, 0100, /* P */ 076, 0101, 0101, 0101, 0105, 0102, 075, /* Q */ 0176, 0101, 0101, 0176, 0104, 0102, 0101, /* R */ 076, 0101, 0100, 076, 1, 0101, 076, /* S */ 0177, 010, 010, 010, 010, 010, 010, /* T */ 0101, 0101, 0101, 0101, 0101, 0101, 076, /* U */ 0101, 0101, 0101, 0101, 042, 024, 010, /* V */ 0101, 0111, 0111, 0111, 0111, 0111, 066, /* W */ 0101, 042, 024, 010, 024, 042, 0101, /* X */ 0101, 042, 024, 010, 010, 010, 010, /* Y */ 0177, 2, 4, 010, 020, 040, 0177, /* Z */ 076, 040, 040, 040, 040, 040, 076, /* [ */ 0100, 040, 020, 010, 004, 002, 001, /* \ */ 076, 2, 2, 2, 2, 2, 076, /* ] */ 010, 024, 042, 0, 0, 0, 0, /* ^ */ 0, 000, 000, 000, 000, 000, 0177, /* _ */ 034, 034, 010, 04, 0, 0, 0, /* ` */ 0, 014, 022, 041, 077, 041, 041, /* A */ 0, 076, 041, 076, 041, 041, 076, /* B */ 0, 036, 041, 040, 040, 041, 036, /* C */ 0, 076, 041, 041, 041, 041, 076, /* D */ 0, 077, 040, 076, 040, 040, 077, /* E */ 0, 077, 040, 076, 040, 040, 040, /* F */ 0, 036, 041, 040, 047, 041, 036, /* G */ 0, 041, 041, 077, 041, 041, 041, /* H */ 0, 004, 004, 004, 004, 004, 004, /* I */ 0, 001, 001, 001, 001, 041, 036, /* J */ 0, 041, 042, 074, 044, 042, 041, /* K */ 0, 040, 040, 040, 040, 040, 077, /* L */ 0, 041, 063, 055, 041, 041, 041, /* M */ 0, 041, 061, 051, 045, 043, 041, /* N */ 0, 036, 041, 041, 041, 041, 036, /* O */ 0, 076, 041, 041, 076, 040, 040, /* P */ 0, 036, 041, 041, 045, 042, 035, /* Q */ 0, 076, 041, 041, 076, 042, 041, /* R */ 0, 036, 040, 036, 001, 041, 036, /* S */ 0, 037, 004, 004, 004, 004, 004, /* T */ 0, 041, 041, 041, 041, 041, 036, /* U */ 0, 041, 041, 041, 041, 022, 014, /* V */ 0, 041, 041, 041, 055, 063, 041, /* W */ 0, 041, 022, 014, 014, 022, 041, /* X */ 0, 021, 012, 004, 004, 004, 004, /* Y */ 0, 077, 002, 004, 010, 020, 077, /* Z */ 034, 040, 040, 0140, 040, 040, 034, /* { */ 010, 010, 010, 0, 010, 010, 010, /* | */ 034, 2, 2, 3, 2, 2, 034, /* } */ 060, 0111, 06, 0, 0, 0, 0, /* ~ */ 0, 000, 000, 000, 000, 000, 000 /* DEL */ }; static void fatal(const char *fmt, ...) { va_list ap; va_start(ap, fmt); (void) fprintf(stderr, "offsetwriter: "); (void) vfprintf(stderr, fmt, ap); va_end(ap); if (fmt[strlen(fmt) - 1] != '\n') (void) fprintf(stderr, ": %s\n", strerror(errno)); exit(1); } void emit(int fd, char c) { int i, j, k; char *buf = alloca(BUFSIZE); hrtime_t t0, t1, delay; if (c < 0) return; (void) printf("'%c'\n", c); for (i = 0; i < NPOS; i++) { t0 = gethrtime(); memset(buf, c + i, BUFSIZE); for (j = 0; j < NLINES; j++) { if (!(ctbl[c][NLINES - 1 - j] & (1 << (7 - i)))) continue; if (lseek(fd, START + j * BLKSIZE, SEEK_SET) < 0) fatal("couldn't lseek to %d", j * BLKSIZE); for (k = 0; k < BLKSIZE; k += BUFSIZE) { if (write(fd, buf, BUFSIZE) == BUFSIZE) continue; fatal("couldn't write %d bytes", BUFSIZE); } } t1 = gethrtime(); delay = (1000000000 - (t1 - t0)) / 1000; printf("\t%d us\n", delay); usleep(delay > 0 ? delay : 0); } } int main(int argc, char **argv) { int i, j, fd; char *fname; if (argc < 2) fatal("need file to write, followed by message\n"); if ((fd = open(argv[1], O_CREAT | O_WRONLY | O_DSYNC | O_TRUNC)) < 0) fatal("couldn't open %s for writing", argv[1]); (void) printf("Injecting offset message.\n\n"); (void) printf("I/O delay time:\n"); for (i = 2; i < argc; i++) { for (j = 0; argv[i][j] != '\0'; j++) emit(fd, argv[i][j]); emit(fd, ' '); } return (0); }