void peer_connection::start_read_loop() { if( !_read_loop.valid() ) _read_loop = fc::async( [this](){ read_loop(); } ); }
static void *run_read_loop(void *unused) { struct sched_param param = { .sched_priority = 98 }; pthread_setschedparam(pthread_self(), SCHED_FIFO, ¶m); read_loop(&queue, &df, read_interval); return NULL; } const char *argp_program_version = "SlotRecorder Diagnostic Tool 0.0.1"; static const char doc[] = "Records WMP network card activity."; static const char args_doc[] = ""; static const struct argp_option options[] = { { "interval", 'i', "INTERVAL", 0, "Interval between reads in microseconds." }, { 0 } }; struct arguments { int interval; }; static error_t parse_opt(int key, char *arg, struct argp_state *state) { struct arguments *arguments = state->input; uint interval; switch (key) { case 'i': if (sscanf(arg, "%u", &interval) < 1) { argp_error(state, "Invalid value for argument 'interval'."); } arguments->interval = interval; break; default: return ARGP_ERR_UNKNOWN; } return 0; } static const struct argp argp = { options, parse_opt, args_doc, doc }; int main(int argc, char *argv[]) { /* Set signal handler for interrupt signal. */ memset(&sigact, 0, sizeof(sigact)); sigact.sa_sigaction = sigint_handler; sigact.sa_flags = SA_SIGINFO; sigaction(SIGINT, &sigact, NULL); /* Parse command line arguments. */ struct arguments arguments; memset(&arguments, 0, sizeof(arguments)); argp_parse(&argp, argc, argv, 0, 0, &arguments); read_interval = arguments.interval; queue_init(&queue, 1024); init_file(&df); pthread_t reader; pthread_create(&reader, NULL, run_read_loop, NULL); process_loop(&queue, &df); pthread_join(reader, NULL); queue_destroy(&queue); close_file(&df); return 0; }
// here all is done int main(int argc, char *argv[]) { char *ptr; int i; int nType = HW_PCI; __u32 dwPort = 0; __u16 wIrq = 0; __u16 wBTR0BTR1 = 0; int nExtended = CAN_INIT_TYPE_ST; const char *szDevNode = DEFAULT_NODE; bool bDevNodeGiven = false; bool bTypeGiven = false; char txt[VERSIONSTRING_LEN]; errno = 0; current_release = CURRENT_RELEASE; disclaimer("receivetest"); init(); // decode command line arguments for (i = 1; i < argc; i++) { char c; ptr = argv[i]; while (*ptr == '-') ptr++; c = *ptr; ptr++; if (*ptr == '=') ptr++; switch(tolower(c)) { case 'f': szDevNode = ptr; bDevNodeGiven = true; break; case 't': nType = getTypeOfInterface(ptr); if (!nType) { errno = EINVAL; printf("receivetest: unknown type of interface!\n"); goto error; } bTypeGiven = true; break; case 'p': dwPort = strtoul(ptr, NULL, 16); break; case 'i': wIrq = (__u16)strtoul(ptr, NULL, 10); break; case 'e': nExtended = CAN_INIT_TYPE_EX; break; case '?': case 'h': hlpMsg(); goto error; break; case 'b': wBTR0BTR1 = (__u16)strtoul(ptr, NULL, 16); break; default: errno = EINVAL; perror("receivetest: unknown command line argument!\n"); goto error; break; } } // simple command input check if (bDevNodeGiven && bTypeGiven) { errno = EINVAL; perror("receivetest: device node and type together is useless"); goto error; } // give some information back if (!bTypeGiven) { printf("receivetest: device node=\"%s\"\n", szDevNode); } else { printf("receivetest: type=%s", getNameOfInterface(nType)); if (nType == HW_USB) { if (dwPort) printf(", %d. device\n", dwPort); else printf(", standard device\n"); } else{ if (dwPort) { if (nType == HW_PCI) printf(", %d. PCI device", dwPort); else printf(", port=0x%08x", dwPort); } else printf(", port=default"); if ((wIrq) && !(nType == HW_PCI)) printf(" irq=0x%04x\n", wIrq); else printf(", irq=default\n"); } } if (nExtended == CAN_INIT_TYPE_EX) printf(" Extended frames are accepted"); else printf(" Only standard frames are accepted"); if (wBTR0BTR1) printf(", init with BTR0BTR1=0x%04x\n", wBTR0BTR1); else printf(", init with 500 kbit/sec.\n"); /* open CAN port */ if ((bDevNodeGiven) || (!bDevNodeGiven && !bTypeGiven)) { h = LINUX_CAN_Open(szDevNode, O_RDWR); if (!h) { printf("receivetest: can't open %s\n", szDevNode); goto error; } } else { // please use what is appropriate // HW_DONGLE_SJA // HW_DONGLE_SJA_EPP // HW_ISA_SJA // HW_PCI h = CAN_Open(nType, dwPort, wIrq); if (!h) { printf("receivetest: can't open %s device.\n", getNameOfInterface(nType)); goto error; } } /* clear status */ // CAN_Status(h); // get version info errno = CAN_VersionInfo(h, txt); if (!errno) printf("receivetest: driver version = %s\n", txt); else { perror("receivetest: CAN_VersionInfo()"); goto error; } // init to a user defined bit rate if (wBTR0BTR1) { errno = CAN_Init(h, wBTR0BTR1, nExtended); if (errno) { perror("receivetest: CAN_Init()"); goto error; } } errno = read_loop(); if (!errno) return 0; error: do_exit(errno); return errno; }
int main(int argc, char *argv[]) { int n; int begin, end; int port; nat_type type; time_t ttl; int ch; extern char *optarg; extern int optind; progname = argv[0]; begin = 0; end = 65535; ttl = 300; type = full_cone; port = 0; while ((ch = getopt(argc, argv, "p:b:e:t:n:v")) != -1){ switch (ch){ case 'p': port = atoi(optarg); break; case 'b': begin = atoi(optarg); break; case 'e': end = atoi(optarg); break; case 't': ttl = atoi(optarg); break; case 'n': n = atoi(optarg); if (n == 0) { type = full_cone; } else if (n == 1) { type = restricted_cone; } else if (n == 2) { type = port_restricted_cone; } break; case 'v': verbose = true; break; default: usage(); return -1; } } argc -= optind; argv += optind; if (port == 0) { std::cerr << "please use -p option for divert socket" << std::endl; usage(); return -1; } filter f(begin, end, type, ttl); int fd; fd = open_divert(port); if (fd < 0) { return -1; } read_loop(fd, f); return 0; }
/* main thread of execution */ int main(int argc, char* args[]) { int fd; char* index, *db, *stream; FILE* indexf; struct bitarray* bits; fprintf_blue(stdout, "gammaray Async Queuer -- " "By: Wolfgang Richter " "<*****@*****.**>\n"); redis_print_version(); if (argc < 4) { fprintf_light_red(stderr, "Usage: %s <index file> <stream file>" " <redis db num>\n", args[0]); return EXIT_FAILURE; } index = args[1]; stream = args[2]; db = args[3]; /* ----------------- hiredis ----------------- */ struct kv_store* handle = redis_init(db, true); if (handle == NULL) { fprintf_light_red(stderr, "Failed getting Redis context " "(connection failure?).\n"); return EXIT_FAILURE; } fprintf_cyan(stdout, "Loading MD filter from: %s\n\n", index); indexf = fopen(index, "r"); if (indexf == NULL) { fprintf_light_red(stderr, "Error opening index file to get MD " "filter.\n"); return EXIT_FAILURE; } if (qemu_load_md_filter(indexf, &bits)) { fprintf_light_red(stderr, "Error getting MD filter from BSON file.\n"); bits = bitarray_init(5242880); bitarray_set_all(bits); } if (bits == NULL) { fprintf_light_red(stderr, "Bitarray is NULL!\n"); return EXIT_FAILURE; } fclose(indexf); fprintf_cyan(stdout, "Attaching to stream: %s\n\n", stream); on_exit((void (*) (int, void *)) redis_shutdown, handle); if (strcmp(stream, "-") != 0) { fd = open(stream, O_RDONLY); } else { fd = STDIN_FILENO; } if (fd == -1) { fprintf_light_red(stderr, "Error opening stream file. " "Does it exist?\n"); return EXIT_FAILURE; } read_loop(fd, handle, bits); close(fd); return EXIT_SUCCESS; }
char *passwdqc_random(const passwdqc_params_qc_t *params) { char output[0x100], *retval; int bits; int word_count, trailing_separator, use_separators, toggle_case; int i; unsigned int max_length, length, extra; const char *start, *end; int fd; unsigned char bytes[3]; bits = params->random_bits; if (bits < BITS_MIN || bits > BITS_MAX) return NULL; /* * Calculate the number of words to use. The first word is always present * (hence the "1 +" and the "- WORD_BITS"). Each one of the following words, * if any, is prefixed by a separator character, so we use SWORD_BITS when * calculating how many additional words to use. We divide "bits - WORD_BITS" * by SWORD_BITS with rounding up (hence the addition of "SWORD_BITS - 1"). */ word_count = 1 + (bits + (SWORD_BITS - 1 - WORD_BITS)) / SWORD_BITS; /* * Special case: would we still encode enough bits if we omit the final word, * but keep the would-be-trailing separator? */ trailing_separator = (SWORD_BITS * (word_count - 1) >= bits); word_count -= trailing_separator; /* * To determine whether we need to use different separator characters or maybe * not, calculate the number of words we'd need to use if we don't use * different separators. We calculate it by dividing "bits" by WORD_BITS with * rounding up (hence the addition of "WORD_BITS - 1"). The resulting number * is either the same as or greater than word_count. Use different separators * only if their use, in the word_count calculation above, has helped reduce * word_count. */ use_separators = ((bits + (WORD_BITS - 1)) / WORD_BITS != word_count); trailing_separator &= use_separators; /* * Toggle case of the first character of each word only if we wouldn't achieve * sufficient entropy otherwise. */ toggle_case = (bits > ((WORD_BITS - 1) * word_count) + (use_separators ? (SEPARATOR_BITS * (word_count - !trailing_separator)) : 0)); /* * Calculate and check the maximum possible length of a "passphrase" we may * generate for a given word_count. We add 1 to WORDSET_4K_LENGTH_MAX to * account for separators (whether different or not). When there's no * trailing separator, we subtract 1. The check against sizeof(output) uses * ">=" to account for NUL termination. */ max_length = word_count * (WORDSET_4K_LENGTH_MAX + 1) - !trailing_separator; if (max_length >= sizeof(output) || (int)max_length > params->max) return NULL; if ((fd = open("/dev/urandom", O_RDONLY)) < 0) return NULL; retval = NULL; length = 0; do { if (read_loop(fd, bytes, sizeof(bytes)) != sizeof(bytes)) goto out; /* * Append a word. Treating bytes as little-endian, we use bits 0 to 11 for the * word index, and bit 13 for toggling the case of the first character. Bits * 12, 14, and 15 are left unused. Bits 16 to 23 are left for the separator. */ i = (((int)bytes[1] & 0x0f) << 8) | (int)bytes[0]; start = _passwdqc_wordset_4k[i]; end = memchr(start, '\0', WORDSET_4K_LENGTH_MAX); if (!end) end = start + WORDSET_4K_LENGTH_MAX; extra = end - start; /* The ">=" leaves room for either one more separator or NUL */ if (length + extra >= sizeof(output)) goto out; memcpy(&output[length], start, extra); if (toggle_case) { /* Toggle case if bit set (we assume ASCII) */ output[length] ^= bytes[1] & 0x20; bits--; } length += extra; bits -= WORD_BITS - 1; if (bits <= 0) break; /* * Append a separator character. We use bits 16 to 19. Bits 20 to 23 are left * unused. * * Special case: we may happen to leave a trailing separator if it provides * enough bits on its own. With WORD_BITS 13 and SEPARATOR_BITS 4, this * happens e.g. for bits values from 31 to 34, 48 to 51, 65 to 68. */ if (use_separators) { i = bytes[2] & 0x0f; output[length++] = SEPARATORS[i]; bits -= SEPARATOR_BITS; } else output[length++] = SEPARATORS[0]; } while (bits > 0); /* * Since we may have added a separator after the check in the loop above, we * must check again now. */ if (length < sizeof(output)) { output[length] = '\0'; retval = strdup(output); } out: memset(bytes, 0, sizeof(bytes)); memset(output, 0, length); close(fd); return retval; }
void start_read_loop() { _read_loop_done = _ntp_thread.async( [this](){ read_loop(); }, "ntp_read_loop" ); }
int main(int argc, char **argv) { int opt; int i2c_bus = DEFAULT_I2C_BUS; int sample_rate = DEFAULT_SAMPLE_RATE_HZ; mag_mode = -1; memset(calFile, 0, sizeof(calFile)); while ((opt = getopt(argc, argv, "b:s:y:amh")) != -1) { switch (opt) { case 'b': i2c_bus = strtoul(optarg, NULL, 0); if (errno == EINVAL) usage(argv[0]); if (i2c_bus < MIN_I2C_BUS || i2c_bus > MAX_I2C_BUS) usage(argv[0]); break; case 's': sample_rate = strtoul(optarg, NULL, 0); if (errno == EINVAL) usage(argv[0]); if (sample_rate < MIN_SAMPLE_RATE || sample_rate > MAX_SAMPLE_RATE) usage(argv[0]); break; case 'y': if (strlen(optarg) >= sizeof(calFile)) { printf("Choose a shorter path for the cal file\n"); usage(argv[0]); } strcpy(calFile, optarg); break; case 'a': if (mag_mode != -1) usage(argv[0]); mag_mode = 0; break; case 'm': if (mag_mode != -1) usage(argv[0]); mag_mode = 1; break; case 'h': default: usage(argv[0]); break; } } if (mag_mode == -1) usage(argv[0]); register_sig_handler(); if (mpu9150_init(i2c_bus, sample_rate, 0)) exit(1); read_loop(sample_rate); if (strlen(calFile) == 0) { if (mag_mode) strcpy(calFile, "magcal.txt"); else strcpy(calFile, "accelcal.txt"); } write_cal(); mpu9150_exit(); return 0; }
int html_attachment(const char *list, unsigned int y, unsigned int m, unsigned int d, unsigned int n, unsigned int a) { unsigned int aday; char *list_file; off_t idx_offset; int fd, error, got, trunc; idx_msgnum_t m1, m1r; struct idx_message idx_msg; idx_off_t offset; idx_size_t size; struct buffer src, dst; struct mime_ctx mime; char *body, *bend; if (y < MIN_YEAR || y > MAX_YEAR || m < 1 || m > 12 || d < 1 || d > 31 || n < 1 || n > 999999) return html_error("Invalid date or message number"); aday = YMD2ADAY(y - MIN_YEAR, m, d); list_file = concat(MAIL_SPOOL_PATH "/", list, NULL); if (!list_file) return html_error(NULL); fd = idx_open(list); if (fd < 0) { error = errno; free(list_file); return html_error(error == ENOENT ? "No such mailing list" : (error == ESRCH ? "Index needs rebuild" : NULL)); } error = !idx_read_aday_ok(fd, aday, &m1, sizeof(m1)); if (error || m1 < 1 || m1 >= MAX_MAILBOX_MESSAGES) { idx_close(fd); free(list_file); return html_error((error || m1 > 0) ? NULL : "No such message"); } m1r = m1 + n - 2; /* both m1 and n are 1-based; m1r is 0-based */ idx_offset = IDX2MSG(m1r); got = idx_read(fd, idx_offset, &idx_msg, sizeof(idx_msg)); if (got != sizeof(idx_msg)) error = 1; if (idx_close(fd) || error) { free(list_file); return html_error(got ? NULL : "No such message"); } if (y - MIN_YEAR != idx_msg.y || m != idx_msg.m || d != idx_msg.d) { free(list_file); return html_error("No such message"); } offset = idx_msg.offset; size = idx_msg.size; trunc = size > MAX_MESSAGE_SIZE; if (trunc) size = MAX_MESSAGE_SIZE; if (buffer_init(&src, size)) { free(list_file); return html_error(NULL); } fd = open(list_file, O_RDONLY); free(list_file); if (fd < 0) { buffer_free(&src); return html_error("mbox open error"); } error = lseek(fd, offset, SEEK_SET) != offset || read_loop(fd, src.start, size) != size; if (close(fd) || error || mime_init(&mime, &src)) { buffer_free(&src); return html_error("mbox read error"); } if (buffer_init(&dst, size)) { buffer_free(&src); mime_free(&mime); return html_error(NULL); } body = NULL; while (src.end - src.ptr > 9 && *src.ptr != '\n') { switch (*src.ptr) { case 'C': case 'c': mime_decode_header(&mime); continue; } mime_skip_header(&mime); } if (src.ptr >= src.end) { buffer_free(&src); buffer_free(&dst); mime_free(&mime); return html_error(NULL); } if (*src.ptr == '\n') body = ++src.ptr; const char *error_msg = "Attachment not found"; unsigned int attachment_count = 0; if (a) do { if (mime.entities->boundary) { body = mime_next_body_part(&mime); if (!body || body >= src.end) break; body = mime_next_body(&mime); } if (mime.entities->boundary || !is_attachment(&mime) || ++attachment_count != a) body = NULL; if (!body) { bend = mime_skip_body(&mime); if (!bend) break; continue; } int text = !strncasecmp(mime.entities->type, "text/", 5); if (text) { buffer_appends(&dst, "Content-Type: text/plain"); if (mime.entities->charset && enc_allowed_charset(mime.entities->charset)) buffer_appendf(&dst, "; charset=%s", mime.entities->charset); buffer_appendc(&dst, '\n'); } else { buffer_appends(&dst, "Content-Type: application/octet-stream\n"); } buffer_appendf(&dst, "Content-Disposition: %s; filename=\"", text ? "inline" : "attachment"); buffer_append_filename(&dst, mime.entities->filename, text); buffer_appends(&dst, "\"\n"); body = mime_decode_body(&mime, RECODE_NO, &bend); if (trunc && (!body || bend >= src.end)) { error_msg = "Attachment is truncated"; break; } buffer_appendf(&dst, "Content-Length: %llu\n\n", (unsigned long long)(mime.dst.ptr - body)); buffer_append(&dst, body, mime.dst.ptr - body); error_msg = NULL; break; } while (bend < src.end && mime.entities); buffer_free(&src); if (error_msg || mime.dst.error || dst.error) { mime_free(&mime); buffer_free(&dst); return html_error(error_msg); } mime_free(&mime); return html_send(&dst); }
int html_message(const char *list, unsigned int y, unsigned int m, unsigned int d, unsigned int n) { unsigned int aday, n0, n2; char *list_file; off_t idx_offset; int fd, error, got, trunc, prev, next; idx_msgnum_t m0, m1, m1r; struct idx_message idx_msg[3]; idx_off_t offset; idx_size_t size; struct buffer src, dst; struct mime_ctx mime; char *p, *q, *date, *from, *to, *cc, *subject, *body, *bend; if (y < MIN_YEAR || y > MAX_YEAR || m < 1 || m > 12 || d < 1 || d > 31 || n < 1 || n > 999999) return html_error("Invalid date or message number"); aday = YMD2ADAY(y - MIN_YEAR, m, d); list_file = concat(MAIL_SPOOL_PATH "/", list, NULL); if (!list_file) return html_error(NULL); fd = idx_open(list); if (fd < 0) { error = errno; free(list_file); return html_error(error == ENOENT ? "No such mailing list" : (error == ESRCH ? "Index needs rebuild" : NULL)); } error = !idx_read_aday_ok(fd, aday, &m1, sizeof(m1)); if (error || m1 < 1 || m1 >= MAX_MAILBOX_MESSAGES) { idx_close(fd); free(list_file); return html_error((error || m1 > 0) ? NULL : "No such message"); } m1r = m1 + n - (1 + 1); /* both m1 and n are 1-based; m1r is 0-based */ idx_offset = IDX2MSG(m1r); prev = next = 1; if (m1r >= 1) { idx_offset -= sizeof(idx_msg[0]); got = idx_read(fd, idx_offset, &idx_msg, sizeof(idx_msg)); if (got != sizeof(idx_msg)) { error = got != sizeof(idx_msg[0]) * 2; idx_msg[2] = idx_msg[1]; next = 0; } } else { prev = 0; got = idx_read(fd, idx_offset, &idx_msg[1], sizeof(idx_msg[1]) * 2); if (got != sizeof(idx_msg[1]) * 2) { error = got != sizeof(idx_msg[1]); idx_msg[2] = idx_msg[1]; next = 0; } idx_msg[0] = idx_msg[1]; } n0 = n - 1; if (!n0 && prev && !error) { aday = YMD2ADAY(idx_msg[0].y, idx_msg[0].m, idx_msg[0].d); error = !idx_read_aday_ok(fd, aday, &m0, sizeof(m0)); if (m1 > m0) n0 = m1 - m0; else error = 1; } if (idx_close(fd) || error) { free(list_file); return html_error(got ? NULL : "No such message"); } n2 = n + 1; if (idx_msg[2].y != idx_msg[1].y || idx_msg[2].m != m || idx_msg[2].d != d) n2 = 1; if (y - MIN_YEAR != idx_msg[1].y || m != idx_msg[1].m || d != idx_msg[1].d) { free(list_file); return html_error("No such message"); } offset = idx_msg[1].offset; size = idx_msg[1].size; trunc = size > MAX_MESSAGE_SIZE; if (trunc) size = MAX_MESSAGE_SIZE; if (buffer_init(&src, size)) { free(list_file); return html_error(NULL); } fd = open(list_file, O_RDONLY); free(list_file); if (fd < 0) { buffer_free(&src); return html_error("mbox open error"); } error = lseek(fd, offset, SEEK_SET) != offset || read_loop(fd, src.start, size) != size; if (close(fd) || error || mime_init(&mime, &src)) { buffer_free(&src); return html_error("mbox read error"); } if (buffer_init(&dst, size)) { buffer_free(&src); mime_free(&mime); return html_error(NULL); } date = from = to = cc = subject = body = NULL; while (src.end - src.ptr > 9 && *src.ptr != '\n') { switch (*src.ptr) { case 'D': case 'd': if (!strncasecmp(src.ptr, "Date:", 5)) { date = mime_decode_header(&mime); continue; } break; case 'F': case 'f': if (!strncasecmp(src.ptr, "From:", 5)) { from = mime_decode_header(&mime); continue; } break; case 'T': case 't': if (!strncasecmp(src.ptr, "To:", 3)) { to = mime_decode_header(&mime); continue; } break; case 'S': case 's': if (!strncasecmp(src.ptr, "Subject:", 8)) { subject = mime_decode_header(&mime); continue; } break; case 'C': case 'c': if (!strncasecmp(src.ptr, "CC:", 3)) cc = mime_decode_header(&mime); else mime_decode_header(&mime); continue; } mime_skip_header(&mime); } if (src.ptr >= src.end) { buffer_free(&src); buffer_free(&dst); mime_free(&mime); return html_error(NULL); } if (*src.ptr == '\n') body = ++src.ptr; if ((p = subject)) { while ((p = strchr(p, '['))) { if (strncasecmp(++p, list, strlen(list))) continue; q = p + strlen(list); if (*q != ']') continue; if (*++q == ' ') q++; memmove(--p, q, strlen(q) + 1); } } buffer_appends(&dst, "\n"); if (html_flags & HTML_HEADER) { buffer_appends(&dst, "<title>"); buffer_appends_html(&dst, list); if (subject && strlen(subject) > 9) { buffer_appends(&dst, " - "); buffer_appends_html(&dst, subject + 9); } buffer_appends(&dst, "</title>\n"); if (html_flags & HTML_CENSOR) buffer_appends(&dst, "<meta name=\"robots\" content=\"noindex\">\n"); } if (html_flags & HTML_BODY) { unsigned int attachment_count = 0; if (prev) { buffer_appends(&dst, "<a href=\""); if (n == 1) buffer_appendf(&dst, "../../../%u/%02u/%02u/", MIN_YEAR + idx_msg[0].y, idx_msg[0].m, idx_msg[0].d); buffer_appendf(&dst, "%u\">[<prev]</a> ", n0); } if (next) { buffer_appends(&dst, "<a href=\""); if (n2 == 1) buffer_appendf(&dst, "../../../%u/%02u/%02u/", MIN_YEAR + idx_msg[2].y, idx_msg[2].m, idx_msg[2].d); buffer_appendf(&dst, "%u\">[next>]</a> ", n2); } if (idx_msg[1].t.pn) { buffer_appends(&dst, "<a href=\""); if (idx_msg[1].t.py != idx_msg[1].y || idx_msg[1].t.pm != idx_msg[1].m || idx_msg[1].t.pd != idx_msg[1].d) buffer_appendf(&dst, "../../../%u/%02u/%02u/", MIN_YEAR + idx_msg[1].t.py, idx_msg[1].t.pm, idx_msg[1].t.pd); buffer_appendf(&dst, "%u\">[<thread-prev]</a> ", idx_msg[1].t.pn); } if (idx_msg[1].t.nn) { buffer_appends(&dst, "<a href=\""); if (idx_msg[1].t.ny != idx_msg[1].y || idx_msg[1].t.nm != idx_msg[1].m || idx_msg[1].t.nd != idx_msg[1].d) buffer_appendf(&dst, "../../../%u/%02u/%02u/", MIN_YEAR + idx_msg[1].t.ny, idx_msg[1].t.nm, idx_msg[1].t.nd); buffer_appendf(&dst, "%u\">[thread-next>]</a> ", idx_msg[1].t.nn); } buffer_appends(&dst, "<a href=\".\">[day]</a>" " <a href=\"..\">[month]</a>" " <a href=\"../..\">[year]</a>" " <a href=\"../../..\">[list]</a>\n"); buffer_appends(&dst, "<pre style=\"white-space: pre-wrap\">\n"); if (date) buffer_append_header(&dst, date); if (from) buffer_append_header(&dst, from); if (to) buffer_append_header(&dst, to); if (cc) buffer_append_header(&dst, cc); if (subject) buffer_append_header(&dst, subject); if (!(html_flags & HTML_CENSOR)) do { if (mime.entities->boundary) { body = mime_next_body_part(&mime); if (!body || body >= src.end) break; body = mime_next_body(&mime); } if (mime.entities->boundary) body = NULL; if (!body) { bend = mime_skip_body(&mime); if (!bend) break; continue; } /* mime_decode_body() will break mime vars, so, * remember them now */ char *filename = mime.entities->filename; char *type = mime.entities->type; const int isattachment = is_attachment(&mime); const int isinline = is_inline(&mime); int skip = 0; body = mime_decode_body(&mime, isattachment ? RECODE_NO : RECODE_YES, &bend); if (!body) break; if (bend >= src.end) skip = trunc; bend = src.ptr; if (!skip && isattachment) { int text = !strncasecmp(type, "text/", 5); attachment_count++; buffer_appendf(&dst, "\n<span style=\"font-family: times;\"><strong>" "%s attachment \"</strong><a href=\"%u/%u\"%s>", text ? "View" : "Download", n, attachment_count, text ? "" : " rel=\"nofollow\" download"); if (filename) buffer_appends_html(&dst, filename); buffer_appends(&dst, "</a><strong>\" of type \"</strong>"); buffer_appends_html(&dst, type); buffer_appends(&dst, "<strong>\""); if (body) buffer_appendf(&dst, " (%llu bytes)", (unsigned long long)(mime.dst.ptr - body)); buffer_appends(&dst, "</strong></span>\n"); continue; } else if (!isinline) { skip = 1; } else { skip = 0; /* do not skip non-attachments */ } if (skip) { buffer_appends(&dst, "\n<span style=\"font-family: times;\"><strong>" "Content of type \"</strong>"); buffer_appends_html(&dst, type); buffer_appends(&dst, "<strong>\" skipped</strong></span>\n"); continue; } /* inline */ buffer_appendc(&dst, '\n'); buffer_append_html_generic(&dst, body, mime.dst.ptr - body, 0, 1); mime.dst.ptr = body; } while (bend < src.end && mime.entities); if ((html_flags & HTML_CENSOR) || trunc) buffer_appendf(&dst, "\n<span style=\"font-family: times;\"><strong>" "Content %s</strong></span>\n", (html_flags & HTML_CENSOR) ? "removed" : "truncated"); buffer_appends(&dst, "</pre>\n"); } buffer_free(&src); if (mime.dst.error || dst.error) { mime_free(&mime); buffer_free(&dst); return html_error(NULL); } mime_free(&mime); return html_send(&dst); }