std::auto_ptr<FastaSequence> FastaReader::next() { bool readingHeader = 1; std::auto_ptr<FastaSequence> fs(new FastaSequence()); while(true) { // check that last read line is valid if (line_.size() > 1 && line_[0] != ' ') { if (!readingHeader && is_header(line_)) return fs; if (readingHeader && is_header(line_)) { fs->name_ += line_.substr(1); } else { fs->sequence_ += line_; readingHeader = 0; } } // can't read further if (!getline(file_, line_)) break; } // if we read something, return it // otherwise return NULL if (fs->sequence().size() > 0) return fs; return std::auto_ptr<FastaSequence>(NULL); }
AmqpProcessor::Result AmqpProcessor::process_frame(const amqp_frame_t& frame) { Result result; if(is_deliver(frame)) { listener_->process_event(Deliver()); result = delivery_decoded(frame); } else if(is_header(frame)) { listener_->process_event(Header(body_size(frame))); result = properties(frame); } else if(is_body(frame)) { amqp_bytes_t fragment = get_body_fragment(frame); listener_->process_event(Body(fragment.len)); AmqpListener::Delivery& delivery = listener_->get_state<AmqpListener::Delivery&>(); bool last = delivery.is_flag_active<Delivered>(); result = std::make_pair(fragment, last); } else { std::cout << "unprocessed frame: " << frame.frame_type << std::endl; } return result; }
static void do_copy (FILE * out, const char *basedir, const char *file) { /* copy a source file suppressing the boiler-plate and headers */ char input[1024]; char row[256]; char *p = row; int c; int boiler_plate = 0; int boiler_plate_found = 0; FILE *in; strcpy (input, PREFIX); strcat (input, basedir); strcat (input, file); in = fopen (input, "r"); if (!in) { fprintf (stderr, "Error opening %s\n", input); return; } do_note (out, file, 0); while ((c = getc (in)) != EOF) { *p++ = c; if (c == '\n') { *p = '\0'; p = row; if (!boiler_plate_found && strlen (row) >= 2 && strncmp (row, "/*", 2) == 0) { boiler_plate_found = 1; boiler_plate = 1; continue; } if (boiler_plate) { if (strlen (row) >= 2 && strncmp (row, "*/", 2) == 0) boiler_plate = 0; continue; } if (is_header (row)) { const char *auto_path = check_autogenerated_path (row); row[strlen (row) - 1] = '\0'; fprintf (out, "/* %s */\n", row); if (auto_path != NULL) do_copy_plain (out, auto_path); continue; } fprintf (out, "%s", row); } } fclose (in); do_note (out, file, 1); }
//! <b>Requires</b>: node is a tree node but not the header. //! //! <b>Effects</b>: Unlinks the node and rebalances the tree. //! //! <b>Complexity</b>: Average complexity is constant time. //! //! <b>Throws</b>: Nothing. static void unlink(node_ptr node) { node_ptr x = NodeTraits::get_parent(node); if(x){ while(!is_header(x)) x = NodeTraits::get_parent(x); tree_algorithms::erase(x, node); } }
void po_message_check_all (po_message_t message, po_message_iterator_t iterator, po_xerror_handler_t handler) { message_ty *mp = (message_ty *) message; /* Establish error handler. */ po_xerror = (void (*) (int, const message_ty *, const char *, size_t, size_t, int, const char *)) handler->xerror; po_xerror2 = (void (*) (int, const message_ty *, const char *, size_t, size_t, int, const char *, const message_ty *, const char *, size_t, size_t, int, const char *)) handler->xerror2; /* For plural checking, combine the message and its header into a small, two-element message list. */ { message_ty *header; /* Find the header. */ { message_list_ty *mlp; size_t j; header = NULL; mlp = msgdomain_list_sublist (iterator->file->mdlp, iterator->domain, false); if (mlp != NULL) for (j = 0; j < mlp->nitems; j++) if (is_header (mlp->item[j]) && !mlp->item[j]->obsolete) { header = mlp->item[j]; break; } } { message_ty *items[2]; struct message_list_ty ml; ml.item = items; ml.nitems = 0; ml.nitems_max = 2; ml.use_hashtable = false; if (header != NULL) message_list_append (&ml, header); if (mp != header) message_list_append (&ml, mp); check_message_list (&ml, 1, 1, 1, 0, 0, 0); } } /* Restore error handler. */ po_xerror = textmode_xerror; po_xerror2 = textmode_xerror2; }
/* * print_tagged_memory will print contents of given memory area and * display it as if it was tagged Erlang terms (which it hopefully * is). This function knows about forwarding pointers to be able to * print a heap during garbage collection. erts_printf("%T",val) * do not know about forwarding pointers though, so it will still * crash if they are encoutered... */ void print_tagged_memory(Eterm *pos, Eterm *end) { erts_printf("+-%s-+-%s-+\n",dashes,dashes); erts_printf("| 0x%0*lx - 0x%0*lx |\n", PTR_SIZE,(unsigned long)pos, PTR_SIZE,(unsigned long)(end - 1)); erts_printf("| %-*s | %-*s |\n",PTR_SIZE,"Address",PTR_SIZE,"Contents"); erts_printf("|-%s-|-%s-|\n",dashes,dashes); while( pos < end ) { Eterm val = pos[0]; erts_printf("| 0x%0*lx | 0x%0*lx | ", PTR_SIZE,(unsigned long)pos, PTR_SIZE,(unsigned long)val); ++pos; if( is_arity_value(val) ) { erts_printf("Arity(%lu)", arityval(val)); } else if( is_thing(val) ) { unsigned int ari = thing_arityval(val); erts_printf("Thing Arity(%u) Tag(%lu)", ari, thing_subtag(val)); while( ari ) { erts_printf("\n| 0x%0*lx | 0x%0*lx | THING", PTR_SIZE, (unsigned long)pos, PTR_SIZE, (unsigned long)*pos); ++pos; --ari; } } else { switch (primary_tag(val)) { case TAG_PRIMARY_BOXED: if (!is_header(*boxed_val(val))) { erts_printf("Moved -> 0x%0*lx\n",PTR_SIZE, (unsigned long)*boxed_val(val)); continue; } break; case TAG_PRIMARY_LIST: if (is_non_value(*list_val(val))) { erts_printf("Moved -> 0x%0*lx\n",PTR_SIZE, (unsigned long)*(list_val(val) + 1)); continue; } break; } erts_printf("%.30T", val); } erts_printf("\n"); } erts_printf("+-%s-+-%s-+\n",dashes,dashes); }
bool scm_read_header(scm *s, header *h) { assert(s); assert(h); if (scm_read(s, h, sizeof (header), 0)) { if (is_header(h)) { return true; } else apperr("%s is not an SCM TIFF", s->name); } return false; }
static void move_one_frag(Eterm** hpp, Eterm* src, Uint src_sz, ErlOffHeap* off_heap) { union { Uint *up; ProcBin *pbp; ErlFunThing *efp; ExternalThing *etp; } ohe; Eterm* ptr = src; Eterm* end = ptr + src_sz; Eterm dummy_ref; Eterm* hp = *hpp; while (ptr != end) { Eterm val; ASSERT(ptr < end); val = *ptr; ASSERT(val != ERTS_HOLE_MARKER); if (is_header(val)) { ASSERT(ptr + header_arity(val) < end); ohe.up = hp; MOVE_BOXED(ptr, val, hp, &dummy_ref); switch (val & _HEADER_SUBTAG_MASK) { case REFC_BINARY_SUBTAG: ohe.pbp->next = off_heap->mso; off_heap->mso = ohe.pbp; break; case FUN_SUBTAG: ohe.efp->next = off_heap->funs; off_heap->funs = ohe.efp; break; case EXTERNAL_PID_SUBTAG: case EXTERNAL_PORT_SUBTAG: case EXTERNAL_REF_SUBTAG: ohe.etp->next = off_heap->externals; off_heap->externals = ohe.etp; break; } } else { /* must be a cons cell */ ASSERT(ptr+1 < end); MOVE_CONS(ptr, val, hp, &dummy_ref); ptr += 2; } } *hpp = hp; }
DELIVERED_HDR_INFO *delivered_hdr_init(VSTREAM *fp, off_t offset, int flags) { char *cp; DELIVERED_HDR_INFO *info; const HEADER_OPTS *hdr; /* * Sanity check. */ info = (DELIVERED_HDR_INFO *) mymalloc(sizeof(*info)); info->flags = flags; info->buf = vstring_alloc(10); info->table = htable_create(0); if (vstream_fseek(fp, offset, SEEK_SET) < 0) msg_fatal("seek queue file %s: %m", VSTREAM_PATH(fp)); /* * XXX Assume that mail_copy() produces delivered-to headers that fit in * a REC_TYPE_NORM record. Lowercase the delivered-to addresses for * consistency. * * XXX Don't get bogged down by gazillions of delivered-to headers. */ #define DELIVERED_HDR_LIMIT 1000 while (rec_get(fp, info->buf, 0) == REC_TYPE_NORM && info->table->used < DELIVERED_HDR_LIMIT) { if (is_header(STR(info->buf))) { if ((hdr = header_opts_find(STR(info->buf))) != 0 && hdr->type == HDR_DELIVERED_TO) { cp = STR(info->buf) + strlen(hdr->name) + 1; while (ISSPACE(*cp)) cp++; if (info->flags & FOLD_ADDR_ALL) fold_addr(cp, info->flags); if (msg_verbose) msg_info("delivered_hdr_init: %s", cp); htable_enter(info->table, cp, (char *) 0); } } else if (ISSPACE(STR(info->buf)[0])) { continue; } else { break; } } return (info); }
gboolean gtk_source_completion_model_iter_is_header (GtkSourceCompletionModel *model, GtkTreeIter *iter) { GList *proposal_node; ProposalInfo *proposal_info; g_return_val_if_fail (GTK_SOURCE_IS_COMPLETION_MODEL (model), FALSE); g_return_val_if_fail (iter != NULL, FALSE); g_return_val_if_fail (iter->user_data != NULL, FALSE); proposal_node = iter->user_data; proposal_info = proposal_node->data; return is_header (proposal_info); }
static void bounce_template_parse_buffer(BOUNCE_TEMPLATE *tp) { char *tval = tp->buffer; char *cp; char **cpp; int cpp_len; int cpp_used; int hlen; char *hval; /* * Sanity check. */ if ((tp->flags & BOUNCE_TMPL_FLAG_NEW_BUFFER) == 0) msg_panic("bounce_template_parse_buffer: nothing to do here"); tp->flags &= ~BOUNCE_TMPL_FLAG_NEW_BUFFER; /* * Discard the unusable template and use the default one instead. */ #define CLEANUP_AND_RETURN() do { \ bounce_template_reset(tp); \ return; \ } while (0) /* * Parse pseudo-header labels and values. */ #define GETLINE(line, buf) \ (((line) = (buf)) != 0 ? ((buf) = split_at((buf), '\n'), (line)) : 0) while ((GETLINE(cp, tval)) != 0 && (hlen = is_header(cp)) > 0) { for (hval = cp + hlen; *hval && (*hval == ':' || ISSPACE(*hval)); hval++) *hval = 0; if (*hval == 0) { msg_warn("%s: empty \"%s\" header value in %s template " "-- ignoring this template", tp->origin, cp, tp->class); CLEANUP_AND_RETURN(); } if (!allascii(hval)) { msg_warn("%s: non-ASCII \"%s\" header value in %s template " "-- ignoring this template", tp->origin, cp, tp->class); CLEANUP_AND_RETURN(); }
//! <b>Requires</b>: 'node' is a node from the tree except the leftmost node. //! //! <b>Effects</b>: Returns the previous node of the tree. //! //! <b>Complexity</b>: Average constant time. //! //! <b>Throws</b>: Nothing. static node_ptr prev_node(const node_ptr & node) { if(is_header(node)){ //return NodeTraits::get_right(node); return maximum(NodeTraits::get_parent(node)); } else if(NodeTraits::get_left(node)){ return maximum(NodeTraits::get_left(node)); } else { node_ptr p(node); node_ptr x = NodeTraits::get_parent(p); while(p == NodeTraits::get_left(x)){ p = x; x = NodeTraits::get_parent(x); } return x; } }
/* Remove the header, and emit the "row-deleted" signal. */ static void hide_header (GtkSourceCompletionModel *model, GList *provider_node) { ProviderInfo *provider_info = provider_node->data; ProposalInfo *proposal_info = g_queue_pop_head (provider_info->proposals); g_assert (provider_info->proposals->length > 0); g_assert (is_header (proposal_info)); proposal_info_free (proposal_info); if (provider_info->visible) { GtkTreePath *path = get_proposal_path (model, provider_info->proposals->head); gtk_tree_model_row_deleted (GTK_TREE_MODEL (model), path); gtk_tree_path_free (path); } }
const char * po_file_domain_header (po_file_t file, const char *domain) { message_list_ty *mlp; size_t j; if (domain == NULL) domain = MESSAGE_DOMAIN_DEFAULT; mlp = msgdomain_list_sublist (file->mdlp, domain, false); if (mlp != NULL) for (j = 0; j < mlp->nitems; j++) if (is_header (mlp->item[j]) && !mlp->item[j]->obsolete) { const char *header = mlp->item[j]->msgstr; if (header != NULL) return xstrdup (header); else return NULL; } return NULL; }
static void move_one_frag(Eterm** hpp, Eterm* src, Uint src_sz, ErlOffHeap* off_heap) { Eterm* ptr = src; Eterm* end = ptr + src_sz; Eterm dummy_ref; Eterm* hp = *hpp; while (ptr != end) { Eterm val; ASSERT(ptr < end); val = *ptr; ASSERT(val != ERTS_HOLE_MARKER); if (is_header(val)) { struct erl_off_heap_header* hdr = (struct erl_off_heap_header*)hp; ASSERT(ptr + header_arity(val) < end); MOVE_BOXED(ptr, val, hp, &dummy_ref); switch (val & _HEADER_SUBTAG_MASK) { case REFC_BINARY_SUBTAG: case FUN_SUBTAG: case EXTERNAL_PID_SUBTAG: case EXTERNAL_PORT_SUBTAG: case EXTERNAL_REF_SUBTAG: hdr->next = off_heap->first; off_heap->first = hdr; break; } } else { /* must be a cons cell */ ASSERT(ptr+1 < end); MOVE_CONS(ptr, val, hp, &dummy_ref); ptr += 2; } } *hpp = hp; }
static uint32_t _initrd_read(struct fs_node *node, uint32_t offset, uint32_t size, uint8_t *buffer) { struct initrd_file_header header = file_headers[node->inode]; uint32_t read_length = size; assert(is_header(&header)); if (offset > header.size) { /* Invalid read (out of bounds) */ initrd_debug("initrd: invalid offset of %h in node size %h\n", offset, size); return 0; } if (offset + size > header.size) { /* Reduce read size as necessary to prevent overshoot. */ read_length = header.size - offset; } memcpy(buffer, (uint8_t *)(header.offset + offset), read_length); return read_length; }
uint64_t alm_dump_heap_item(ATERM t, int stack) { if (is_num(t)) printf("%18.1lf ", num_val(t)); else if (is_nil(t)) printf(" [] "); else if (is_cons(t)) { printf("<cons/0x%.3llX> ", (uint64_t)cons_ptr(t)); } else if (is_boxed(t)) { ATERM *box = boxed_ptr(t); if (is_atom(*box)) printf("<atom/0x%.3llX> ", (uint64_t)box); } else if (is_header(t)) { if (stack) printf("<fram/0x%.3llX> ",(uint64_t)frame_val(t)); else if (is_atom(t)) { printf("<atom/0x%.3llX> ",boxed_arity(t)); return boxed_arity(t)+1; } else printf("<frwd/0x%.3llX> ",(uint64_t)frame_val(t)); } return 1; }
dogen::formatters::artefact stitch_formatter:: format(const artefact_formatter_interface& stock_formatter, const context& ctx, const yarn::element& e) const { const auto al(stock_formatter.archetype_location()); const auto needs_guard(is_header(stock_formatter.inclusion_support_type())); const auto id(e.name().id()); assistant a(ctx, al, needs_guard, id); const auto& fp(a.artefact_properties().file_path()); auto stitch_template(fp); stitch_template.replace_extension(stitch_extension); /* * If the template does not yet exist, we should just create an * empty artefact. * * This scenario happens when creating a new model or when adding * a new artefact formatter for the first time. */ if (!boost::filesystem::exists(stitch_template)) { BOOST_LOG_SEV(lg, debug) << "Stitch template not found: " << fp.generic_string(); dogen::formatters::artefact r; r.overwrite(a.artefact_properties().overwrite()); return r; } /* * Since the template exists, we can instantiate it. */ auto r(instantiator_.instantiate(stitch_template)); r.overwrite(a.artefact_properties().overwrite()); r.dependencies().push_back(stitch_template); return r; }
bool message_equal (const message_ty *mp1, const message_ty *mp2, bool ignore_potcdate) { size_t i, i1, i2; if (!(mp1->msgctxt != NULL ? mp2->msgctxt != NULL && strcmp (mp1->msgctxt, mp2->msgctxt) == 0 : mp2->msgctxt == NULL)) return false; if (strcmp (mp1->msgid, mp2->msgid) != 0) return false; if (!(mp1->msgid_plural != NULL ? mp2->msgid_plural != NULL && strcmp (mp1->msgid_plural, mp2->msgid_plural) == 0 : mp2->msgid_plural == NULL)) return false; if (is_header (mp1) && ignore_potcdate ? !msgstr_equal_ignoring_potcdate (mp1->msgstr, mp1->msgstr_len, mp2->msgstr, mp2->msgstr_len) : !msgstr_equal (mp1->msgstr, mp1->msgstr_len, mp2->msgstr, mp2->msgstr_len)) return false; if (!pos_equal (&mp1->pos, &mp2->pos)) return false; if (!string_list_equal (mp1->comment, mp2->comment)) return false; if (!string_list_equal (mp1->comment_dot, mp2->comment_dot)) return false; i1 = mp1->filepos_count; i2 = mp2->filepos_count; if (i1 != i2) return false; for (i = 0; i < i1; i++) if (!pos_equal (&mp1->filepos[i], &mp2->filepos[i])) return false; if (mp1->is_fuzzy != mp2->is_fuzzy) return false; for (i = 0; i < NFORMATS; i++) if (mp1->is_format[i] != mp2->is_format[i]) return false; if (!(mp1->range.min == mp2->range.min && mp1->range.max == mp2->range.max)) return false; if (!(mp1->prev_msgctxt != NULL ? mp2->prev_msgctxt != NULL && strcmp (mp1->prev_msgctxt, mp2->prev_msgctxt) == 0 : mp2->prev_msgctxt == NULL)) return false; if (!(mp1->prev_msgid != NULL ? mp2->prev_msgid != NULL && strcmp (mp1->prev_msgid, mp2->prev_msgid) == 0 : mp2->prev_msgid == NULL)) return false; if (!(mp1->prev_msgid_plural != NULL ? mp2->prev_msgid_plural != NULL && strcmp (mp1->prev_msgid_plural, mp2->prev_msgid_plural) == 0 : mp2->prev_msgid_plural == NULL)) return false; if (mp1->obsolete != mp2->obsolete) return false; return true; }
Uint size_object(Eterm obj) { Uint sum = 0; Eterm* ptr; int arity; DECLARE_ESTACK(s); for (;;) { switch (primary_tag(obj)) { case TAG_PRIMARY_LIST: sum += 2; ptr = list_val(obj); obj = *ptr++; if (!IS_CONST(obj)) { ESTACK_PUSH(s, obj); } obj = *ptr; break; case TAG_PRIMARY_BOXED: { Eterm hdr = *boxed_val(obj); ASSERT(is_header(hdr)); switch (hdr & _TAG_HEADER_MASK) { case ARITYVAL_SUBTAG: ptr = tuple_val(obj); arity = header_arity(hdr); sum += arity + 1; if (arity == 0) { /* Empty tuple -- unusual. */ goto pop_next; } while (arity-- > 1) { obj = *++ptr; if (!IS_CONST(obj)) { ESTACK_PUSH(s, obj); } } obj = *++ptr; break; case FUN_SUBTAG: { Eterm* bptr = fun_val(obj); ErlFunThing* funp = (ErlFunThing *) bptr; unsigned eterms = 1 /* creator */ + funp->num_free; unsigned sz = thing_arityval(hdr); sum += 1 /* header */ + sz + eterms; bptr += 1 /* header */ + sz; while (eterms-- > 1) { obj = *bptr++; if (!IS_CONST(obj)) { ESTACK_PUSH(s, obj); } } obj = *bptr; break; } case SUB_BINARY_SUBTAG: { Eterm real_bin; Uint offset; /* Not used. */ Uint bitsize; Uint bitoffs; Uint extra_bytes; Eterm hdr; ERTS_GET_REAL_BIN(obj, real_bin, offset, bitoffs, bitsize); if ((bitsize + bitoffs) > 8) { sum += ERL_SUB_BIN_SIZE; extra_bytes = 2; } else if ((bitsize + bitoffs) > 0) { sum += ERL_SUB_BIN_SIZE; extra_bytes = 1; } else { extra_bytes = 0; } hdr = *binary_val(real_bin); if (thing_subtag(hdr) == REFC_BINARY_SUBTAG) { sum += PROC_BIN_SIZE; } else { sum += heap_bin_size(binary_size(obj)+extra_bytes); } goto pop_next; } break; case BIN_MATCHSTATE_SUBTAG: erl_exit(ERTS_ABORT_EXIT, "size_object: matchstate term not allowed"); default: sum += thing_arityval(hdr) + 1; goto pop_next; } } break; case TAG_PRIMARY_IMMED1: pop_next: if (ESTACK_ISEMPTY(s)) { DESTROY_ESTACK(s); return sum; } obj = ESTACK_POP(s); break; default: erl_exit(ERTS_ABORT_EXIT, "size_object: bad tag for %#x\n", obj); } } }
Uint size_object(Eterm obj) #endif { Uint sum = 0; Eterm* ptr; int arity; DECLARE_ESTACK(s); for (;;) { switch (primary_tag(obj)) { case TAG_PRIMARY_LIST: sum += 2; ptr = list_val_rel(obj,base); obj = *ptr++; if (!IS_CONST(obj)) { ESTACK_PUSH(s, obj); } obj = *ptr; break; case TAG_PRIMARY_BOXED: { Eterm hdr = *boxed_val_rel(obj,base); ASSERT(is_header(hdr)); switch (hdr & _TAG_HEADER_MASK) { case ARITYVAL_SUBTAG: ptr = tuple_val_rel(obj,base); arity = header_arity(hdr); sum += arity + 1; if (arity == 0) { /* Empty tuple -- unusual. */ goto pop_next; } while (arity-- > 1) { obj = *++ptr; if (!IS_CONST(obj)) { ESTACK_PUSH(s, obj); } } obj = *++ptr; break; case FUN_SUBTAG: { Eterm* bptr = fun_val_rel(obj,base); ErlFunThing* funp = (ErlFunThing *) bptr; unsigned eterms = 1 /* creator */ + funp->num_free; unsigned sz = thing_arityval(hdr); sum += 1 /* header */ + sz + eterms; bptr += 1 /* header */ + sz; while (eterms-- > 1) { obj = *bptr++; if (!IS_CONST(obj)) { ESTACK_PUSH(s, obj); } } obj = *bptr; break; } case MAP_SUBTAG: switch (MAP_HEADER_TYPE(hdr)) { case MAP_HEADER_TAG_FLATMAP_HEAD : { Uint n; flatmap_t *mp; mp = (flatmap_t*)flatmap_val_rel(obj,base); ptr = (Eterm *)mp; n = flatmap_get_size(mp) + 1; sum += n + 2; ptr += 2; /* hdr + size words */ while (n--) { obj = *ptr++; if (!IS_CONST(obj)) { ESTACK_PUSH(s, obj); } } goto pop_next; } case MAP_HEADER_TAG_HAMT_HEAD_BITMAP : case MAP_HEADER_TAG_HAMT_HEAD_ARRAY : case MAP_HEADER_TAG_HAMT_NODE_BITMAP : { Eterm *head; Uint sz; head = hashmap_val_rel(obj, base); sz = hashmap_bitcount(MAP_HEADER_VAL(hdr)); sum += 1 + sz + header_arity(hdr); head += 1 + header_arity(hdr); if (sz == 0) { goto pop_next; } while(sz-- > 1) { obj = head[sz]; if (!IS_CONST(obj)) { ESTACK_PUSH(s, obj); } } obj = head[0]; } break; default: erl_exit(ERTS_ABORT_EXIT, "size_object: bad hashmap type %d\n", MAP_HEADER_TYPE(hdr)); } break; case SUB_BINARY_SUBTAG: { Eterm real_bin; ERTS_DECLARE_DUMMY(Uint offset); /* Not used. */ Uint bitsize; Uint bitoffs; Uint extra_bytes; Eterm hdr; ERTS_GET_REAL_BIN_REL(obj, real_bin, offset, bitoffs, bitsize, base); if ((bitsize + bitoffs) > 8) { sum += ERL_SUB_BIN_SIZE; extra_bytes = 2; } else if ((bitsize + bitoffs) > 0) { sum += ERL_SUB_BIN_SIZE; extra_bytes = 1; } else { extra_bytes = 0; } hdr = *binary_val_rel(real_bin,base); if (thing_subtag(hdr) == REFC_BINARY_SUBTAG) { sum += PROC_BIN_SIZE; } else { sum += heap_bin_size(binary_size_rel(obj,base)+extra_bytes); } goto pop_next; } break; case BIN_MATCHSTATE_SUBTAG: erl_exit(ERTS_ABORT_EXIT, "size_object: matchstate term not allowed"); default: sum += thing_arityval(hdr) + 1; goto pop_next; } } break; case TAG_PRIMARY_IMMED1: pop_next: if (ESTACK_ISEMPTY(s)) { DESTROY_ESTACK(s); return sum; } obj = ESTACK_POP(s); break; default: erl_exit(ERTS_ABORT_EXIT, "size_object: bad tag for %#x\n", obj); } } }
static char *hbc_action(void *context, HBC_CALL_BACKS *cb, const char *map_class, const char *where, const char *cmd, const char *line, ssize_t line_len, off_t offset) { const char *cmd_args = cmd + strcspn(cmd, " \t"); int cmd_len = cmd_args - cmd; char *ret; /* * XXX We don't use a hash table for action lookup. Mail rarely triggers * an action, and mail that triggers multiple actions is even rarer. * Setting up the hash table costs more than we would gain from using it. */ while (*cmd_args && ISSPACE(*cmd_args)) cmd_args++; #define STREQUAL(x,y,l) (strncasecmp((x), (y), (l)) == 0 && (y)[l] == 0) if (cb->extend && (ret = cb->extend(context, cmd, cmd_len, cmd_args, where, line, line_len, offset)) != HBC_CHECKS_STAT_UNKNOWN) return (ret); if (STREQUAL(cmd, "WARN", cmd_len)) { cb->logger(context, "warning", where, line, cmd_args); return ((char *) line); } if (STREQUAL(cmd, "INFO", cmd_len)) { cb->logger(context, "info", where, line, cmd_args); return ((char *) line); } if (STREQUAL(cmd, "REPLACE", cmd_len)) { if (*cmd_args == 0) { msg_warn("REPLACE action without text in %s map", map_class); return ((char *) line); } else if (strcmp(where, HBC_CTXT_HEADER) == 0 && !is_header(cmd_args)) { msg_warn("bad REPLACE header text \"%s\" in %s map -- " "need \"headername: headervalue\"", cmd_args, map_class); return ((char *) line); } else { cb->logger(context, "replace", where, line, cmd_args); return (mystrdup(cmd_args)); } } if (cb->prepend && STREQUAL(cmd, "PREPEND", cmd_len)) { if (*cmd_args == 0) { msg_warn("PREPEND action without text in %s map", map_class); } else if (strcmp(where, HBC_CTXT_HEADER) == 0 && !is_header(cmd_args)) { msg_warn("bad PREPEND header text \"%s\" in %s map -- " "need \"headername: headervalue\"", cmd_args, map_class); } else { cb->logger(context, "prepend", where, line, cmd_args); cb->prepend(context, REC_TYPE_NORM, cmd_args, strlen(cmd_args), offset); } return ((char *) line); } /* Allow and ignore optional text after the action. */ if (STREQUAL(cmd, "IGNORE", cmd_len)) /* XXX Not logged for compatibility with cleanup(8). */ return (HBC_CHECKS_STAT_IGNORE); if (STREQUAL(cmd, "DUNNO", cmd_len) /* preferred */ ||STREQUAL(cmd, "OK", cmd_len)) /* compatibility */ return ((char *) line); msg_warn("unsupported command in %s map: %s", map_class, cmd); return ((char *) line); }
static void tree_model_get_value (GtkTreeModel *tree_model, GtkTreeIter *iter, gint column, GValue *value) { GList *proposal_node; ProposalInfo *proposal_info; ProviderInfo *provider_info; GtkSourceCompletionProposal *completion_proposal; GtkSourceCompletionProvider *completion_provider; g_return_if_fail (GTK_SOURCE_IS_COMPLETION_MODEL (tree_model)); g_return_if_fail (iter != NULL); g_return_if_fail (iter->user_data != NULL); g_return_if_fail (0 <= column && column < GTK_SOURCE_COMPLETION_MODEL_N_COLUMNS); proposal_node = iter->user_data; proposal_info = proposal_node->data; provider_info = proposal_info->provider_node->data; completion_proposal = proposal_info->completion_proposal; completion_provider = provider_info->completion_provider; g_value_init (value, GTK_SOURCE_COMPLETION_MODEL (tree_model)->priv->column_types[column]); switch (column) { case GTK_SOURCE_COMPLETION_MODEL_COLUMN_PROVIDER: g_value_set_object (value, completion_provider); break; case GTK_SOURCE_COMPLETION_MODEL_COLUMN_PROPOSAL: g_value_set_object (value, completion_proposal); break; case GTK_SOURCE_COMPLETION_MODEL_COLUMN_MARKUP: if (is_header (proposal_info)) { gchar *name = gtk_source_completion_provider_get_name (completion_provider); if (name != NULL) { gchar *escaped = g_markup_escape_text (name, -1); gchar *markup = g_strdup_printf ("<b>%s</b>", escaped); g_value_take_string (value, markup); g_free (name); g_free (escaped); } else { gchar *markup = g_strdup_printf ("<b>%s</b>", _("Provider")); g_value_take_string (value, markup); } } else { gchar *markup = gtk_source_completion_proposal_get_markup (completion_proposal); if (markup == NULL) { gchar *label = gtk_source_completion_proposal_get_label (completion_proposal); markup = g_markup_escape_text (label != NULL ? label : "", -1); g_free (label); } g_value_take_string (value, markup); } break; case GTK_SOURCE_COMPLETION_MODEL_COLUMN_ICON: if (is_header (proposal_info)) { GdkPixbuf *icon = gtk_source_completion_provider_get_icon (completion_provider); g_value_set_object (value, (gpointer)icon); } else { GdkPixbuf *icon = gtk_source_completion_proposal_get_icon (completion_proposal); g_value_set_object (value, (gpointer)icon); } break; case GTK_SOURCE_COMPLETION_MODEL_COLUMN_ICON_NAME: if (is_header (proposal_info)) { const gchar *icon_name = gtk_source_completion_provider_get_icon_name (completion_provider); g_value_set_string (value, (gpointer)icon_name); } else { const gchar *icon_name = gtk_source_completion_proposal_get_icon_name (completion_proposal); g_value_set_string (value, (gpointer)icon_name); } break; case GTK_SOURCE_COMPLETION_MODEL_COLUMN_GICON: if (is_header (proposal_info)) { GIcon *icon = gtk_source_completion_provider_get_gicon (completion_provider); g_value_set_object (value, (gpointer)icon); } else { GIcon *icon = gtk_source_completion_proposal_get_gicon (completion_proposal); g_value_set_object (value, (gpointer)icon); } break; case GTK_SOURCE_COMPLETION_MODEL_COLUMN_IS_HEADER: g_value_set_boolean (value, is_header (proposal_info)); break; default: g_assert_not_reached (); } }
static void postcat(VSTREAM *fp, VSTRING *buffer, int flags) { int prev_type = 0; int rec_type; struct timeval tv; time_t time; int ch; off_t offset; const char *error_text; char *attr_name; char *attr_value; int rec_flags = (msg_verbose ? REC_FLAG_NONE : REC_FLAG_DEFAULT); int state; /* state machine, input type */ int do_print; /* state machine, output control */ long data_offset; /* state machine, read optimization */ long data_size; /* state machine, read optimization */ #define TEXT_RECORD(rec_type) \ (rec_type == REC_TYPE_CONT || rec_type == REC_TYPE_NORM) /* * See if this is a plausible file. */ if ((ch = VSTREAM_GETC(fp)) != VSTREAM_EOF) { if (!strchr(REC_TYPE_ENVELOPE, ch)) { msg_warn("%s: input is not a valid queue file", VSTREAM_PATH(fp)); return; } vstream_ungetc(fp, ch); } /* * Other preliminaries. */ if (flags & PC_FLAG_PRINT_ENV) vstream_printf("*** ENVELOPE RECORDS %s ***\n", VSTREAM_PATH(fp)); state = PC_STATE_ENV; do_print = (flags & PC_FLAG_PRINT_ENV); data_offset = data_size = -1; /* * Now look at the rest. */ for (;;) { if (flags & PC_FLAG_PRINT_OFFSET) offset = vstream_ftell(fp); rec_type = rec_get_raw(fp, buffer, 0, rec_flags); if (rec_type == REC_TYPE_ERROR) msg_fatal("record read error"); if (rec_type == REC_TYPE_EOF) break; /* * First inspect records that have side effects on the (envelope, * header, body) state machine or on the record reading order. * * XXX Comments marked "Optimization:" identify subtle code that will * likely need to be revised when the queue file organization is * changed. */ #define PRINT_MARKER(flags, fp, offset, type, text) do { \ if ((flags) & PC_FLAG_PRINT_OFFSET) \ vstream_printf("%9lu ", (unsigned long) (offset)); \ if (flags & PC_FLAG_PRINT_RTYPE_DEC) \ vstream_printf("%3d ", (type)); \ vstream_printf("*** %s %s ***\n", (text), VSTREAM_PATH(fp)); \ vstream_fflush(VSTREAM_OUT); \ } while (0) #define PRINT_RECORD(flags, offset, type, value) do { \ if ((flags) & PC_FLAG_PRINT_OFFSET) \ vstream_printf("%9lu ", (unsigned long) (offset)); \ if (flags & PC_FLAG_PRINT_RTYPE_DEC) \ vstream_printf("%3d ", (type)); \ vstream_printf("%s: %s\n", rec_type_name(rec_type), (value)); \ vstream_fflush(VSTREAM_OUT); \ } while (0) if (TEXT_RECORD(rec_type)) { /* This is wrong when the message starts with whitespace. */ if (state == PC_STATE_HEADER && (flags & (PC_MASK_PRINT_TEXT)) && prev_type != REC_TYPE_CONT && TEXT_RECORD(rec_type) && !(is_header(STR(buffer)) || IS_SPACE_TAB(STR(buffer)[0]))) { /* Update the state machine. */ state = PC_STATE_BODY; do_print = (flags & PC_FLAG_PRINT_BODY); /* Optimization: terminate if nothing left to print. */ if (do_print == 0 && (flags & PC_FLAG_PRINT_ENV) == 0) break; /* Optimization: skip to extracted segment marker. */ if (do_print == 0 && (flags & PC_FLAG_PRINT_ENV) && data_offset >= 0 && data_size >= 0 && vstream_fseek(fp, data_offset + data_size, SEEK_SET) < 0) msg_fatal("seek error: %m"); } /* Optional output happens further down below. */ } else if (rec_type == REC_TYPE_MESG) { /* Sanity check. */ if (state != PC_STATE_ENV) msg_warn("%s: out-of-order message content marker", VSTREAM_PATH(fp)); /* Optional output. */ if (flags & PC_FLAG_PRINT_ENV) PRINT_MARKER(flags, fp, offset, rec_type, "MESSAGE CONTENTS"); /* Optimization: skip to extracted segment marker. */ if ((flags & PC_MASK_PRINT_TEXT) == 0 && data_offset >= 0 && data_size >= 0 && vstream_fseek(fp, data_offset + data_size, SEEK_SET) < 0) msg_fatal("seek error: %m"); /* Update the state machine, even when skipping. */ state = PC_STATE_HEADER; do_print = (flags & PC_FLAG_PRINT_HEADER); continue; } else if (rec_type == REC_TYPE_XTRA) { /* Sanity check. */ if (state != PC_STATE_HEADER && state != PC_STATE_BODY) msg_warn("%s: out-of-order extracted segment marker", VSTREAM_PATH(fp)); /* Optional output (terminate preceding header/body line). */ if (do_print && prev_type == REC_TYPE_CONT) VSTREAM_PUTCHAR('\n'); if (flags & PC_FLAG_PRINT_ENV) PRINT_MARKER(flags, fp, offset, rec_type, "HEADER EXTRACTED"); /* Update the state machine. */ state = PC_STATE_ENV; do_print = (flags & PC_FLAG_PRINT_ENV); /* Optimization: terminate if nothing left to print. */ if (do_print == 0) break; continue; } else if (rec_type == REC_TYPE_END) { /* Sanity check. */ if (state != PC_STATE_ENV) msg_warn("%s: out-of-order message end marker", VSTREAM_PATH(fp)); /* Optional output. */ if (flags & PC_FLAG_PRINT_ENV) PRINT_MARKER(flags, fp, offset, rec_type, "MESSAGE FILE END"); /* Terminate the state machine. */ break; } else if (rec_type == REC_TYPE_PTR) { /* Optional output. */ /* This record type is exposed only with '-v'. */ if (do_print) PRINT_RECORD(flags, offset, rec_type, STR(buffer)); /* Skip to the pointer's target record. */ if (rec_goto(fp, STR(buffer)) == REC_TYPE_ERROR) msg_fatal("bad pointer record, or input is not seekable"); continue; } else if (rec_type == REC_TYPE_SIZE) { /* Optional output (here before we update the state machine). */ if (do_print) PRINT_RECORD(flags, offset, rec_type, STR(buffer)); /* Read the message size/offset for the state machine optimizer. */ if (data_size >= 0 || data_offset >= 0) { msg_warn("file contains multiple size records"); } else { if (sscanf(STR(buffer), "%ld %ld", &data_size, &data_offset) != 2 || data_offset <= 0 || data_size <= 0) msg_fatal("invalid size record: %.100s", STR(buffer)); /* Optimization: skip to the message header. */ if ((flags & PC_FLAG_PRINT_ENV) == 0) { if (vstream_fseek(fp, data_offset, SEEK_SET) < 0) msg_fatal("seek error: %m"); /* Update the state machine. */ state = PC_STATE_HEADER; do_print = (flags & PC_FLAG_PRINT_HEADER); } } continue; } /* * Don't inspect side-effect-free records that aren't printed. */ if (do_print == 0) continue; if (flags & PC_FLAG_PRINT_OFFSET) vstream_printf("%9lu ", (unsigned long) offset); if (flags & PC_FLAG_PRINT_RTYPE_DEC) vstream_printf("%3d ", rec_type); switch (rec_type) { case REC_TYPE_TIME: REC_TYPE_TIME_SCAN(STR(buffer), tv); time = tv.tv_sec; vstream_printf("%s: %s", rec_type_name(rec_type), asctime(localtime(&time))); break; case REC_TYPE_WARN: REC_TYPE_WARN_SCAN(STR(buffer), time); vstream_printf("%s: %s", rec_type_name(rec_type), asctime(localtime(&time))); break; case REC_TYPE_CONT: /* REC_TYPE_FILT collision */ if (state == PC_STATE_ENV) vstream_printf("%s: ", rec_type_name(rec_type)); else if (msg_verbose) vstream_printf("unterminated_text: "); vstream_fwrite(VSTREAM_OUT, STR(buffer), LEN(buffer)); if (state == PC_STATE_ENV || msg_verbose || (flags & PC_FLAG_PRINT_OFFSET) != 0) { rec_type = 0; VSTREAM_PUTCHAR('\n'); } break; case REC_TYPE_NORM: if (msg_verbose) vstream_printf("%s: ", rec_type_name(rec_type)); vstream_fwrite(VSTREAM_OUT, STR(buffer), LEN(buffer)); VSTREAM_PUTCHAR('\n'); break; case REC_TYPE_DTXT: /* This record type is exposed only with '-v'. */ vstream_printf("%s: ", rec_type_name(rec_type)); vstream_fwrite(VSTREAM_OUT, STR(buffer), LEN(buffer)); VSTREAM_PUTCHAR('\n'); break; case REC_TYPE_ATTR: error_text = split_nameval(STR(buffer), &attr_name, &attr_value); if (error_text != 0) { msg_warn("%s: malformed attribute: %s: %.100s", VSTREAM_PATH(fp), error_text, STR(buffer)); break; } if (strcmp(attr_name, MAIL_ATTR_CREATE_TIME) == 0) { time = atol(attr_value); vstream_printf("%s: %s", MAIL_ATTR_CREATE_TIME, asctime(localtime(&time))); } else { vstream_printf("%s: %s=%s\n", rec_type_name(rec_type), attr_name, attr_value); } break; default: vstream_printf("%s: %s\n", rec_type_name(rec_type), STR(buffer)); break; } prev_type = rec_type; /* * In case the next record is broken. */ vstream_fflush(VSTREAM_OUT); } }
msgdomain_list_ty * msgdomain_read_tcl (const char *locale_name, const char *directory) { const char *gettextdatadir; char *tclscript; size_t len; char *frobbed_locale_name; char *p; char *file_name; char *argv[4]; pid_t child; int fd[1]; FILE *fp; msgdomain_list_ty *mdlp; int exitstatus; size_t k; /* Make it possible to override the msgunfmt.tcl location. This is necessary for running the testsuite before "make install". */ gettextdatadir = getenv ("GETTEXTDATADIR"); if (gettextdatadir == NULL || gettextdatadir[0] == '\0') gettextdatadir = relocate (GETTEXTDATADIR); tclscript = concatenated_pathname (gettextdatadir, "msgunfmt.tcl", NULL); /* Convert the locale name to lowercase and remove any encoding. */ len = strlen (locale_name); frobbed_locale_name = (char *) xallocsa (len + 1); memcpy (frobbed_locale_name, locale_name, len + 1); for (p = frobbed_locale_name; *p != '\0'; p++) if (*p >= 'A' && *p <= 'Z') *p = *p - 'A' + 'a'; else if (*p == '.') { *p = '\0'; break; } file_name = concatenated_pathname (directory, frobbed_locale_name, ".msg"); freesa (frobbed_locale_name); /* Prepare arguments. */ argv[0] = "tclsh"; argv[1] = tclscript; argv[2] = file_name; argv[3] = NULL; if (verbose) { char *command = shell_quote_argv (argv); printf ("%s\n", command); free (command); } /* Open a pipe to the Tcl interpreter. */ child = create_pipe_in ("tclsh", "tclsh", argv, DEV_NULL, false, true, true, fd); fp = fdopen (fd[0], "r"); if (fp == NULL) error (EXIT_FAILURE, errno, _("fdopen() failed")); /* Read the message list. */ mdlp = read_catalog_stream (fp, "(pipe)", "(pipe)", &input_format_po); fclose (fp); /* Remove zombie process from process list, and retrieve exit status. */ exitstatus = wait_subprocess (child, "tclsh", false, false, true, true); if (exitstatus != 0) { if (exitstatus == 2) /* Special exitcode provided by msgunfmt.tcl. */ error (EXIT_FAILURE, ENOENT, _("error while opening \"%s\" for reading"), file_name); else error (EXIT_FAILURE, 0, _("%s subprocess failed with exit code %d"), "tclsh", exitstatus); } free (tclscript); /* Move the header entry to the beginning. */ for (k = 0; k < mdlp->nitems; k++) { message_list_ty *mlp = mdlp->item[k]->messages; size_t j; for (j = 0; j < mlp->nitems; j++) if (is_header (mlp->item[j])) { /* Found the header entry. */ if (j > 0) { message_ty *header = mlp->item[j]; size_t i; for (i = j; i > 0; i--) mlp->item[i] = mlp->item[i - 1]; mlp->item[0] = header; } break; } } return mdlp; }
/* * Returns true/false indicating data successfully read from hypervisor. * Used both to get packets for tty connections and to advance the state * machine during console handshaking (in which case tty = NULL and we ignore * incoming data). */ static int hvsi_load_chunk(struct hvsi_struct *hp, struct tty_struct **flip, struct tty_struct **hangup, struct hvsi_struct **handshake) { uint8_t *packet = hp->inbuf; int chunklen; *flip = NULL; *hangup = NULL; *handshake = NULL; chunklen = hvsi_read(hp, hp->inbuf_end, HVSI_MAX_READ); if (chunklen == 0) { pr_debug("%s: 0-length read\n", __FUNCTION__); return 0; } pr_debug("%s: got %i bytes\n", __FUNCTION__, chunklen); dbg_dump_hex(hp->inbuf_end, chunklen); hp->inbuf_end += chunklen; /* handle all completed packets */ while ((packet < hp->inbuf_end) && got_packet(hp, packet)) { struct hvsi_header *header = (struct hvsi_header *)packet; if (!is_header(packet)) { printk(KERN_ERR "hvsi%i: got malformed packet\n", hp->index); /* skip bytes until we find a header or run out of data */ while ((packet < hp->inbuf_end) && (!is_header(packet))) packet++; continue; } pr_debug("%s: handling %i-byte packet\n", __FUNCTION__, len_packet(packet)); dbg_dump_packet(packet); switch (header->type) { case VS_DATA_PACKET_HEADER: if (!is_open(hp)) break; if (hp->tty == NULL) break; /* no tty buffer to put data in */ *flip = hvsi_recv_data(hp, packet); break; case VS_CONTROL_PACKET_HEADER: hvsi_recv_control(hp, packet, hangup, handshake); break; case VS_QUERY_RESPONSE_PACKET_HEADER: hvsi_recv_response(hp, packet); break; case VS_QUERY_PACKET_HEADER: hvsi_recv_query(hp, packet); break; default: printk(KERN_ERR "hvsi%i: unknown HVSI packet type 0x%x\n", hp->index, header->type); dump_packet(packet); break; } packet += len_packet(packet); if (*hangup || *handshake) { pr_debug("%s: hangup or handshake\n", __FUNCTION__); /* * we need to send the hangup now before receiving any more data. * If we get "data, hangup, data", we can't deliver the second * data before the hangup. */ break; } } compact_inbuf(hp, packet); return 1; }
int mime_state_update(MIME_STATE *state, int rec_type, const char *text, int len) { int input_is_text = (rec_type == REC_TYPE_NORM || rec_type == REC_TYPE_CONT); MIME_STACK *sp; HEADER_OPTS *header_info; const unsigned char *cp; #define SAVE_PREV_REC_TYPE_AND_RETURN_ERR_FLAGS(state, rec_type) do { \ state->prev_rec_type = rec_type; \ return (state->err_flags); \ } while (0) /* * Be sure to flush any partial output line that might still be buffered * up before taking any other "end of input" actions. */ if (!input_is_text && state->prev_rec_type == REC_TYPE_CONT) mime_state_update(state, REC_TYPE_NORM, "", 0); /* * This message state machine is kept simple for the sake of robustness. * Standards evolve over time, and we want to be able to correctly * process messages that are not yet defined. This state machine knows * about headers and bodies, understands that multipart/whatever has * multiple body parts with a header and body, and that message/whatever * has message headers at the start of a body part. */ switch (state->curr_state) { /* * First, deal with header information that we have accumulated from * previous input records. Discard text that does not fit in a header * buffer. Our limit is quite generous; Sendmail will refuse mail * with only 32kbyte in all the message headers combined. */ case MIME_STATE_PRIMARY: case MIME_STATE_MULTIPART: case MIME_STATE_NESTED: if (LEN(state->output_buffer) > 0) { if (input_is_text) { if (state->prev_rec_type == REC_TYPE_CONT) { if (LEN(state->output_buffer) < var_header_limit) { vstring_strcat(state->output_buffer, text); } else { if (state->static_flags & MIME_OPT_REPORT_TRUNC_HEADER) REPORT_ERROR(state, MIME_ERR_TRUNC_HEADER, STR(state->output_buffer)); } SAVE_PREV_REC_TYPE_AND_RETURN_ERR_FLAGS(state, rec_type); } if (IS_SPACE_TAB(*text)) { if (LEN(state->output_buffer) < var_header_limit) { vstring_strcat(state->output_buffer, "\n"); vstring_strcat(state->output_buffer, text); } else { if (state->static_flags & MIME_OPT_REPORT_TRUNC_HEADER) REPORT_ERROR(state, MIME_ERR_TRUNC_HEADER, STR(state->output_buffer)); } SAVE_PREV_REC_TYPE_AND_RETURN_ERR_FLAGS(state, rec_type); } } /* * The input is (the beginning of) another message header, or is * not a message header, or is not even a text record. With no * more input to append to this saved header, do output * processing and reset the saved header buffer. Hold on to the * content transfer encoding header if we have to do a 8->7 * transformation, because the proper information depends on the * content type header: message and multipart require a domain, * leaf entities have either a transformation or a domain. */ if (LEN(state->output_buffer) > 0) { header_info = header_opts_find(STR(state->output_buffer)); if (!(state->static_flags & MIME_OPT_DISABLE_MIME) && header_info != 0) { if (header_info->type == HDR_CONTENT_TYPE) mime_state_content_type(state, header_info); if (header_info->type == HDR_CONTENT_TRANSFER_ENCODING) mime_state_content_encoding(state, header_info); } if ((state->static_flags & MIME_OPT_REPORT_8BIT_IN_HEADER) != 0 && (state->err_flags & MIME_ERR_8BIT_IN_HEADER) == 0) { for (cp = CU_CHAR_PTR(STR(state->output_buffer)); cp < CU_CHAR_PTR(END(state->output_buffer)); cp++) if (*cp & 0200) { REPORT_ERROR(state, MIME_ERR_8BIT_IN_HEADER, STR(state->output_buffer)); break; } } /* Output routine is explicitly allowed to change the data. */ if (header_info == 0 || header_info->type != HDR_CONTENT_TRANSFER_ENCODING || (state->static_flags & MIME_OPT_DOWNGRADE) == 0 || state->curr_domain == MIME_ENC_7BIT) HEAD_OUT(state, header_info, len); state->prev_rec_type = 0; VSTRING_RESET(state->output_buffer); } } /* * With past header information moved out of the way, proceed with a * clean slate. */ if (input_is_text) { int header_len; /* * See if this input is (the beginning of) a message header. * Normalize obsolete "name space colon" syntax to "name colon". * Things would be too confusing otherwise. */ if ((header_len = is_header(text)) > 0) { vstring_strncpy(state->output_buffer, text, header_len); for (text += header_len; IS_SPACE_TAB(*text); text++) /* void */ ; vstring_strcat(state->output_buffer, text); SAVE_PREV_REC_TYPE_AND_RETURN_ERR_FLAGS(state, rec_type); } } /* * This input terminates a block of message headers. When converting * 8-bit to 7-bit mail, this is the right place to emit the correct * content-transfer-encoding header. With message or multipart we * specify 7bit, with leaf entities we specify quoted-printable. * * We're not going to convert non-text data into base 64. If they send * arbitrary binary data as 8-bit text, then the data is already * broken beyond recovery, because the Postfix SMTP server sanitizes * record boundaries, treating broken record boundaries as CRLF. * * Clear the output buffer, we will need it for storage of the * conversion result. */ if ((state->static_flags & MIME_OPT_DOWNGRADE) && state->curr_domain != MIME_ENC_7BIT) { if (state->curr_ctype == MIME_CTYPE_MESSAGE || state->curr_ctype == MIME_CTYPE_MULTIPART) cp = CU_CHAR_PTR("7bit"); else cp = CU_CHAR_PTR("quoted-printable"); vstring_sprintf(state->output_buffer, "Content-Transfer-Encoding: %s", cp); HEAD_OUT(state, (HEADER_OPTS *) 0, len); VSTRING_RESET(state->output_buffer); } /* * This input terminates a block of message headers. Call the * optional header end routine at the end of the first header block. */ if (state->curr_state == MIME_STATE_PRIMARY && state->head_end) state->head_end(state->app_context); /* * This is the right place to check if the sender specified an * appropriate identity encoding (7bit, 8bit, binary) for multipart * and for message. */ if (state->static_flags & MIME_OPT_REPORT_ENCODING_DOMAIN) { if (state->curr_ctype == MIME_CTYPE_MESSAGE) { if (state->curr_stype == MIME_STYPE_PARTIAL || state->curr_stype == MIME_STYPE_EXTERN_BODY) { if (state->curr_domain != MIME_ENC_7BIT) REPORT_ERROR(state, MIME_ERR_ENCODING_DOMAIN, mime_state_enc_name(state->curr_encoding)); } else { if (state->curr_encoding != state->curr_domain) REPORT_ERROR(state, MIME_ERR_ENCODING_DOMAIN, mime_state_enc_name(state->curr_encoding)); } } else if (state->curr_ctype == MIME_CTYPE_MULTIPART) { if (state->curr_encoding != state->curr_domain) REPORT_ERROR(state, MIME_ERR_ENCODING_DOMAIN, mime_state_enc_name(state->curr_encoding)); } } /* * Find out if the next body starts with its own message headers. In * agressive mode, examine headers of partial and external-body * messages. Otherwise, treat such headers as part of the "body". Set * the proper encoding information for the multipart prolog. * * XXX This changes state to MIME_STATE_NESTED and then outputs a body * line, so that the body offset is not properly reset. */ if (input_is_text) { if (*text == 0) { state->body_offset = 0; /* XXX */ if (state->curr_ctype == MIME_CTYPE_MESSAGE) { if (state->curr_stype == MIME_STYPE_RFC822 || (state->static_flags & MIME_OPT_RECURSE_ALL_MESSAGE)) SET_MIME_STATE(state, MIME_STATE_NESTED, MIME_CTYPE_TEXT, MIME_STYPE_PLAIN, MIME_ENC_7BIT, MIME_ENC_7BIT); else SET_CURR_STATE(state, MIME_STATE_BODY); } else if (state->curr_ctype == MIME_CTYPE_MULTIPART) { SET_MIME_STATE(state, MIME_STATE_BODY, MIME_CTYPE_OTHER, MIME_STYPE_OTHER, MIME_ENC_7BIT, MIME_ENC_7BIT); } else { SET_CURR_STATE(state, MIME_STATE_BODY); } } /* * Invalid input. Force output of one blank line and jump to the * body state, leaving all other state alone. */ else { SET_CURR_STATE(state, MIME_STATE_BODY); BODY_OUT(state, REC_TYPE_NORM, "", 0); } } /* * This input is not text. Go to body state, unconditionally. */ else { SET_CURR_STATE(state, MIME_STATE_BODY); } /* FALLTHROUGH */ /* * Body text. Look for message boundaries, and recover from missing * boundary strings. Missing boundaries can happen in agressive mode * with text/rfc822-headers or with message/partial. Ignore non-space * cruft after --boundary or --boundary--, because some MUAs do, and * because only perverse software would take advantage of this to * escape detection. We have to ignore trailing cruft anyway, because * our saved copy of the boundary string may have been truncated for * safety reasons. * * Optionally look for 8-bit data in content that was announced as, or * that defaults to, 7-bit. Unfortunately, we cannot turn this on by * default. Majordomo sends requests for approval that do not * propagate the MIME information from the enclosed message to the * message headers of the approval request. * * Set the proper state information after processing a message boundary * string. * * Don't look for boundary strings at the start of a continued record. */ case MIME_STATE_BODY: if (input_is_text) { if ((state->static_flags & MIME_OPT_REPORT_8BIT_IN_7BIT_BODY) != 0 && state->curr_encoding == MIME_ENC_7BIT && (state->err_flags & MIME_ERR_8BIT_IN_7BIT_BODY) == 0) { for (cp = CU_CHAR_PTR(text); cp < CU_CHAR_PTR(text + len); cp++) if (*cp & 0200) { REPORT_ERROR(state, MIME_ERR_8BIT_IN_7BIT_BODY, text); break; } } if (state->stack && state->prev_rec_type != REC_TYPE_CONT && text[0] == '-' && text[1] == '-') { for (sp = state->stack; sp != 0; sp = sp->next) { if (strncmp(text + 2, sp->boundary, sp->bound_len) == 0) { while (sp != state->stack) mime_state_pop(state); if (strncmp(text + 2 + sp->bound_len, "--", 2) == 0) { mime_state_pop(state); SET_MIME_STATE(state, MIME_STATE_BODY, MIME_CTYPE_OTHER, MIME_STYPE_OTHER, MIME_ENC_7BIT, MIME_ENC_7BIT); } else { SET_MIME_STATE(state, MIME_STATE_MULTIPART, sp->def_ctype, sp->def_stype, MIME_ENC_7BIT, MIME_ENC_7BIT); } break; } } } /* Put last for consistency with header output routine. */ if ((state->static_flags & MIME_OPT_DOWNGRADE) && state->curr_domain != MIME_ENC_7BIT) mime_state_downgrade(state, rec_type, text, len); else BODY_OUT(state, rec_type, text, len); } /* * The input is not a text record. Inform the application that this * is the last opportunity to send any pending output. */ else { if (state->body_end) state->body_end(state->app_context); } SAVE_PREV_REC_TYPE_AND_RETURN_ERR_FLAGS(state, rec_type); /* * Oops. This can't happen. */ default: msg_panic("mime_state_update: unknown state: %d", state->curr_state); } }