/* * Host name checking according to RFC 2595. */ static enum okay nss_check_host(const char *server, struct sock *sp) { CERTCertificate *cert; char *cn = NULL; enum okay ok = STOP; PRArenaPool *arena; CERTGeneralName *gn; SECItem altname; CERTAltNameEncodedContext ec; int i; const SEC_ASN1Template gntempl[] = { { SEC_ASN1_SEQUENCE_OF, 0, SEC_AnyTemplate } }; if ((cert = SSL_PeerCertificate(sp->s_prfd)) == NULL) { fprintf(stderr, "no certificate from \"%s\"\n", server); return STOP; } arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); if (CERT_FindCertExtension(cert, SEC_OID_X509_SUBJECT_ALT_NAME, &altname) == SECSuccess && SEC_ASN1DecodeItem(arena, &ec, gntempl, &altname) == SECSuccess && ec.encodedGenName != NULL) { for (i = 0; ec.encodedGenName[i] != NULL; i++) { gn = CERT_DecodeGeneralName(arena, ec.encodedGenName[i], NULL); if (gn->type == certDNSName) { char *dn = ac_alloc(gn->name.other.len + 1); memcpy(dn, gn->name.other.data, gn->name.other.len); dn[gn->name.other.len] = '\0'; if (verbose) fprintf(stderr, "Comparing DNS name: \"%s\"\n", dn); if (rfc2595_hostname_match(server, dn) == OKAY) { ac_free(dn); goto out; } ac_free(dn); } } } if ((cn = CERT_GetCommonName(&cert->subject)) != NULL) { if (verbose) fprintf(stderr, "Comparing common name: \"%s\"\n", cn); ok = rfc2595_hostname_match(server, cn); } if (ok == STOP) fprintf(stderr, "host certificate does not match \"%s\"\n", server); out: if (cn) PORT_Free(cn); PORT_FreeArena(arena, PR_FALSE); CERT_DestroyCertificate(cert); return ok; }
/* * Print out the indenting in threaded display. */ static int putindent(FILE *fp, struct message *mp, int maxwidth) { struct message *mq; int indent, i; int *us; char *cs; int important = MNEW|MFLAGGED; if (mp->m_level == 0) return 0; cs = ac_alloc(mp->m_level); us = ac_alloc(mp->m_level * sizeof *us); i = mp->m_level - 1; if (mp->m_younger && mp->m_younger->m_level == i + 1) { if (mp->m_parent && mp->m_parent->m_flag & important) us[i] = mp->m_flag & important ? 0x2523 : 0x2520; else us[i] = mp->m_flag & important ? 0x251D : 0x251C; cs[i] = '+'; } else { if (mp->m_parent && mp->m_parent->m_flag & important) us[i] = mp->m_flag & important ? 0x2517 : 0x2516; else us[i] = mp->m_flag & important ? 0x2515 : 0x2514; cs[i] = '\\'; } mq = mp->m_parent; for (i = mp->m_level - 2; i >= 0; i--) { if (mq) { if (i > mq->m_level - 1) { us[i] = cs[i] = ' '; continue; } if (mq->m_younger) { if (mq->m_parent && mq->m_parent->m_flag&important) us[i] = 0x2503; else us[i] = 0x2502; cs[i] = '|'; } else us[i] = cs[i] = ' '; mq = mq->m_parent; } else us[i] = cs[i] = ' '; } for (indent = 0; indent < mp->m_level && indent < maxwidth; indent++) { if (indent < maxwidth - 1) putuc(us[indent], cs[indent] & 0377, fp); else putuc(0x21B8, '^', fp); } ac_free(us); ac_free(cs); return indent; }
int main(void) { ac_bool error = AC_FALSE; // Must return AC_NULL although according to C99 standard a // malloc(0) may return either but undefined behavior happens // if the pointer is used. Therefore we'll defined it as always // returning AC_NULL error |= AC_TEST(ac_malloc(0) == AC_NULL); // Test conditions which attempt allocate too much memory error |= AC_TEST(ac_malloc(((ac_size_t)0) - 1) == AC_NULL); error |= AC_TEST(ac_malloc(((ac_size_t)0) - 2) == AC_NULL); error |= AC_TEST(ac_malloc(((ac_size_t)0) - 63) == AC_NULL); error |= AC_TEST(ac_malloc(((ac_size_t)0) - 64) == AC_NULL); error |= AC_TEST(ac_malloc(((ac_size_t)0) - 65) == AC_NULL); error |= AC_TEST(ac_malloc(((ac_size_t)0) - 66) == AC_NULL); // Test conditions which must succeed as we expect at // least being able to do a few small allocations void* p1 = ac_malloc(1); error |= AC_TEST(ac_malloc(1) != AC_NULL); ac_free(p1); void* p2 = ac_malloc(2); error |= AC_TEST(p2 != AC_NULL); ac_free(p2); void* p63 = ac_malloc(63); error |= AC_TEST(p63 != AC_NULL); ac_free(p63); void* p64 = ac_malloc(64); error |= AC_TEST(p64 != AC_NULL); ac_free(p64); void* p65 = ac_malloc(1); error |= AC_TEST(p65 != AC_NULL); ac_free(p65); if (!error) { // Succeeded ac_printf("OK\n"); } return error; }
static enum okay getcipher(const char *to, SECOidTag *alg, int *key) { char *vn, *cp; int vs; *key = 0; *alg = SEC_OID_DES_EDE3_CBC; vn = ac_alloc(vs = strlen(to) + 30); snprintf(vn, vs, "smime-cipher-%s", to); if ((cp = value(vn)) != NULL) { if (strcmp(cp, "rc2-40") == 0) { *alg = SEC_OID_RC2_CBC; *key = 40; } else if (strcmp(cp, "rc2-64") == 0) { *alg = SEC_OID_RC2_CBC; *key = 64; } else if (strcmp(cp, "rc2-128") == 0) { *alg = SEC_OID_RC2_CBC; *key = 128; } else if (strcmp(cp, "des") == 0) *alg = SEC_OID_DES_CBC; else if (strcmp(cp, "fortezza") == 0) *alg = SEC_OID_FORTEZZA_SKIPJACK; else if (strcmp(cp, "des-ede3") == 0) /*EMPTY*/; else { fprintf(stderr, "Invalid cipher \"%s\".\n", cp); return STOP; } } ac_free(vn); return OKAY; }
//__attribute__((noinline)) STATIC tcb_x86* thread_create(ac_size_t stack_size, ac_uptr flags, void*(*entry)(void*), void* entry_arg) { ac_uint sv_flags = disable_intr(); tcb_x86* ptcb = AC_NULL; ac_u8* pstack = AC_NULL; int error = 0; // Allocate a stack if (stack_size <= 0) { stack_size = AC_THREAD_STACK_MIN; } if (stack_size < AC_THREAD_STACK_MIN) { error = 1; goto done; } stack_size = (stack_size + 0xff) & ~0xff; pstack = ac_malloc(stack_size); if (pstack == AC_NULL) { ac_printf("thread_create: could not allocate stack\n"); error = 1; // TODO: add AC_STATUS_OOM goto done; } ac_debug_assert(((ac_uptr)pstack & 0xf) == 0); // Get the tcb and initialize the stack frame ptcb = get_tcb(entry, entry_arg); if (ptcb == AC_NULL) { ac_printf("thread_create: no tcb's available\n"); error = 1; // TODO: add AC_STATUS_TO_MANY_THREADS goto done; } ptcb->pstack = pstack; init_stack_frame(pstack, stack_size, flags, entry_trampoline, ptcb, &ptcb->sp, &ptcb->ss); // Add this after pready add_tcb_after(ptcb, pready); done: if (error != 0) { if (pstack != AC_NULL) { ac_free(pstack); } } #if AC_FALSE ac_printf("thread_create: pstack=0x%x stack_size=0x%x tos=0x%x rl=%d\n", pstack, stack_size, pstack + stack_size, get_ready_length()); ac_printf("thread_create:-ptcb=0x%x ready: ", ptcb); print_tcb_list(AC_NULL, pready); #endif restore_intr(sv_flags); return ptcb; }
/// free an entire AC table void ac_destroy(struct ac_table *in) { int i; for(i = 0; i < AHO_CORASICK_CHARACTERS ;i++) if ( in->zerostate->next[i] && in->zerostate->next[i]->id > 0 ){ ac_free(in->zerostate->next[i]); in->zerostate->next[i] = NULL; } free(in->zerostate); }
/// free an AC table from a given startnode (recursively) static void ac_free(struct ac_state *state) { int i; for(i = 0; i < AHO_CORASICK_CHARACTERS ;i++) if ( state->next[i] ) ac_free(state->next[i]); if (state->output) ac_pattern_delete(state->output); free(state); }
/** * @see ac_msg_pool.h */ void AcMsgPool_deinit(AcMsgPool* mp) { if (mp == AC_NULL) { return; } AcMpscRingBuff_deinit(&mp->rb); // We ASSUME none of the message are being used!!! ac_free(mp->msgs_raw); // BUG: We can't free next_ptrs because they could still be in use!!! // These can only be freed when all components have stopped. We will // need a "global" manager to free them //ac_free(mp->next_ptrs_raw); }
void nss_gen_err(const char *fmt, ...) { va_list ap; char *text; int len; va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); if ((len = PR_GetErrorTextLength()) > 0) { text = ac_alloc(len); if (PR_GetErrorText(text) > 0) fprintf(stderr, ": %s\n", text); ac_free(text); } else fprintf(stderr, ": %s.\n", nss_strerror(PR_GetError())); }
/** * Allocate count elements each at least size long and each aligned * on the alignment value. The value in pRaw is the unaligned pointer * and is passed to ac_free. The value in pAligned is the address of * the first element. * * @param count is the number of elements to create * @param size is the minimum size of each element created * @param alignment is a value to align on, such as AC_MAX_CACHE_LINE_LEN * @param pRaw is the address to return the raw pointer passed to ac_free * @param pAligned is the address to return the aligned pointer of the frist element * @param pElemSize is length of each element which will be a multipel of alignment */ AcStatus ac_calloc_align(AcU32 count, AcU32 size, AcU32 alignment, void** pRaw, void** pAligned, AcU32* pElemSize) { ac_debug_printf("ac_calloc_align:+count=%u size=%u alignment=%u\n" " pRaw=%p pAligned=%p pElemSize=%p\n", count, size, alignment, pRaw, pAligned, pElemSize); AcStatus status; void* raw = AC_NULL; void* aligned = AC_NULL; AcU32 elem_size = 0; AcUptr mask = 0; if ((count == 0) | (size == 0) | (AC_COUNT_ONE_BITS(alignment) != 1) | (pRaw == AC_NULL) | (pAligned == AC_NULL) | (pElemSize == AC_NULL)) { ac_debug_printf("ac_calloc_align: BAD_PARAM\n"); status = AC_STATUS_BAD_PARAM; goto done; } mask = ~((AcUptr)alignment - 1); elem_size = (size + alignment - 1) & mask; AcU64 allocation_size = (elem_size * count) + alignment - 1; raw = ac_calloc(1, allocation_size); if (raw == AC_NULL) { ac_debug_printf("ac_calloc_align: OUT_OF_MEMORY\n"); status = AC_STATUS_OUT_OF_MEMORY; goto done; } aligned = (void*)((((AcUptr)raw) + alignment - 1) & mask); status = AC_STATUS_OK; done: if (status != AC_STATUS_OK) { ac_free(raw); } else { *pRaw = raw; *pAligned = aligned; *pElemSize = elem_size; } ac_debug_printf("ac_calloc_align:-raw=%p aligned=%p elem_size=%u status=%u\n", raw, aligned, elem_size, status); return status; }
/** * Remove any zombie threads recoverying the stack * and the tcb. */ ac_uint remove_zombies(void) { tcb_x86* pzombie = AC_NULL; tcb_x86* pnext_tcb; ac_uint count = 0; ac_uptr flags = disable_intr(); // Loop through the list of ready tcbs removing // ZOMBIE entries. We'll start at idle_tcb as // the tail since its guaranteed to be on the // list and not a ZOMBIE. tcb_x86* phead = pidle_tcb->pnext_tcb; while (phead != pidle_tcb) { //ac_uptr flags = disable_intr(); ac_s32* pthread_id = &phead->thread_id; ac_s32 thread_id = __atomic_load_n(pthread_id, __ATOMIC_ACQUIRE); if (thread_id == AC_THREAD_ID_ZOMBIE) { // phead is a ZOMBIE, remove it from the // list advancing the head past it. pzombie = phead; pnext_tcb = remove_tcb_intr_disabled(pzombie); } else { pnext_tcb = phead->pnext_tcb; } // Advance head phead = pnext_tcb; //restore_intr(flags); if (pzombie != AC_NULL) { // Free the ZOMBIE's stack and mark it EMPTY if (pzombie->pstack != AC_NULL) { ac_free(pzombie->pstack); } __atomic_store_n(pthread_id, AC_THREAD_ID_EMPTY, __ATOMIC_RELEASE); count += 1; pzombie = AC_NULL; } } restore_intr(flags); return count; }
void seqenc_free(seqenc_t* E) { if (E == NULL) return; str_free(&E->tmpseq); ac_free(E->ac); cond_dist16_free(&E->cs); size_t i; for (i = 0; i < prefix_len; ++i) { cond_dist16_free(&E->cs0[i]); } free(E->d_nmask); uint32_enc_free(&E->d_contig_off); cond_dist4_free(&E->supercontig_motif); uint32_enc_free(&E->d_ext_flags); cond_dist128_free(&E->d_ext_seqname); size_t refsize = strmap_size(E->seq_index); for (i = 0; i < refsize; ++i) { cond_dist256_free(&E->d_ext_pos[i]); } free(E->d_ext_pos); cond_dist16_free(&E->d_ext_cigar_op); uint32_enc_free(&E->d_ext_cigar_n); for (i = 0; i < 9; ++i) { uint32_enc_free(&E->d_ext_cigar_len[i]); } uint32_enc_free(&E->d_ext_tlen); strmap_free(E->seq_index); free(E); }
/** * Starts AT handler on stream "fd'. * returns 0 on success, -1 on error. */ int at_open(int fd, ATUnsolHandler h) { int ret; pthread_attr_t attr; struct atcontext *ac = NULL; if (initializeAtContext()) { ALOGE("%s() InitializeAtContext failed!", __func__); goto error; } ac = getAtContext(); ac->fd = fd; ac->isInitialized = 1; ac->unsolHandler = h; ac->readerClosed = 0; ac->responsePrefix = NULL; ac->smsPDU = NULL; ac->response = NULL; pthread_attr_init (&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); ret = pthread_create(&ac->tid_reader, &attr, readerLoop, ac); if (ret < 0) { perror ("pthread_create"); goto error; } return 0; error: ac_free(); return -1; }
static CERTCertificate * get_signer_cert(char *addr) { CERTCertDBHandle *handle; CERTCertList *list; CERTCertListNode *node; CERTCertificate *cert = NULL; const char *cp; char *nick; char *vn; int vs, found = 0; addr = skin(addr); vn = ac_alloc(vs = strlen(addr) + 30); snprintf(vn, vs, "smime-sign-nickname-%s", addr); if ((nick = value(vn)) == NULL) nick = value("smime-sign-nickname"); ac_free(vn); handle = CERT_GetDefaultCertDB(); if (nick) { cert = CERT_FindCertByNickname(handle, nick); if (cert == NULL) fprintf(stderr, "No certificate \"%s\" found.\n", nick); return cert; } if ((list = CERT_FindUserCertsByUsage(handle, certUsageEmailSigner, PR_TRUE, PR_TRUE, NULL)) == NULL) { fprintf(stderr, "Cannot find any certificates for signing.\n"); return NULL; } for (node = CERT_LIST_HEAD(list); !CERT_LIST_END(node, list); node = CERT_LIST_NEXT(node)) { if ((cp = CERT_GetCertEmailAddress(&node->cert->subject)) != NULL && asccasecmp(cp, addr) == 0) { cert = node->cert; found++; } } if (cert == NULL) { for (node = CERT_LIST_HEAD(list); !CERT_LIST_END(node, list) && cert == NULL; node = CERT_LIST_NEXT(node)) { cp = CERT_GetFirstEmailAddress(node->cert); while (cp) { if (asccasecmp(cp, addr) == 0) { cert = node->cert; found++; } cp = CERT_GetNextEmailAddress(node->cert, cp); } } } if (found > 1) { fprintf(stderr, "More than one signing certificate found for <%s>.\n" "Use the smime-sign-nickname variable.\n", addr); return NULL; } if (cert == NULL) fprintf(stderr, "Cannot find a signing certificate for <%s>.\n", addr); return cert; }
FILE * smime_encrypt(FILE *ip, const char *ignored, const char *to) { NSSCMSMessage *msg; NSSCMSContentInfo *content; NSSCMSEnvelopedData *data; NSSCMSRecipientInfo *info; CERTCertificate *cert[2]; CERTCertDBHandle *handle; SECOidTag tag; FILE *hp, *pp, *yp; int keysize; char *nickname, *vn; int vs; if (nss_init() != OKAY) return NULL; handle = CERT_GetDefaultCertDB(); vn = ac_alloc(vs = strlen(to) + 30); snprintf(vn, vs, "smime-nickname-%s", to); nickname = value(vn); ac_free(vn); if ((cert[0] = CERT_FindCertByNicknameOrEmailAddr(handle, nickname ? nickname : (char *)to)) == NULL) { if (nickname) fprintf(stderr, "Cannot find certificate \"%s\".\n", nickname); else fprintf(stderr, "Cannot find certificate for <%s>.\n", to); return NULL; } cert[1] = NULL; if (getcipher(to, &tag, &keysize) != OKAY) return NULL; if ((msg = NSS_CMSMessage_Create(NULL)) == NULL) { fprintf(stderr, "Cannot create CMS message.\n"); return NULL; } if ((data = NSS_CMSEnvelopedData_Create(msg, tag, keysize)) == NULL) { fprintf(stderr, "Cannot create enveloped data.\n"); return NULL; } content = NSS_CMSMessage_GetContentInfo(msg); if (NSS_CMSContentInfo_SetContent_EnvelopedData(msg, content, data) != SECSuccess) { fprintf(stderr, "Cannot attach enveloped data.\n"); return NULL; } content = NSS_CMSEnvelopedData_GetContentInfo(data); if (NSS_CMSContentInfo_SetContent_Data(msg, content, NULL, PR_FALSE) != SECSuccess) { fprintf(stderr, "Cannot attach CMS data.\n"); return NULL; } if ((info = NSS_CMSRecipientInfo_Create(msg, cert[0])) == NULL) { fprintf(stderr, "Cannot create CMS recipient information.\n"); return NULL; } if (NSS_CMSEnvelopedData_AddRecipient(data, info) != SECSuccess) { fprintf(stderr, "Cannot add CMS recipient information.\n"); return NULL; } CERT_DestroyCertificate(cert[0]); if ((yp = encode(ip, &hp, &pp, msg, base64_cb)) == NULL) return NULL; NSS_CMSMessage_Destroy(msg); return smime_encrypt_assemble(hp, yp); }
/** * @see ac_msg_pool.h */ AcStatus AcMsgPool_init(AcMsgPool* mp, AcU32 msg_count, AcU32 len_extra) { ac_debug_printf("AcMsgPool_init:+mp=%p msg_count=%u len_extra=%u\n", mp, msg_count, len_extra); AcStatus status; if (mp == AC_NULL) { status = AC_STATUS_BAD_PARAM; goto done; } mp->msgs_raw = AC_NULL; mp->next_ptrs_raw = AC_NULL; mp->msgs = AC_NULL; mp->len_extra = len_extra; // Allocate and align the messages AcU32 size_entry; status = ac_calloc_align(msg_count, sizeof(AcMsg) + len_extra, sizeof(AcU64), &mp->msgs_raw, (void**)&mp->msgs, &size_entry); ac_debug_printf("AcMsgPool_init: mp=%p msgs_raw=%p msgs=%p size_entry=%u status=%u\n", mp, mp->msgs_raw, mp->msgs, size_entry, status); if (status != AC_STATUS_OK) { goto done; } // Allocate and align the AcNextPtrs // BUG These AcNextPtrs need to be managed globally. AcU32 size_next_entry; status = ac_calloc_align(msg_count, sizeof(AcNextPtr), AC_MAX_CACHE_LINE_LEN, &mp->next_ptrs_raw, (void**)&mp->next_ptrs, &size_next_entry); ac_debug_printf("AcMsgPool_init: mp=%p next_ptrs_raw=%p next_ptrs=%p size_next_entry=%u status=%u\n", mp, mp->next_ptrs_raw, mp->msgs, size_next_entry, status); if (status != AC_STATUS_OK) { goto done; } // Init the ring buffer status = AcMpscRingBuff_init(&mp->rb, msg_count); if (status != AC_STATUS_OK) { goto done; } // Add messages void* base = mp->msgs; void* base_np = mp->next_ptrs; for (AcU32 i = 0; i < msg_count; i++) { AcMsg* msg = (AcMsg*)base; AcNextPtr* np = (AcNextPtr*)base_np; // Init next_ptr fields np->next = AC_NULL; np->msg = AC_NULL; // Init msg fields msg->mp = mp; msg->next_ptr = np; // Add msg to ring buffer if (!AcMpscRingBuff_add_mem(&mp->rb, msg)) { ac_fail("AcMsgPool_init: WTF should always be able to add msg"); status = AC_STATUS_ERR; goto done; } // Advance to next entries base += size_entry; base_np += size_next_entry; } done: if (status != AC_STATUS_OK && mp != AC_NULL) { ac_free(mp->msgs_raw); ac_free(mp->next_ptrs_raw); } ac_debug_printf("AcMsgPool_init:-mp=%p msg_count=%u len_extra=%u status=%d\n", mp, msg_count, len_extra, status); return status; }
static bool test_inherit(struct ConfigSet *cs, struct Buffer *err) { log_line(__func__); bool result = false; const char *account = "fruit"; const char *parent = "Quince"; char child[128]; snprintf(child, sizeof(child), "%s:%s", account, parent); const char *AccountVarAddr[] = { parent, NULL, }; struct CfgAccount *ac = ac_new(cs, account, AccountVarAddr); // set parent mutt_buffer_reset(err); int rc = cs_str_string_set(cs, parent, "*****@*****.**", err); if (!TEST_CHECK(CSR_RESULT(rc) == CSR_SUCCESS)) { TEST_MSG("Error: %s\n", err->data); goto ti_out; } dump_native(cs, parent, child); // set child mutt_buffer_reset(err); rc = cs_str_string_set(cs, child, "*****@*****.**", err); if (!TEST_CHECK(CSR_RESULT(rc) == CSR_SUCCESS)) { TEST_MSG("Error: %s\n", err->data); goto ti_out; } dump_native(cs, parent, child); // reset child mutt_buffer_reset(err); rc = cs_str_reset(cs, child, err); if (!TEST_CHECK(CSR_RESULT(rc) == CSR_SUCCESS)) { TEST_MSG("Error: %s\n", err->data); goto ti_out; } dump_native(cs, parent, child); // reset parent mutt_buffer_reset(err); rc = cs_str_reset(cs, parent, err); if (!TEST_CHECK(CSR_RESULT(rc) == CSR_SUCCESS)) { TEST_MSG("Error: %s\n", err->data); goto ti_out; } dump_native(cs, parent, child); log_line(__func__); result = true; ti_out: ac_free(cs, &ac); return result; }
static void hprf(const char *fmt, int mesg, FILE *f, int threaded, const char *attrlist) { struct message *mp = &message[mesg-1]; char *headline = NULL, *subjline, *name, *cp, *pbuf = NULL; struct headline hl; size_t headsize = 0; const char *fp; int B, c, i, n, s; int headlen = 0; struct str in, out; int subjlen = scrnwidth, fromlen, isto = 0, isaddr = 0; FILE *ibuf; if ((mp->m_flag & MNOFROM) == 0) { if ((ibuf = setinput(&mb, mp, NEED_HEADER)) == NULL) return; if ((headlen = readline(ibuf, &headline, &headsize)) < 0) return; } if ((subjline = hfield("subject", mp)) == NULL) subjline = hfield("subj", mp); if (subjline == NULL) { out.s = NULL; out.l = 0; } else { in.s = subjline; in.l = strlen(subjline); mime_fromhdr(&in, &out, TD_ICONV | TD_ISPR); subjline = out.s; } if ((mp->m_flag & MNOFROM) == 0) { pbuf = ac_alloc(headlen + 1); parse(headline, headlen, &hl, pbuf); } else { hl.l_from = /*fakefrom(mp);*/NULL; hl.l_tty = NULL; hl.l_date = fakedate(mp->m_time); } if (value("datefield") && (cp = hfield("date", mp)) != NULL) hl.l_date = fakedate(rfctime(cp)); if (Iflag) { if ((name = hfield("newsgroups", mp)) == NULL) if ((name = hfield("article-id", mp)) == NULL) name = "<>"; name = prstr(name); } else if (value("show-rcpt") == NULL) { name = name1(mp, 0); isaddr = 1; if (value("showto") && name && is_myname(skin(name))) { if ((cp = hfield("to", mp)) != NULL) { name = cp; isto = 1; } } } else { isaddr = 1; if ((name = hfield("to", mp)) != NULL) isto = 1; } if (name == NULL) { name = ""; isaddr = 0; } if (isaddr) { if (value("showname")) name = realname(name); else { name = prstr(skin(name)); } } for (fp = fmt; *fp; fp++) { if (*fp == '%') { if (*++fp == '-') { fp++; } else if (*fp == '+') fp++; while (digitchar(*fp&0377)) fp++; if (*fp == '\0') break; } else { #if defined (HAVE_MBTOWC) && defined (HAVE_WCWIDTH) if (mb_cur_max > 1) { wchar_t wc; if ((s = mbtowc(&wc, fp, mb_cur_max)) < 0) n = s = 1; else { if ((n = wcwidth(wc)) < 0) n = 1; } } else #endif /* HAVE_MBTOWC && HAVE_WCWIDTH */ { n = s = 1; } subjlen -= n; while (--s > 0) fp++; } } for (fp = fmt; *fp; fp++) { if (*fp == '%') { B = 0; n = 0; s = 1; if (*++fp == '-') { s = -1; fp++; } else if (*fp == '+') fp++; if (digitchar(*fp&0377)) { do n = 10*n + *fp - '0'; while (fp++, digitchar(*fp&0377)); } if (*fp == '\0') break; n *= s; switch (*fp) { case '%': putc('%', f); subjlen--; break; case '>': case '<': c = dot == mp ? *fp&0377 : ' '; putc(c, f); subjlen--; break; case 'a': c = dispc(mp, attrlist); putc(c, f); subjlen--; break; case 'm': if (n == 0) { n = 3; if (threaded) for (i=msgCount; i>999; i/=10) n++; } subjlen -= fprintf(f, "%*d", n, mesg); break; case 'f': if (n <= 0) n = 18; fromlen = n; if (isto) fromlen -= 3; fprintf(f, "%s%s", isto ? "To " : "", colalign(name, fromlen, 1)); subjlen -= n; break; case 'd': if (n <= 0) n = 16; subjlen -= fprintf(f, "%*.*s", n, n, hl.l_date); break; case 'l': if (n == 0) n = 4; if (mp->m_xlines) subjlen -= fprintf(f, "%*ld", n, mp->m_xlines); else { subjlen -= n; while (n--) putc(' ', f); } break; case 'o': if (n == 0) n = -5; subjlen -= fprintf(f, "%*lu", n, (long)mp->m_xsize); break; case 'i': if (threaded) subjlen -= putindent(f, mp, scrnwidth - 60); break; case 'S': B = 1; /*FALLTHRU*/ case 's': n = n>0 ? n : subjlen - 2; if (B) n -= 2; if (subjline != NULL && n >= 0) { /* pretty pathetic */ fprintf(f, B ? "\"%s\"" : "%s", colalign(subjline, n, 0)); } break; case 'U': if (n == 0) n = 9; subjlen -= fprintf(f, "%*lu", n, mp->m_uid); break; case 'e': if (n == 0) n = 2; subjlen -= fprintf(f, "%*u", n, threaded == 1 ? mp->m_level : 0); break; case 't': if (n == 0) { n = 3; if (threaded) for (i=msgCount; i>999; i/=10) n++; } fprintf(f, "%*ld", n, threaded ? mp->m_threadpos : mesg); subjlen -= n; break; case 'c': if (n == 0) n = 6; subjlen -= fprintf(f, "%*g", n, mp->m_score); break; } } else putc(*fp&0377, f); } putc('\n', f); if (out.s) free(out.s); if (headline) free(headline); if (pbuf) ac_free(pbuf); }