static gchar * get_tag (const gchar *utf8_string, const gchar *tag_name, gchar *opening, gchar *closing) { gchar *t; gunichar c; gboolean has_end; c = '\0'; t = g_utf8_find_prev_char (utf8_string, closing); while (t != opening) { c = g_utf8_get_char (t); if (!g_unichar_isspace (c)) break; } /* Not a pair tag */ if (c == '/') return g_strndup (opening, closing - opening + 1); t = closing; while (t) { c = g_utf8_get_char (t); if (c == '<') { if (t[1] == '!' && t[2] == '-' && t[3] == '-') { /* it's a comment start, read until the end of "-->" */ gchar *end = strstr (t + 4, "-->"); if (end) { t = end + 2; } else break; } else break; } t = g_utf8_find_next_char (t, NULL); } has_end = FALSE; do { c = g_utf8_get_char (t); if (c == '/') { has_end = TRUE; break; } if (c == '>') { has_end = FALSE; break; } t = g_utf8_find_next_char (t, NULL); } while (t); /* Broken HTML? */ if (!has_end) return NULL; do { c = g_utf8_get_char (t); if ((c != ' ') && (c != '/')) break; t = g_utf8_find_next_char (t, NULL); } while (t); /* tag_name is always ASCII */ if (g_ascii_strncasecmp (t, tag_name, strlen (tag_name)) == 0) { closing = g_utf8_strchr (t, -1, '>'); return g_strndup (opening, closing - opening + 1); } /* Broken HTML? */ return NULL; }
static void video_guess_values_from_display_name (const gchar *display_name, gchar **title, gchar **showname, GDateTime **date, gint *season, gint *episode) { gchar *metadata; GRegex *regex; GMatchInfo *info; metadata = video_display_name_to_metadata (display_name); regex = g_regex_new (MOVIE_REGEX, 0, 0, NULL); g_regex_match (regex, metadata, 0, &info); if (g_match_info_matches (info)) { if (title) { *title = g_match_info_fetch_named (info, "name"); /* Replace "." with <space> */ g_strdelimit (*title, ".", ' '); *title = g_strstrip (*title); } if (date) { gchar *year = g_match_info_fetch_named (info, "year"); *date = g_date_time_new_utc (atoi (year), 1, 1, 0, 0, 0.0); g_free (year); } if (showname) { *showname = NULL; } if (season) { *season = 0; } if (episode) { *episode = 0; } g_regex_unref (regex); g_match_info_free (info); g_free (metadata); return; } g_regex_unref (regex); g_match_info_free (info); regex = g_regex_new (TV_REGEX, 0, 0, NULL); g_regex_match (regex, metadata, 0, &info); if (g_match_info_matches (info)) { if (title) { *title = g_match_info_fetch_named (info, "name"); g_strdelimit (*title, ".()", ' '); *title = g_strstrip (*title); if (*title[0] == '\0') { g_free (*title); *title = NULL; } } if (showname) { *showname = g_match_info_fetch_named (info, "showname"); g_strdelimit (*showname, ".", ' '); *showname = g_strstrip (*showname); } if (season) { gchar *s = g_match_info_fetch_named (info, "season"); if (s) { if (*s == 's' || *s == 'S') { *season = atoi (s + 1); } else { *season = atoi (s); } } else { *season = 0; } g_free (s); } if (episode) { gchar *e = g_match_info_fetch_named (info, "episode"); if (e) { if (g_ascii_strncasecmp (e, "ep", 2) == 0) { *episode = atoi (e + 2); } else if (*e == 'e' || *e == 'E' || *e == 'x' || *e == '.') { *episode = atoi (e + 1); } else { *episode = atoi (e); } } else { *episode = 0; } g_free (e); } if (date) { *date = NULL; } g_regex_unref (regex); g_match_info_free (info); g_free (metadata); return; } g_regex_unref (regex); g_match_info_free (info); /* The filename doesn't look like a movie or a TV show, just use the filename without extension as the title */ if (title) { *title = g_strdelimit (metadata, ".", ' '); } if (showname) { *showname = NULL; } if (date) { *date = NULL; } if (season) { *season = 0; } if (episode) { *episode = 0; } }
static gboolean show_suggest_dropdown(GntEntry *entry) { char *suggest = NULL; int len; int offset = 0, x, y; int count = 0; GList *iter; const char *text = NULL; const char *sgst = NULL; int max = -1; if (entry->word) { char *s = get_beginning_of_word(entry); suggest = g_strndup(s, entry->cursor - s); if (entry->scroll < s) offset = gnt_util_onscreen_width(entry->scroll, s); } else suggest = g_strdup(entry->start); len = strlen(suggest); /* Don't need to use the utf8-function here */ if (entry->ddown == NULL) { GntWidget *box = gnt_vbox_new(FALSE); entry->ddown = gnt_tree_new(); gnt_tree_set_compare_func(GNT_TREE(entry->ddown), (GCompareFunc)g_utf8_collate); gnt_box_add_widget(GNT_BOX(box), entry->ddown); GNT_WIDGET_SET_FLAGS(box, GNT_WIDGET_TRANSIENT); gnt_widget_get_position(GNT_WIDGET(entry), &x, &y); x += offset; y++; if (y + 10 >= getmaxy(stdscr)) y -= 11; gnt_widget_set_position(box, x, y); } else gnt_tree_remove_all(GNT_TREE(entry->ddown)); for (count = 0, iter = entry->suggests; iter; iter = iter->next) { text = iter->data; if (g_ascii_strncasecmp(suggest, text, len) == 0 && strlen(text) >= len) { gnt_tree_add_row_after(GNT_TREE(entry->ddown), (gpointer)text, gnt_tree_create_row(GNT_TREE(entry->ddown), text), NULL, NULL); count++; if (max == -1) max = strlen(text) - len; else if (max) max = MIN(max, max_common_prefix(sgst + len, text + len)); sgst = text; } } g_free(suggest); if (count == 0) { destroy_suggest(entry); return FALSE; } else if (count == 1) { char *store = g_strndup(entry->start, entry->end - entry->start); gboolean ret; destroy_suggest(entry); complete_suggest(entry, sgst); ret = (strncmp(store, entry->start, entry->end - entry->start) != 0); g_free(store); return ret; } else { if (max > 0) { GntWidget *ddown = entry->ddown; char *match = g_strndup(sgst + len, max); entry->ddown = NULL; gnt_entry_key_pressed(GNT_WIDGET(entry), match); g_free(match); if (entry->ddown) gnt_widget_destroy(ddown); else entry->ddown = ddown; } gnt_widget_draw(entry->ddown->parent); } return TRUE; }
static gint multipart_parse_header (GstMultipartDemux * multipart) { const guint8 *data; const guint8 *dataend; gchar *boundary; int boundary_len; int datalen; guint8 *pos; guint8 *end, *next; datalen = gst_adapter_available (multipart->adapter); data = gst_adapter_peek (multipart->adapter, datalen); dataend = data + datalen; /* Skip leading whitespace, pos endposition should at least leave space for * the boundary and a \n */ for (pos = (guint8 *) data; pos < dataend - 4 && g_ascii_isspace (*pos); pos++); if (pos >= dataend - 4) { return MULTIPART_NEED_MORE_DATA; } if (G_UNLIKELY (pos[0] != '-' || pos[1] != '-')) { GST_DEBUG_OBJECT (multipart, "No boundary available"); goto wrong_header; } /* First the boundary */ if (!get_line_end (pos, dataend, &end, &next)) return MULTIPART_NEED_MORE_DATA; /* Ignore the leading -- */ boundary_len = end - pos - 2; boundary = (gchar *) pos + 2; if (boundary_len < 1) { GST_DEBUG_OBJECT (multipart, "No boundary available"); goto wrong_header; } if (G_UNLIKELY (multipart->boundary == NULL)) { /* First time we see the boundary, copy it */ multipart->boundary = g_strndup (boundary, boundary_len); multipart->boundary_len = boundary_len; } else if (G_UNLIKELY (boundary_len != multipart->boundary_len)) { /* Something odd is going on, either the boundary indicated EOS or it's * invalid */ if (G_UNLIKELY (boundary_len == multipart->boundary_len + 2 && !strncmp (boundary, multipart->boundary, multipart->boundary_len) && !strncmp (boundary + multipart->boundary_len, "--", 2))) { return MULTIPART_DATA_EOS; } GST_DEBUG_OBJECT (multipart, "Boundary length doesn't match detected boundary (%d <> %d", boundary_len, multipart->boundary_len); goto wrong_header; } else if (G_UNLIKELY (strncmp (boundary, multipart->boundary, boundary_len))) { GST_DEBUG_OBJECT (multipart, "Boundary doesn't match previous boundary"); goto wrong_header; } pos = next; while (get_line_end (pos, dataend, &end, &next)) { guint len = end - pos; if (len == 0) { /* empty line, data starts behind us */ GST_DEBUG_OBJECT (multipart, "Parsed the header - boundary: %s, mime-type: %s, content-length: %d", multipart->boundary, multipart->mime_type, multipart->content_length); return next - data; } if (len >= 14 && !g_ascii_strncasecmp ("content-type:", (gchar *) pos, 13)) { guint mime_len; /* only take the mime type up to the first ; if any. After ; there can be * properties that we don't handle yet. */ mime_len = get_mime_len (pos + 14, len - 14); g_free (multipart->mime_type); multipart->mime_type = g_ascii_strdown ((gchar *) pos + 14, mime_len); } else if (len >= 15 && !g_ascii_strncasecmp ("content-length:", (gchar *) pos, 15)) { multipart->content_length = g_ascii_strtoull ((gchar *) pos + 15, NULL, 10); } pos = next; } GST_DEBUG_OBJECT (multipart, "Need more data for the header"); return MULTIPART_NEED_MORE_DATA; wrong_header: { GST_ELEMENT_ERROR (multipart, STREAM, DEMUX, (NULL), ("Boundary not found in the multipart header")); return MULTIPART_DATA_ERROR; } }
/* * Parse one address from the input stream; if an output stream is * given, create an item on it for the output address. */ static LibBalsaABErr libbalsa_address_book_vcard_parse_address(FILE * stream, LibBalsaAddress * address, FILE * stream_out, LibBalsaAddress * address_out) { gchar string[LINE_LEN]; gchar *name = NULL, *nick_name = NULL, *org = NULL; gchar *full_name = NULL, *last_name = NULL, *first_name = NULL; gint in_vcard = FALSE; GList *address_list = NULL; guint wrote = 0; while (fgets(string, sizeof(string), stream)) { /* * Check if it is a card. */ if (g_ascii_strncasecmp(string, "BEGIN:VCARD", 11) == 0) { in_vcard = TRUE; if (stream_out) lbab_vcard_write_begin(stream_out); continue; } if (g_ascii_strncasecmp(string, "END:VCARD", 9) == 0) { LibBalsaABErr res = LBABERR_CANNOT_READ; /* * We are done loading a card. */ if (address_list) { if (stream_out) { if (!(wrote & (1 << FULL_NAME))) lbab_vcard_write_fn(stream_out, address_out); if (!(wrote & (1 << FIRST_NAME))) lbab_vcard_write_n(stream_out, address_out); if (!(wrote & (1 << NICK_NAME))) lbab_vcard_write_nickname(stream_out, address_out); if (!(wrote & (1 << ORGANIZATION))) lbab_vcard_write_org(stream_out, address_out); lbab_vcard_write_addresses(stream_out, address_out); res = lbab_vcard_write_end(stream_out); } if (address) { if (full_name) { address->full_name = full_name; g_free(name); } else if (name) address->full_name = name; else if (nick_name) address->full_name = g_strdup(nick_name); else address->full_name = g_strdup(_("No-Name")); address->last_name = last_name; address->first_name = first_name; address->nick_name = nick_name; address->organization = org; address->address_list = g_list_reverse(address_list); return LBABERR_OK; } g_list_foreach(address_list, (GFunc) g_free, NULL); g_list_free(address_list); } /* Record without e-mail address, or we're not creating * addresses: free memory. */ g_free(full_name); g_free(name); g_free(last_name); g_free(first_name); g_free(nick_name); g_free(org); return res; } if (!in_vcard) continue; g_strchomp(string); if (g_ascii_strncasecmp(string, "FN:", 3) == 0) { full_name = g_strdup(string + 3); full_name = validate_vcard_string(full_name); if (stream_out) { lbab_vcard_write_fn(stream_out, address_out); wrote |= 1 << FULL_NAME; } continue; } if (g_ascii_strncasecmp(string, "N:", 2) == 0) { name = libbalsa_address_extract_name(string + 2, &last_name, &first_name); name = validate_vcard_string(name); last_name = validate_vcard_string(last_name); first_name = validate_vcard_string(first_name); if (stream_out) { lbab_vcard_write_n(stream_out, address_out); wrote |= 1 << FIRST_NAME; } continue; } if (g_ascii_strncasecmp(string, "NICKNAME:", 9) == 0) { nick_name = g_strdup(string + 9); nick_name = validate_vcard_string(nick_name); if (stream_out) { lbab_vcard_write_nickname(stream_out, address_out); wrote |= 1 << NICK_NAME; } continue; } if (g_ascii_strncasecmp(string, "ORG:", 4) == 0) { org = g_strdup(string + 4); org = validate_vcard_string(org); if (stream_out) { lbab_vcard_write_org(stream_out, address_out); wrote |= 1 << ORGANIZATION; } continue; } /* * fetch all e-mail fields */ if (g_ascii_strncasecmp(string, "EMAIL", 5) == 0) { gchar *ptr = strchr(string + 5, ':'); if (ptr) { address_list = g_list_prepend(address_list, g_strdup(ptr + 1)); } continue; } /* * unknown line */ if (stream_out) lbab_vcard_write_unknown(stream_out, string); } return LBABERR_CANNOT_READ; }
static char *find_parameter(char *parameters, const char *key, int *retlen) { char *start, *p; int keylen = 0; int len = 0; if(!parameters || !*parameters || !key || strlen(key) == 0) /* we won't be able to find anything */ return NULL; keylen = (int) strlen(key); p = parameters; while (*p) { while ((*p) && g_ascii_isspace(*p)) p++; /* Skip white space */ if (g_ascii_strncasecmp(p, key, keylen) == 0) break; /* Skip to next parameter */ p = strchr(p, ';'); if (p == NULL) { return NULL; } p++; /* Skip semicolon */ } if (*p == 0x0) return NULL; /* key wasn't found */ start = p + keylen; if (start[0] == 0) { return NULL; } /* * Process the parameter value */ if (start[0] == '"') { /* * Parameter value is a quoted-string */ start++; /* Skip the quote */ len = index_of_char(start, '"'); if (len < 0) { /* * No closing quote */ return NULL; } } else { /* * Look for end of boundary */ p = start; while (*p) { if (*p == ';' || g_ascii_isspace(*p)) break; p++; len++; } } if(retlen) (*retlen) = len; return start; }
EXPORT bool_t str_has_prefix_nocase (const char * str, const char * prefix) { return ! g_ascii_strncasecmp (str, prefix, strlen (prefix)); }
BalsaMimeWidget * balsa_mime_widget_new(BalsaMessage * bm, LibBalsaMessageBody * mime_body, gpointer data) { BalsaMimeWidget *mw = NULL; gchar *content_type; mime_delegate_t *delegate; g_return_val_if_fail(bm != NULL, NULL); g_return_val_if_fail(mime_body != NULL, NULL); /* determine the content type of the passed MIME body */ content_type = libbalsa_message_body_get_mime_type(mime_body); delegate = mime_delegate; while (delegate->handler && ((delegate->wildcard && g_ascii_strncasecmp(delegate->mime_type, content_type, strlen(delegate->mime_type))) || (!delegate->wildcard && g_ascii_strcasecmp(delegate->mime_type, content_type)))) delegate++; if (delegate->handler) mw = (delegate->handler) (bm, mime_body, content_type, data); /* fall back to default if no handler is present */ if (!mw) mw = balsa_mime_widget_new_unknown(bm, mime_body, content_type); if (mw) { if (mw->widget) { g_signal_connect(G_OBJECT(mw->widget), "focus_in_event", G_CALLBACK(balsa_mime_widget_limit_focus), (gpointer) bm); g_signal_connect(G_OBJECT(mw->widget), "focus_out_event", G_CALLBACK(balsa_mime_widget_unlimit_focus), (gpointer) bm); #ifdef HAVE_GPGME if (mime_body->sig_info && g_ascii_strcasecmp("application/pgp-signature", content_type) && g_ascii_strcasecmp("application/pkcs7-signature", content_type) && g_ascii_strcasecmp("application/x-pkcs7-signature", content_type)) { GtkWidget * signature = balsa_mime_widget_signature_widget(mime_body, content_type); mw->widget = balsa_mime_widget_crypto_frame(mime_body, mw->widget, mime_body->was_encrypted, FALSE, signature); } else if (mime_body->was_encrypted && g_ascii_strcasecmp("multipart/signed", content_type)) { mw->widget = balsa_mime_widget_crypto_frame(mime_body, mw->widget, TRUE, TRUE, NULL); } #endif g_object_ref_sink(mw->widget); if (GTK_IS_LAYOUT(mw->widget)) { GtkAdjustment *vadj; g_object_get(G_OBJECT(mw->widget), "vadjustment", &vadj, NULL); g_signal_connect(vadj, "changed", G_CALLBACK(vadj_change_cb), mw->widget); } gtk_widget_show_all(mw->widget); } } g_free(content_type); return mw; }
static BalsaMimeWidget * balsa_mime_widget_new_unknown(BalsaMessage * bm, LibBalsaMessageBody * mime_body, const gchar * content_type) { GtkWidget *hbox; GtkWidget *button = NULL; gchar *msg; GtkWidget *msg_label; gchar *content_desc; BalsaMimeWidget *mw; gchar *use_content_type; g_return_val_if_fail(mime_body, NULL); mw = g_object_new(BALSA_TYPE_MIME_WIDGET, NULL); mw->widget = gtk_box_new(GTK_ORIENTATION_VERTICAL, BMW_VBOX_SPACE); gtk_container_set_border_width(GTK_CONTAINER(mw->widget), BMW_CONTAINER_BORDER); if (mime_body->filename) { msg = g_strdup_printf(_("File name: %s"), mime_body->filename); gtk_box_pack_start(GTK_BOX(mw->widget), gtk_label_new(msg), FALSE, FALSE, 0); g_free(msg); } /* guess content_type if not specified or if generic app/octet-stream */ /* on local mailboxes only, to avoid possibly long downloads */ if ((content_type == NULL || g_ascii_strcasecmp(content_type, "application/octet-stream") == 0) && LIBBALSA_IS_MAILBOX_LOCAL(mime_body->message->mailbox)) { GError *err = NULL; gpointer buffer; GMimeStream *stream = libbalsa_message_body_get_stream(mime_body, &err); if(!stream) { libbalsa_information(LIBBALSA_INFORMATION_ERROR, _("Error reading message part: %s"), err ? err->message : "Unknown error"); g_clear_error(&err); use_content_type = g_strdup(content_type); } else { ssize_t length = 1024 /* g_mime_stream_length(stream) */ ; ssize_t size; buffer = g_malloc(length); libbalsa_mime_stream_shared_lock(stream); size = g_mime_stream_read(stream, buffer, length); libbalsa_mime_stream_shared_unlock(stream); g_object_unref(stream); use_content_type = libbalsa_vfs_content_type_of_buffer(buffer, size); if (g_ascii_strncasecmp(use_content_type, "text", 4) == 0 && (libbalsa_text_attr_string(buffer) & LIBBALSA_TEXT_HI_BIT)) { /* Hmmm...better stick with application/octet-stream. */ g_free(use_content_type); use_content_type = g_strdup("application/octet-stream"); } g_free(buffer); } } else use_content_type = g_strdup(content_type); content_desc = libbalsa_vfs_content_description(use_content_type); if (content_desc) { msg = g_strdup_printf(_("Type: %s (%s)"), content_desc, use_content_type); g_free(content_desc); } else msg = g_strdup_printf(_("Content Type: %s"), use_content_type); msg_label = gtk_label_new(msg); g_free(msg); gtk_label_set_ellipsize(GTK_LABEL(msg_label), PANGO_ELLIPSIZE_END); gtk_box_pack_start(GTK_BOX(mw->widget), msg_label, FALSE, FALSE, 0); hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, BMW_HBOX_SPACE); gtk_box_set_homogeneous(GTK_BOX(hbox), TRUE); if ((button = libbalsa_vfs_mime_button(mime_body, use_content_type, G_CALLBACK(balsa_mime_widget_ctx_menu_cb), (gpointer) mime_body))) gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); else gtk_box_pack_start(GTK_BOX(mw->widget), gtk_label_new(_("No open or view action " "defined for this content type")), FALSE, FALSE, 0); g_free(use_content_type); button = gtk_button_new_with_mnemonic(_("S_ave part")); gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(balsa_mime_widget_ctx_menu_save), (gpointer) mime_body); gtk_box_pack_start(GTK_BOX(mw->widget), hbox, FALSE, FALSE, 0); return mw; }
GimpLayerModeEffects psd_to_gimp_blend_mode (const gchar *psd_mode) { if (g_ascii_strncasecmp (psd_mode, "norm", 4) == 0) /* Normal (ps3) */ return GIMP_NORMAL_MODE; if (g_ascii_strncasecmp (psd_mode, "dark", 4) == 0) /* Darken (ps3) */ return GIMP_DARKEN_ONLY_MODE; if (g_ascii_strncasecmp (psd_mode, "lite", 4) == 0) /* Lighten (ps3) */ return GIMP_LIGHTEN_ONLY_MODE; if (g_ascii_strncasecmp (psd_mode, "hue ", 4) == 0) /* Hue (ps3) */ return GIMP_HUE_MODE; if (g_ascii_strncasecmp (psd_mode, "sat ", 4) == 0) /* Saturation (ps3) */ { if (CONVERSION_WARNINGS) { static gchar *mode_name = "SATURATION"; g_message ("Gimp uses a different equation to photoshop for " "blend mode: %s. Results will differ.", mode_name); } return GIMP_SATURATION_MODE; } if (g_ascii_strncasecmp (psd_mode, "colr", 4) == 0) /* Color (ps3) */ return GIMP_COLOR_MODE; if (g_ascii_strncasecmp (psd_mode, "lum ", 4) == 0) /* Luminosity (ps3) */ { if (CONVERSION_WARNINGS) { static gchar *mode_name = "LUMINOSITY (VALUE)"; g_message ("Gimp uses a different equation to photoshop for " "blend mode: %s. Results will differ.", mode_name); } return GIMP_VALUE_MODE; } if (g_ascii_strncasecmp (psd_mode, "mul ", 4) == 0) /* Multiply (ps3) */ return GIMP_MULTIPLY_MODE; if (g_ascii_strncasecmp (psd_mode, "scrn", 4) == 0) /* Screen (ps3) */ return GIMP_SCREEN_MODE; if (g_ascii_strncasecmp (psd_mode, "diss", 4) == 0) /* Dissolve (ps3) */ return GIMP_DISSOLVE_MODE; if (g_ascii_strncasecmp (psd_mode, "over", 4) == 0) /* Overlay (ps3) */ { if (CONVERSION_WARNINGS) { static gchar *mode_name = "OVERLAY"; g_message ("Gimp uses a different equation to photoshop for " "blend mode: %s. Results will differ.", mode_name); } return GIMP_OVERLAY_MODE; } if (g_ascii_strncasecmp (psd_mode, "hLit", 4) == 0) /* Hard light (ps3) */ return GIMP_HARDLIGHT_MODE; if (g_ascii_strncasecmp (psd_mode, "sLit", 4) == 0) /* Soft light (ps3) */ { if (CONVERSION_WARNINGS) { static gchar *mode_name = "SOFT LIGHT"; g_message ("Gimp uses a different equation to photoshop for " "blend mode: %s. Results will differ.", mode_name); } return GIMP_SOFTLIGHT_MODE; } if (g_ascii_strncasecmp (psd_mode, "diff", 4) == 0) /* Difference (ps3) */ return GIMP_DIFFERENCE_MODE; if (g_ascii_strncasecmp (psd_mode, "smud", 4) == 0) /* Exclusion (ps6) */ { if (CONVERSION_WARNINGS) { static gchar *mode_name = "EXCLUSION"; g_message ("Unsupported blend mode: %s. Mode reverts to normal", mode_name); } return GIMP_NORMAL_MODE; } if (g_ascii_strncasecmp (psd_mode, "div ", 4) == 0) /* Color dodge (ps6) */ return GIMP_DODGE_MODE; if (g_ascii_strncasecmp (psd_mode, "idiv", 4) == 0) /* Color burn (ps6) */ return GIMP_BURN_MODE; if (g_ascii_strncasecmp (psd_mode, "lbrn", 4) == 0) /* Linear burn (ps7)*/ { if (CONVERSION_WARNINGS) { static gchar *mode_name = "LINEAR BURN"; g_message ("Unsupported blend mode: %s. Mode reverts to normal", mode_name); } return GIMP_NORMAL_MODE; } if (g_ascii_strncasecmp (psd_mode, "lddg", 4) == 0) /* Linear dodge (ps7)*/ return GIMP_ADDITION_MODE; if (g_ascii_strncasecmp (psd_mode, "lLit", 4) == 0) /* Linear light (ps7)*/ { if (CONVERSION_WARNINGS) { static gchar *mode_name = "LINEAR LIGHT"; g_message ("Unsupported blend mode: %s. Mode reverts to normal", mode_name); } return GIMP_NORMAL_MODE; } if (g_ascii_strncasecmp (psd_mode, "pLit", 4) == 0) /* Pin light (ps7)*/ { if (CONVERSION_WARNINGS) { static gchar *mode_name = "PIN LIGHT"; g_message ("Unsupported blend mode: %s. Mode reverts to normal", mode_name); } return GIMP_NORMAL_MODE; } if (g_ascii_strncasecmp (psd_mode, "vLit", 4) == 0) /* Vivid light (ps7)*/ { if (CONVERSION_WARNINGS) { static gchar *mode_name = "VIVID LIGHT"; g_message ("Unsupported blend mode: %s. Mode reverts to normal", mode_name); } return GIMP_NORMAL_MODE; } if (g_ascii_strncasecmp (psd_mode, "hMix", 4) == 0) /* Hard Mix (CS)*/ { if (CONVERSION_WARNINGS) { static gchar *mode_name = "HARD MIX"; g_message ("Unsupported blend mode: %s. Mode reverts to normal", mode_name); } return GIMP_NORMAL_MODE; } if (CONVERSION_WARNINGS) { gchar *mode_name = g_strndup (psd_mode, 4); g_message ("Unsupported blend mode: %s. Mode reverts to normal", mode_name); g_free (mode_name); } return GIMP_NORMAL_MODE; }
const gchar *get_conn_cfilter(void) { static GString *filter_str = NULL; gchar *env, **tokens; char *lastp, *lastc, *p; char *pprotocol = NULL; char *phostname = NULL; size_t hostlen; char *remip, *locip; if (filter_str == NULL) { filter_str = g_string_new(""); } if ((env = getenv("SSH_CONNECTION")) != NULL) { tokens = g_strsplit(env, " ", 4); if (tokens[3]) { remip = sanitize_filter_ip(tokens[0]); locip = sanitize_filter_ip(tokens[2]); g_string_printf(filter_str, "not (tcp port %s and %s host %s " "and tcp port %s and %s host %s)", tokens[1], host_ip_af(remip), remip, tokens[3], host_ip_af(locip), locip); g_free(remip); g_free(locip); return filter_str->str; } } else if ((env = getenv("SSH_CLIENT")) != NULL) { tokens = g_strsplit(env, " ", 3); remip = sanitize_filter_ip(tokens[2]); g_string_printf(filter_str, "not (tcp port %s and %s host %s " "and tcp port %s)", tokens[1], host_ip_af(remip), tokens[0], remip); g_free(remip); return filter_str->str; } else if ((env = getenv("REMOTEHOST")) != NULL) { /* FreeBSD 7.0 sets REMOTEHOST to an empty string */ if (g_ascii_strcasecmp(env, "localhost") == 0 || strcmp(env, "127.0.0.1") == 0 || strcmp(env, "") == 0) { return ""; } remip = sanitize_filter_ip(env); g_string_printf(filter_str, "not %s host %s", host_ip_af(remip), remip); g_free(remip); return filter_str->str; } else if ((env = getenv("DISPLAY")) != NULL) { /* * This mirrors what _X11TransConnectDisplay() does. * Note that, on some systems, the hostname can * begin with "/", which means that it's a pathname * of a UNIX domain socket to connect to. * * The comments mirror those in _X11TransConnectDisplay(), * too. :-) * * Display names may be of the following format: * * [protoco./] [hostname] : [:] displaynumber [.screennumber] * * A string with exactly two colons separating hostname * from the display indicates a DECnet style name. Colons * in the hostname may occur if an IPv6 numeric address * is used as the hostname. An IPv6 numeric address may * also end in a double colon, so three colons in a row * indicates an IPv6 address ending in :: followed by * :display. To make it easier for people to read, an * IPv6 numeric address hostname may be surrounded by [] * in a similar fashion to the IPv6 numeric address URL * syntax defined by IETF RFC 2732. * * If no hostname and no protocol is specified, the string * is interpreted as the most efficient local connection * to a server on the same machine. This is usually: * * o shared memory * o local stream * o UNIX domain socket * o TCP to local host. */ p = env; /* * Step 0, find the protocol. This is delimited by * the optional slash ('/'). */ for (lastp = p; *p != '\0' && *p != ':' && *p != '/'; p++) ; if (*p == '\0') return ""; /* must have a colon */ if (p != lastp && *p != ':') { /* protocol given? */ /* Yes */ pprotocol = p; /* Is it TCP? */ if (p - lastp != 3 || g_ascii_strncasecmp(lastp, "tcp", 3) != 0) return ""; /* not TCP */ p++; /* skip the '/' */ } else p = env; /* reset the pointer in case no protocol was given */ /* * Step 1, find the hostname. This is delimited either by * one colon, or two colons in the case of DECnet (DECnet * Phase V allows a single colon in the hostname). (See * note above regarding IPv6 numeric addresses with * triple colons or [] brackets.) */ lastp = p; lastc = NULL; for (; *p != '\0'; p++) if (*p == ':') lastc = p; if (lastc == NULL) return ""; /* must have a colon */ if ((lastp != lastc) && (*(lastc - 1) == ':') && (((lastc - 1) == lastp) || (*(lastc - 2) != ':'))) { /* DECnet display specified */ return ""; } else hostlen = lastc - lastp; if (hostlen == 0) return ""; /* no hostname supplied */ phostname = (char *)g_malloc(hostlen + 1); memcpy(phostname, lastp, hostlen); phostname[hostlen] = '\0'; if (pprotocol == NULL) { /* * No protocol was explicitly specified, so it * could be a local connection over a transport * that we won't see. * * Does the host name refer to the local host? * If so, the connection would probably be a * local connection. * * XXX - compare against our host name? * _X11TransConnectDisplay() does. */ if (g_ascii_strcasecmp(phostname, "localhost") == 0 || strcmp(phostname, "127.0.0.1") == 0) { g_free(phostname); return ""; } /* * A host name of "unix" (case-sensitive) also * causes a local connection. */ if (strcmp(phostname, "unix") == 0) { g_free(phostname); return ""; } /* * Does the host name begin with "/"? If so, * it's presumed to be the pathname of a * UNIX domain socket. */ if (phostname[0] == '/') { g_free(phostname); return ""; } } g_string_printf(filter_str, "not %s host %s", host_ip_af(phostname), phostname); g_free(phostname); return filter_str->str; #ifdef _WIN32 } else if (GetSystemMetrics(SM_REMOTESESSION)) { /* We have a remote session: http://msdn.microsoft.com/en-us/library/aa380798%28VS.85%29.aspx */ g_string_printf(filter_str, "not tcp port 3389"); return filter_str->str; #endif /* _WIN32 */ } return ""; }
/* * Parse one address from the input stream; if an output stream is * given, create an item on it for the output address. */ static LibBalsaABErr libbalsa_address_book_ldif_parse_address(FILE * stream, LibBalsaAddress * address, FILE * stream_out, LibBalsaAddress * address_out) { gchar *line; gchar *surname = NULL, *givenname = NULL, *nickname = NULL, *fullname = NULL, *organization = NULL; gint in_ldif = FALSE; GList *address_list = NULL; guint wrote = 0; for (; (line=read_line(stream)) != NULL || in_ldif; g_free(line) ) { if (line) { /* * Check if it is a card. */ if (g_ascii_strncasecmp(line, "dn:", 3) == 0) { in_ldif = TRUE; if (stream_out) lbab_ldif_write_dn(stream_out, address_out); continue; } if (!in_ldif) { if (stream_out && *line) fprintf(stream_out, "%s\n", line); continue; } g_strchomp(line); } if (!line || line[0] == '\0') { LibBalsaABErr res = LBABERR_CANNOT_READ; /* * We are done loading a card. */ if (address_list) { if (stream_out) { if (!(wrote & (1 << LAST_NAME))) lbab_ldif_write_surname(stream_out, address_out); if (!(wrote & (1 << FIRST_NAME))) lbab_ldif_write_givenname(stream_out, address_out); if (!(wrote & (1 << NICK_NAME))) lbab_ldif_write_nickname(stream_out, address_out); if (!(wrote & (1 << ORGANIZATION))) lbab_ldif_write_organization(stream_out, address_out); lbab_ldif_write_addresses(stream_out, address_out); res = fprintf(stream_out, "\n") < 0 ? LBABERR_CANNOT_WRITE : LBABERR_OK; } if (address) { address_new_prefill(address, g_list_reverse(address_list), nickname, givenname, surname, fullname, organization); g_free(line); return LBABERR_OK; } g_list_foreach(address_list, (GFunc) g_free, NULL); g_list_free(address_list); } /* Record without e-mail address, or we're not creating * addresses: free memory. */ g_free(fullname); g_free(nickname); g_free(givenname); g_free(surname); g_free(organization); g_free(line); return res; } if (g_ascii_strncasecmp(line, "cn:", 3) == 0) { fullname = value_spec_to_string(g_strchug(line + 3)); continue; } if (g_ascii_strncasecmp(line, "sn:", 3) == 0) { surname = value_spec_to_string(g_strchug(line + 3)); if (stream_out) { lbab_ldif_write_surname(stream_out, address_out); wrote |= 1 << LAST_NAME; } continue; } if (g_ascii_strncasecmp(line, "givenname:", 10) == 0) { givenname = value_spec_to_string(g_strchug(line + 10)); if (stream_out) { lbab_ldif_write_givenname(stream_out, address_out); wrote |= 1 << FIRST_NAME; } continue; } if (g_ascii_strncasecmp(line, "xmozillanickname:", 17) == 0) { nickname = value_spec_to_string(g_strchug(line + 17)); if (stream_out) { lbab_ldif_write_nickname(stream_out, address_out); wrote |= 1 << NICK_NAME; } continue; } if (g_ascii_strncasecmp(line, "o:", 2) == 0) { organization = value_spec_to_string(g_strchug(line + 2)); if (stream_out) { lbab_ldif_write_organization(stream_out, address_out); wrote |= 1 << ORGANIZATION; } continue; } if (g_ascii_strncasecmp(line, "member:", 7) == 0) { address_list = g_list_prepend(address_list, member_value_to_mail(g_strchug(line + 7))); continue; } /* * fetch all e-mail fields */ if (g_ascii_strncasecmp(line, "mail:", 5) == 0) { address_list = g_list_prepend(address_list, value_spec_to_string(g_strchug(line + 5))); continue; } /* * unknown line */ if (stream_out && *line) fprintf(stream_out, "%s\n", line); } return LBABERR_CANNOT_READ; }
/** * playlist_parser_scan_uri * @parser: A #PlaylistParser * @uri: An URI * @error: Location where to store a #GError if an error occurs. * * Parse @uri. * * Return value: TRUE on success, FALSE if an error occured in which case * @error is set as well. **/ gboolean playlist_parser_parse (PlaylistParser *parser, const char *uri, GError **error) { char *ext, *filename, *dirname; GIOChannel *channel; g_return_val_if_fail (IS_PLAYLIST_PARSER (parser), FALSE); g_return_val_if_fail (uri != NULL, FALSE); /** * Does @uri point to a M3U file? **/ ext = strrchr (uri, '.'); if (!ext || g_ascii_strcasecmp (ext, ".m3u")) { g_set_error (error, PLAYLIST_PARSER_ERROR, PLAYLIST_PARSER_ERROR_UNKNOWN_TYPE, "Unknown type"); return FALSE; } /** * Does @uri point to a local file? **/ if (g_ascii_strncasecmp (uri, "file:", 5)) { g_set_error (error, PLAYLIST_PARSER_ERROR, PLAYLIST_PARSER_ERROR_UNSUPPORTED_SCHEME, "Unsupported scheme in URI '%s'", uri); return FALSE; } /** * Convert @uri to a filename. **/ filename = g_filename_from_uri (uri, NULL, error); if (!filename) return FALSE; /** * Open @filename for reading. **/ channel = g_io_channel_new_file (filename, "r", error); if (!channel) { g_free (filename); return FALSE; } /** * Pass channel to parser. **/ dirname = g_path_get_dirname (filename); parse_m3u (parser, channel, dirname); g_free (dirname); /** * Cleanup. **/ g_io_channel_unref (channel); g_free (filename); return TRUE; }
gint read_diffax(gchar *filename, struct model_pak *model) { gint num_tokens, num_layer, tot_layer; gdouble offset; gchar **buff; GSList *list1, *list2; struct core_pak *core; struct layer_pak *layer; FILE *fp; /* checks */ g_return_val_if_fail(model != NULL, 1); g_return_val_if_fail(filename != NULL, 2); fp = fopen(filename, "rt"); if (!fp) return(3); /* setup */ model->id = DIFFAX_INP; model->fractional = TRUE; model->periodic = 3; model->colour_scheme = REGION; strcpy(model->filename, filename); g_free(model->basename); model->basename = parse_strip(filename); /* scan the file */ while ((buff = get_tokenized_line(fp, &num_tokens))) { diffax_keyword_search:; /* restricted unit cell */ if (g_ascii_strncasecmp("structural", *buff, 10) == 0) { g_strfreev(buff); buff = get_tokenized_line(fp, &num_tokens); if (num_tokens > 3) { model->pbc[0] = str_to_float(*(buff+0)); model->pbc[1] = str_to_float(*(buff+1)); model->pbc[2] = str_to_float(*(buff+2)); model->pbc[3] = PI/2.0; model->pbc[4] = PI/2.0; model->pbc[5] = D2R*str_to_float(*(buff+3)); } } /* layer testing */ if (g_ascii_strncasecmp("layer", *buff, 5) == 0) { layer = g_malloc(sizeof(struct model_pak)); layer->width = 1.0; VEC3SET(layer->centroid, 0.5, 0.5, 0.5); layer->cores = NULL; model->layer_list = g_slist_prepend(model->layer_list, layer); g_strfreev(buff); buff = get_tokenized_line(fp, &num_tokens); if (buff) { /* TODO - if centrosymmetric : add a -1 operation */ } /* get layer data */ g_strfreev(buff); buff = get_tokenized_line(fp, &num_tokens); while (buff) { if (elem_symbol_test(*buff)) { if (num_tokens > 6) { /* printf("[%s] [%s %s %s]\n", *buff, *(buff+2), *(buff+3), *(buff+4)); */ core = new_core(*buff, model); model->cores = g_slist_prepend(model->cores, core); layer->cores = g_slist_prepend(layer->cores, core); core->x[0] = str_to_float(*(buff+2)); core->x[1] = str_to_float(*(buff+3)); core->x[2] = str_to_float(*(buff+4)); core->sof = str_to_float(*(buff+5)); } } else goto diffax_keyword_search; /* get next line of tokens */ g_strfreev(buff); buff = get_tokenized_line(fp, &num_tokens); } } g_strfreev(buff); } /* TODO - enumerate layers and scale, so they are stacked 1..n in a single cell */ /* also label the layers as different region types */ model->layer_list = g_slist_reverse(model->layer_list); num_layer = 0; tot_layer = g_slist_length(model->layer_list); model->pbc[2] *= tot_layer; #if DEBUG_READ_DIFFAX printf("Read in %d layers.\n", tot_layer); #endif for (list1=model->layer_list ; list1 ; list1=g_slist_next(list1)) { layer = (struct layer_pak *) list1->data; layer->width = 1.0 / (gdouble) tot_layer; offset = (gdouble) num_layer * layer->width; VEC3SET(layer->centroid, 0.0, 0.0, offset); for (list2=layer->cores ; list2 ; list2=g_slist_next(list2)) { core = (struct core_pak *) list2->data; /* scale to within the big cell (encloses all DIFFAX layers) */ core->x[2] *= layer->width; /* offset each particular layer */ core->x[2] += offset; core->region = num_layer; } num_layer++; } /* end of read */ fclose(fp); /* post read setup */ model->cores = g_slist_reverse(model->cores); model_prep(model); return(0); }
static gboolean xmms_cue_browse (xmms_xform_t *xform, const gchar *url, xmms_error_t *error) { gchar line[XMMS_XFORM_MAX_LINE_SIZE]; cue_track track; gchar *p; g_return_val_if_fail (xform, FALSE); memset (&track, 0, sizeof (cue_track)); if (!xmms_xform_read_line (xform, line, error)) { xmms_error_set (error, XMMS_ERROR_INVAL, "error reading cue-file!"); return FALSE; } do { p = skip_white_space (line); if (g_ascii_strncasecmp (p, "FILE", 4) == 0) { if (track.file[0]) { add_track (xform, &track); } p = skip_to_char (p, '"'); p ++; save_to_char (p, '"', track.file); } else if (g_ascii_strncasecmp (p, "TRACK", 5) == 0) { p = skip_to_char (p, ' '); p = skip_white_space (p); p = skip_to_char (p, ' '); p = skip_white_space (p); if (g_ascii_strncasecmp (p, "AUDIO", 5) == 0) { cue_track *t = g_new0 (cue_track, 1); track.tracks = g_list_prepend (track.tracks, t); } } else if (g_ascii_strncasecmp (p, "INDEX", 5) == 0) { cue_track *t = g_list_nth_data (track.tracks, 0); if (!t) { continue; } p = skip_to_char (p, ' '); p = skip_white_space (p); p = skip_to_char (p, ' '); p = skip_white_space (p); add_index (t, p); } else if (g_ascii_strncasecmp (p, "TITLE", 5) == 0) { cue_track *t = g_list_nth_data (track.tracks, 0); p = skip_to_char (p, '"'); p ++; if (!t) { save_to_char (p, '"', track.album); } else { save_to_char (p, '"', t->title); } } else if (g_ascii_strncasecmp (p, "PERFORMER", 9) == 0) { cue_track *t = g_list_nth_data (track.tracks, 0); p = skip_to_char (p, '"'); p ++; if (!t) { save_to_char (p, '"', track.artist); } else { save_to_char (p, '"', t->artist); } } } while (xmms_xform_read_line (xform, line, error)); if (track.file[0]) { add_track (xform, &track); } xmms_error_reset (error); return TRUE; }
void ctcp_handle (session *sess, char *to, char *nick, char *ip, char *msg, char *word[], char *word_eol[], int id, const message_tags_data *tags_data) { char *po; session *chansess; server *serv = sess->server; char outbuf[1024]; int ctcp_offset = 2; if (serv->have_idmsg && (word[4][1] == '+' || word[4][1] == '-') ) ctcp_offset = 3; /* consider DCC to be different from other CTCPs */ if (!g_ascii_strncasecmp (msg, "DCC", 3)) { /* but still let CTCP replies override it */ if (!ctcp_check (sess, nick, word, word_eol, word[4] + ctcp_offset)) { if (!ignore_check (word[1], IG_DCC)) handle_dcc (sess, nick, word, word_eol, tags_data); } return; } /* consider ACTION to be different from other CTCPs. Check ignore as if it was a PRIV/CHAN. */ if (!g_ascii_strncasecmp (msg, "ACTION ", 7)) { if (is_channel (serv, to)) { /* treat a channel action as a CHAN */ if (ignore_check (word[1], IG_CHAN)) return; } else { /* treat a private action as a PRIV */ if (ignore_check (word[1], IG_PRIV)) return; } /* but still let CTCP replies override it */ if (ctcp_check (sess, nick, word, word_eol, word[4] + ctcp_offset)) goto generic; inbound_action (sess, to, nick, ip, msg + 7, FALSE, id, tags_data); return; } if (ignore_check (word[1], IG_CTCP)) return; if (!g_ascii_strcasecmp (msg, "VERSION") && !prefs.hex_irc_hide_version) { #ifdef WIN32 g_snprintf (outbuf, sizeof (outbuf), "VERSION HexChat "PACKAGE_VERSION" [x%d] / %s", get_cpu_arch (), get_sys_str (1)); #else g_snprintf (outbuf, sizeof (outbuf), "VERSION HexChat "PACKAGE_VERSION" / %s", get_sys_str (1)); #endif serv->p_nctcp (serv, nick, outbuf); } if (word[4][1] == '\0') return; if (!ctcp_check (sess, nick, word, word_eol, word[4] + ctcp_offset)) { if (!g_ascii_strncasecmp (msg, "SOUND", 5)) { po = strchr (word[5], '\001'); if (po) po[0] = 0; if (is_channel (sess->server, to)) { chansess = find_channel (sess->server, to); if (!chansess) chansess = sess; EMIT_SIGNAL_TIMESTAMP (XP_TE_CTCPSNDC, chansess, word[5], nick, to, NULL, 0, tags_data->timestamp); } else { EMIT_SIGNAL_TIMESTAMP (XP_TE_CTCPSND, sess->server->front_session, word[5], nick, NULL, NULL, 0, tags_data->timestamp); } /* don't let IRCers specify path */ #ifdef WIN32 if (strchr (word[5], '/') == NULL && strchr (word[5], '\\') == NULL) #else if (strchr (word[5], '/') == NULL) #endif sound_play (word[5], TRUE); return; } } generic: po = strchr (msg, '\001'); if (po) po[0] = 0; if (!is_channel (sess->server, to)) { EMIT_SIGNAL_TIMESTAMP (XP_TE_CTCPGEN, sess->server->front_session, msg, nick, NULL, NULL, 0, tags_data->timestamp); } else { chansess = find_channel (sess->server, to); if (!chansess) chansess = sess; EMIT_SIGNAL_TIMESTAMP (XP_TE_CTCPGENC, chansess, msg, nick, to, NULL, 0, tags_data->timestamp); } }
gint regexp_module_config (struct rspamd_config *cfg) { struct regexp_module_item *cur_item; const ucl_object_t *sec, *value, *elt; ucl_object_iter_t it = NULL; gint res = TRUE, id; if (!rspamd_config_is_module_enabled (cfg, "regexp")) { return TRUE; } sec = ucl_object_find_key (cfg->rcl_obj, "regexp"); if (sec == NULL) { msg_err_config ("regexp module enabled, but no rules are defined"); return TRUE; } regexp_module_ctx->max_size = 0; while ((value = ucl_iterate_object (sec, &it, true)) != NULL) { if (g_ascii_strncasecmp (ucl_object_key (value), "max_size", sizeof ("max_size") - 1) == 0) { regexp_module_ctx->max_size = ucl_obj_toint (value); rspamd_mime_expression_set_re_limit (regexp_module_ctx->max_size); } else if (g_ascii_strncasecmp (ucl_object_key (value), "max_threads", sizeof ("max_threads") - 1) == 0) { msg_warn_config ("regexp module is now single threaded, max_threads is ignored"); } else if (value->type == UCL_STRING) { cur_item = rspamd_mempool_alloc0 (regexp_module_ctx->regexp_pool, sizeof (struct regexp_module_item)); cur_item->symbol = ucl_object_key (value); if (!read_regexp_expression (regexp_module_ctx->regexp_pool, cur_item, ucl_object_key (value), ucl_obj_tostring (value), cfg)) { res = FALSE; } else { rspamd_symbols_cache_add_symbol (cfg->cache, cur_item->symbol, 0, process_regexp_item, cur_item, SYMBOL_TYPE_NORMAL, -1); } } else if (value->type == UCL_USERDATA) { /* Just a lua function */ cur_item = rspamd_mempool_alloc0 (regexp_module_ctx->regexp_pool, sizeof (struct regexp_module_item)); cur_item->symbol = ucl_object_key (value); cur_item->lua_function = ucl_object_toclosure (value); rspamd_symbols_cache_add_symbol (cfg->cache, cur_item->symbol, 0, process_regexp_item, cur_item, SYMBOL_TYPE_NORMAL, -1); } else if (value->type == UCL_OBJECT) { const gchar *description = NULL, *group = NULL, *metric = DEFAULT_METRIC; gdouble score = 0.0; gboolean one_shot = FALSE, is_lua = FALSE, valid_expression = TRUE; /* We have some lua table, extract its arguments */ elt = ucl_object_find_key (value, "callback"); if (elt == NULL || elt->type != UCL_USERDATA) { /* Try plain regexp expression */ elt = ucl_object_find_any_key (value, "regexp", "re", NULL); if (elt != NULL && ucl_object_type (elt) == UCL_STRING) { cur_item = rspamd_mempool_alloc0 (regexp_module_ctx->regexp_pool, sizeof (struct regexp_module_item)); cur_item->symbol = ucl_object_key (value); if (!read_regexp_expression (regexp_module_ctx->regexp_pool, cur_item, ucl_object_key (value), ucl_obj_tostring (elt), cfg)) { res = FALSE; } else { valid_expression = TRUE; } } else { msg_err_config ( "no callback/expression defined for regexp symbol: " "%s", ucl_object_key (value)); } } else { is_lua = TRUE; cur_item = rspamd_mempool_alloc0 ( regexp_module_ctx->regexp_pool, sizeof (struct regexp_module_item)); cur_item->symbol = ucl_object_key (value); cur_item->lua_function = ucl_object_toclosure (value); } if (cur_item && (is_lua || valid_expression)) { id = rspamd_symbols_cache_add_symbol (cfg->cache, cur_item->symbol, 0, process_regexp_item, cur_item, SYMBOL_TYPE_NORMAL, -1); elt = ucl_object_find_key (value, "condition"); if (elt != NULL && ucl_object_type (elt) == UCL_USERDATA) { struct ucl_lua_funcdata *conddata; conddata = ucl_object_toclosure (elt); rspamd_symbols_cache_add_condition (cfg->cache, id, conddata->L, conddata->idx); } elt = ucl_object_find_key (value, "metric"); if (elt) { metric = ucl_object_tostring (elt); } elt = ucl_object_find_key (value, "description"); if (elt) { description = ucl_object_tostring (elt); } elt = ucl_object_find_key (value, "group"); if (elt) { group = ucl_object_tostring (elt); } elt = ucl_object_find_key (value, "score"); if (elt) { score = ucl_object_todouble (elt); } elt = ucl_object_find_key (value, "one_shot"); if (elt) { one_shot = ucl_object_toboolean (elt); } rspamd_config_add_metric_symbol (cfg, metric, cur_item->symbol, score, description, group, one_shot, FALSE); } } else { msg_warn_config ("unknown type of attribute %s for regexp module", ucl_object_key (value)); } } return res; }
bool xplayerGMPControls::InvokeByIndex (int aIndex, const NPVariant *argv, uint32_t argc, NPVariant *_result) { XPLAYER_LOG_INVOKE (aIndex, xplayerGMPControls); switch (Methods (aIndex)) { case ePause: /* void pause (); */ Plugin()->Command (XPLAYER_COMMAND_PAUSE); return VoidVariant (_result); case ePlay: /* void play (); */ Plugin()->Command (XPLAYER_COMMAND_PLAY); return VoidVariant (_result); case eStop: /* void stop (); */ Plugin()->Command (XPLAYER_COMMAND_PAUSE); return VoidVariant (_result); case eGetAudioLanguageDescription: /* AUTF8String getAudioLanguageDescription (in long index); */ XPLAYER_WARN_1_INVOKE_UNIMPLEMENTED (aIndex,xplayerGMPControls); return StringVariant (_result, "English"); case eGetLanguageName: /* AUTF8String getLanguageName (in long LCID); */ XPLAYER_WARN_1_INVOKE_UNIMPLEMENTED (aIndex,xplayerGMPControls); return StringVariant (_result, "English"); case eIsAvailable: /* boolean isAvailable (in ACString name); */ NPString name; if (!GetNPStringFromArguments (argv, argc, 0, name)) return false; if (g_ascii_strncasecmp (name.UTF8Characters, "currentItem", name.UTF8Length) == 0 || g_ascii_strncasecmp (name.UTF8Characters, "next", name.UTF8Length) == 0 || g_ascii_strncasecmp (name.UTF8Characters, "pause", name.UTF8Length) == 0 || g_ascii_strncasecmp (name.UTF8Characters, "play", name.UTF8Length) == 0 || g_ascii_strncasecmp (name.UTF8Characters, "previous", name.UTF8Length) == 0 || g_ascii_strncasecmp (name.UTF8Characters, "stop", name.UTF8Length) == 0) return BoolVariant (_result, true); return BoolVariant (_result, false); case eFastForward: /* void fastForward (); */ case eFastReverse: /* void fastReverse (); */ case eGetAudioLanguageID: /* long getAudioLanguageID (in long index); */ case eNext: /* void next (); */ case ePlayItem: /* void playItem (in xplayerIGMPMedia theMediaItem); */ case ePrevious: /* void previous (); */ case eStep: /* void step (in long frameCount); */ XPLAYER_WARN_INVOKE_UNIMPLEMENTED (aIndex,xplayerGMPControls); return VoidVariant (_result); } return false; }
/* * Process a multipart body-part: * MIME-part-headers [ line-end *OCTET ] * line-end dashed-boundary transport-padding line-end * * If applicable, call a media subdissector. * * Return the offset to the start of the next body-part. */ static gint process_body_part(proto_tree *tree, tvbuff_t *tvb, multipart_info_t *m_info, packet_info *pinfo, gint start, gint idx, gboolean *last_boundary) { proto_tree *subtree; proto_item *ti; gint offset = start, next_offset = 0; char *parameters = NULL; gint body_start, boundary_start, boundary_line_len; gchar *content_type_str = NULL; gchar *content_encoding_str = NULL; char *filename = NULL; char *mimetypename = NULL; int len = 0; gboolean last_field = FALSE; gboolean is_raw_data = FALSE; const guint8 *boundary = (guint8 *)m_info->boundary; gint boundary_len = m_info->boundary_length; ti = proto_tree_add_item(tree, hf_multipart_part, tvb, start, 0, ENC_ASCII|ENC_NA); subtree = proto_item_add_subtree(ti, ett_multipart_body); /* find the next boundary to find the end of this body part */ boundary_start = find_next_boundary(tvb, offset, boundary, boundary_len, &boundary_line_len, last_boundary); if (boundary_start <= 0) { return -1; } /* * Process the MIME-part-headers */ while (!last_field) { gint colon_offset; char *hdr_str; char *header_str; /* Look for the end of the header (denoted by cr) * 3:d argument to imf_find_field_end() maxlen; must be last offset in the tvb. */ next_offset = imf_find_field_end(tvb, offset, tvb_reported_length_remaining(tvb, offset)+offset, &last_field); /* the following should never happen */ /* If cr not found, won't have advanced - get out to avoid infinite loop! */ /* if (next_offset == offset) { break; } */ if (last_field && (next_offset+2) <= boundary_start) { /* Add the extra CRLF of the last field */ next_offset += 2; } else if((next_offset-2) == boundary_start) { /* if CRLF is the start of next boundary it belongs to the boundary and not the field, so it's the last field without CRLF */ last_field = TRUE; next_offset -= 2; } else if (next_offset > boundary_start) { /* if there is no CRLF between last field and next boundary - trim it! */ next_offset = boundary_start; } hdr_str = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, next_offset - offset, ENC_ASCII); header_str = unfold_and_compact_mime_header(hdr_str, &colon_offset); if (colon_offset <= 0) { /* if there is no colon it's no header, so break and add complete line to the body */ next_offset = offset; break; } else { gint hf_index; /* Split header name from header value */ header_str[colon_offset] = '\0'; hf_index = is_known_multipart_header(header_str, colon_offset); if (hf_index == -1) { if(isprint_string(hdr_str)) { proto_tree_add_format_text(subtree, tvb, offset, next_offset - offset); } else { /* if the header name is unkown and not printable, break and add complete line to the body */ next_offset = offset; break; } } else { char *value_str = header_str + colon_offset + 1; proto_tree_add_string_format(subtree, hf_header_array[hf_index], tvb, offset, next_offset - offset, (const char *)value_str, "%s", tvb_format_text(tvb, offset, next_offset - offset)); switch (hf_index) { case POS_ORIGINALCONTENT: { gint semicolon_offset; /* The Content-Type starts at colon_offset + 1 or after the type parameter */ char* type_str = find_parameter(value_str, "type=", NULL); if(type_str != NULL) { value_str = type_str; } semicolon_offset = index_of_char( value_str, ';'); if (semicolon_offset > 0) { value_str[semicolon_offset] = '\0'; m_info->orig_parameters = wmem_strdup(wmem_packet_scope(), value_str + semicolon_offset + 1); } m_info->orig_content_type = wmem_ascii_strdown(wmem_packet_scope(), value_str, -1); } break; case POS_CONTENT_TYPE: { /* The Content-Type starts at colon_offset + 1 */ gint semicolon_offset = index_of_char( value_str, ';'); if (semicolon_offset > 0) { value_str[semicolon_offset] = '\0'; parameters = wmem_strdup(wmem_packet_scope(), value_str + semicolon_offset + 1); } else { parameters = NULL; } content_type_str = wmem_ascii_strdown(wmem_packet_scope(), value_str, -1); /* Show content-type in root 'part' label */ proto_item_append_text(ti, " (%s)", content_type_str); /* find the "name" parameter in case we don't find a content disposition "filename" */ if((mimetypename = find_parameter(parameters, "name=", &len)) != NULL) { mimetypename = g_strndup(mimetypename, len); } if(strncmp(content_type_str, "application/octet-stream", sizeof("application/octet-stream")-1) == 0) { is_raw_data = TRUE; } /* there are only 2 body parts possible and each part has specific content types */ if(m_info->protocol && idx == 0 && (is_raw_data || g_ascii_strncasecmp(content_type_str, m_info->protocol, strlen(m_info->protocol)) != 0)) { return -1; } } break; case POS_CONTENT_TRANSFER_ENCODING: { /* The Content-Transferring starts at colon_offset + 1 */ gint cr_offset = index_of_char(value_str, '\r'); if (cr_offset > 0) { value_str[cr_offset] = '\0'; } content_encoding_str = wmem_ascii_strdown(wmem_packet_scope(), value_str, -1); } break; case POS_CONTENT_DISPOSITION: { /* find the "filename" parameter */ if((filename = find_parameter(value_str, "filename=", &len)) != NULL) { filename = g_strndup(filename, len); } } break; default: break; } } } offset = next_offset; } body_start = next_offset; /* * Process the body */ { gint body_len = boundary_start - body_start; tvbuff_t *tmp_tvb = tvb_new_subset_length(tvb, body_start, body_len); /* if multipart subtype is encrypted the protcol string was set */ /* see: https://msdn.microsoft.com/en-us/library/cc251581.aspx */ /* there are only 2 body parts possible and each part has specific content types */ if(m_info->protocol && idx == 1 && is_raw_data) { gssapi_encrypt_info_t encrypt; memset(&encrypt, 0, sizeof(encrypt)); encrypt.decrypt_gssapi_tvb=DECRYPT_GSSAPI_NORMAL; dissect_kerberos_encrypted_message(tmp_tvb, pinfo, subtree, &encrypt); if(encrypt.gssapi_decrypted_tvb) { tmp_tvb = encrypt.gssapi_decrypted_tvb; is_raw_data = FALSE; content_type_str = m_info->orig_content_type; parameters = m_info->orig_parameters; } else if(encrypt.gssapi_encrypted_tvb) { tmp_tvb = encrypt.gssapi_encrypted_tvb; proto_tree_add_expert(tree, pinfo, &ei_multipart_decryption_not_possible, tmp_tvb, 0, -1); } } if (!is_raw_data && content_type_str) { /* * subdissection */ gboolean dissected; /* * Try and remove any content transfer encoding so that each sub-dissector * doesn't have to do it itself * */ if(content_encoding_str && remove_base64_encoding) { if(!g_ascii_strncasecmp(content_encoding_str, "base64", 6)) tmp_tvb = base64_decode(pinfo, tmp_tvb, filename ? filename : (mimetypename ? mimetypename : content_type_str)); } /* * First try the dedicated multipart dissector table */ dissected = dissector_try_string(multipart_media_subdissector_table, content_type_str, tmp_tvb, pinfo, subtree, parameters); if (! dissected) { /* * Fall back to the default media dissector table */ dissected = dissector_try_string(media_type_dissector_table, content_type_str, tmp_tvb, pinfo, subtree, parameters); } if (! dissected) { const char *save_match_string = pinfo->match_string; pinfo->match_string = content_type_str; call_dissector_with_data(media_handle, tmp_tvb, pinfo, subtree, parameters); pinfo->match_string = save_match_string; } parameters = NULL; /* Shares same memory as content_type_str */ } else { call_dissector(data_handle, tmp_tvb, pinfo, subtree); } proto_item_set_len(ti, boundary_start - start); if (*last_boundary == TRUE) { proto_tree_add_item(tree, hf_multipart_last_boundary, tvb, boundary_start, boundary_line_len, ENC_NA|ENC_ASCII); } else { proto_tree_add_item(tree, hf_multipart_boundary, tvb, boundary_start, boundary_line_len, ENC_NA|ENC_ASCII); } g_free(filename); g_free(mimetypename); return boundary_start + boundary_line_len; } }
/** * camel_url_new_with_base: * @base: a base URL * @url_string: the URL * * Parses @url_string relative to @base. * * Returns: a parsed #CamelURL **/ CamelURL * camel_url_new_with_base (CamelURL *base, const gchar *url_string) { CamelURL *url; const gchar *end, *hash, *colon, *semi, *at, *slash, *question; const gchar *p; #ifdef G_OS_WIN32 const gchar *start = url_string; #endif g_return_val_if_fail (url_string != NULL, NULL); url = g_new0 (CamelURL, 1); /* See RFC1808 for details. IF YOU CHANGE ANYTHING IN THIS * FUNCTION, RUN tests/misc/url AFTERWARDS. */ /* Find fragment. RFC 1808 2.4.1 */ end = hash = strchr (url_string, '#'); if (hash) { if (hash[1]) { url->fragment = g_strdup (hash + 1); camel_url_decode (url->fragment); } } else end = url_string + strlen (url_string); /* Find protocol: initial [a-z+.-]* substring until ":" */ p = url_string; while (p < end && (isalnum ((guchar) * p) || *p == '.' || *p == '+' || *p == '-')) p++; if (p > url_string && *p == ':') { url->protocol = g_strndup (url_string, p - url_string); camel_strdown (url->protocol); url_string = p + 1; } if (!*url_string && !base) return url; #ifdef G_OS_WIN32 if (url->protocol && !strcmp (url->protocol, "file")) { url->path = g_filename_from_uri (start, &url->host, NULL); return url; } #endif /* Check for authority */ if (strncmp (url_string, "//", 2) == 0) { url_string += 2; slash = url_string + strcspn (url_string, "/#"); at = strchr (url_string, '@'); if (at && at < slash) { colon = strchr (url_string, ':'); if (colon && colon < at) { /* XXX We used to extract and store the * password here, now we just eat it. */ } else { colon = at; } semi = strchr (url_string, ';'); if (semi && semi < colon && !g_ascii_strncasecmp (semi, ";auth=", 6)) { url->authmech = g_strndup ( semi + 6, colon - semi - 6); camel_url_decode (url->authmech); } else { url->authmech = NULL; semi = colon; } url->user = g_strndup (url_string, semi - url_string); camel_url_decode (url->user); url_string = at + 1; } else url->user = url->authmech = NULL; /* Find host and port. */ colon = strchr (url_string, ':'); if (colon && colon < slash) { url->host = g_strndup (url_string, colon - url_string); url->port = strtoul (colon + 1, NULL, 10); } else { url->host = g_strndup (url_string, slash - url_string); camel_url_decode (url->host); url->port = 0; } url_string = slash; } /* Find query */ question = memchr (url_string, '?', end - url_string); if (question) { if (question[1]) { url->query = g_strndup ( question + 1, end - (question + 1)); camel_url_decode (url->query); } end = question; } /* Find parameters */ semi = memchr (url_string, ';', end - url_string); if (semi) { if (semi[1]) { const gchar *cur, *p, *eq; gchar *name, *value; for (cur = semi + 1; cur < end; cur = p + 1) { p = memchr (cur, ';', end - cur); if (!p) p = end; eq = memchr (cur, '=', p - cur); if (eq) { name = g_strndup (cur, eq - cur); value = g_strndup (eq + 1, p - (eq + 1)); camel_url_decode (value); } else { name = g_strndup (cur, p - cur); value = g_strdup (""); } camel_url_decode (name); g_datalist_set_data_full ( &url->params, name, value, g_free); g_free (name); } } end = semi; } if (end != url_string) { url->path = g_strndup (url_string, end - url_string); camel_url_decode (url->path); } /* Apply base URL. Again, this is spelled out in RFC 1808. */ if (base && !url->protocol && url->host) url->protocol = g_strdup (base->protocol); else if (base && !url->protocol) { if (!url->user && !url->authmech && !url->host && !url->port && !url->path && !url->params && !url->query && !url->fragment) url->fragment = g_strdup (base->fragment); url->protocol = g_strdup (base->protocol); url->user = g_strdup (base->user); url->authmech = g_strdup (base->authmech); url->host = g_strdup (base->host); url->port = base->port; if (!url->path) { url->path = g_strdup (base->path); if (!url->params) { g_datalist_foreach (&base->params, copy_param, &url->params); if (!url->query) url->query = g_strdup (base->query); } } else if (*url->path != '/') { gchar *newpath, *last, *p, *q; /* the base->path is NULL if given Content-Base url was without last slash, * i.e. like "http://example.com" (this expected only "http://example.com/") */ last = base->path ? strrchr (base->path, '/') : NULL; if (last) { newpath = g_strdup_printf ( "%.*s/%s", (gint)(last - base->path), base->path, url->path); } else newpath = g_strdup_printf ("/%s", url->path); /* Remove "./" where "." is a complete segment. */ for (p = newpath + 1; *p; ) { if (*(p - 1) == '/' && *p == '.' && *(p + 1) == '/') memmove (p, p + 2, strlen (p + 2) + 1); else p++; } /* Remove "." at end. */ if (p > newpath + 2 && *(p - 1) == '.' && *(p - 2) == '/') *(p - 1) = '\0'; /* Remove "<segment>/../" where <segment> != ".." */ for (p = newpath + 1; *p; ) { if (!strncmp (p, "../", 3)) { p += 3; continue; } q = strchr (p + 1, '/'); if (!q) break; if (strncmp (q, "/../", 4) != 0) { p = q + 1; continue; } memmove (p, q + 4, strlen (q + 4) + 1); p = newpath + 1; } /* Remove "<segment>/.." at end */ q = strrchr (newpath, '/'); if (q && !strcmp (q, "/..")) { p = q - 1; while (p > newpath && *p != '/') p--; if (strncmp (p, "/../", 4) != 0) *(p + 1) = 0; } g_free (url->path); url->path = newpath; } } return url; }
static void CDDBProcessLine(char *inbuffer,DiscData *data, int numtracks) { int track; int len = 0; char *st; if(!g_ascii_strncasecmp(inbuffer,"DTITLE",6)) { len = strlen(data->data_title); strncpy(data->data_title+len,ChopWhite(inbuffer+7),256-len); } else if(!g_ascii_strncasecmp(inbuffer,"DYEAR",5)) { strtok(inbuffer,"="); st = strtok(NULL, ""); if(st == NULL) return; data->data_year=atoi(ChopWhite(st)); } else if(!g_ascii_strncasecmp(inbuffer,"DGENRE",6)) { strtok(inbuffer,"="); st = strtok(NULL, ""); if(st == NULL) return; data->data_genre=CDDBGenreValue(ChopWhite(st)); } else if(!g_ascii_strncasecmp(inbuffer,"TTITLE",6)) { track=atoi(strtok(inbuffer+6,"=")); if(track >= 0 && track<numtracks) { len=strlen(data->data_track[track].track_name); strncpy(data->data_track[track].track_name+len, ChopWhite(strtok(NULL,"")),256-len); } } else if(!g_ascii_strncasecmp(inbuffer,"TARTIST",7)) { data->data_multi_artist=TRUE; track=atoi(strtok(inbuffer+7,"=")); if(track >= 0 && track<numtracks) { len=strlen(data->data_track[track].track_artist); st = strtok(NULL, ""); if(st == NULL) return; strncpy(data->data_track[track].track_artist+len, ChopWhite(st),256-len); } } else if(!g_ascii_strncasecmp(inbuffer,"EXTD",4)) { len=strlen(data->data_extended); strncpy(data->data_extended+len,ChopWhite(inbuffer+5),4096-len); } else if(!g_ascii_strncasecmp(inbuffer,"EXTT",4)) { track=atoi(strtok(inbuffer+4,"=")); if(track >= 0 && track<numtracks) { len=strlen(data->data_track[track].track_extended); st = strtok(NULL, ""); if(st == NULL) return; strncpy(data->data_track[track].track_extended+len, ChopWhite(st),4096-len); } } else if(!g_ascii_strncasecmp(inbuffer,"PLAYORDER",5)) { len=strlen(data->data_playlist); strncpy(data->data_playlist+len,ChopWhite(inbuffer+10),256-len); } }
static GList* parse_hkp_index (const gchar *response) { /* * Luckily enough, both the HKP server and NAI HKP interface to their * LDAP server are close enough in output so the same function can * parse them both. */ /* pub 2048/<a href="/pks/lookup?op=get&search=0x3CB3B415">3CB3B415</a> 1998/04/03 David M. Shaw <<a href="/pks/lookup?op=get&search=0x3CB3B415">[email protected]</a>> */ gchar **lines, **l; gchar **v; gchar *line, *t; SeahorsePgpKey *key = NULL; GList *keys = NULL; GList *subkeys = NULL; GList *uids = NULL; guint flags; lines = g_strsplit (response, "\n", 0); for (l = lines; *l; l++) { line = *l; dehtmlize (line); #if DEBUG_HKP_ENABLE fprintf(stderr,"%s\n", line); #endif /* Start a new key */ if (g_ascii_strncasecmp (line, "pub ", 4) == 0) { t = line + 4; while (*t && g_ascii_isspace (*t)) t++; v = g_strsplit_set (t, " ", 3); if (!v[0] || !v[1] || !v[2]) { g_warning ("Invalid key line from server: %s", line); } else { gchar *fingerprint, *fpr = NULL; const gchar *algo; gboolean has_uid = TRUE; SeahorsePgpSubkey *subkey; flags = SEAHORSE_FLAG_EXPORTABLE; /* Cut the length and fingerprint */ fpr = strchr (v[0], '/'); if (fpr == NULL) { g_warning ("couldn't find key fingerprint in line from server: %s", line); fpr = ""; } else { *(fpr++) = 0; } /* Check out the key type */ switch (g_ascii_toupper (v[0][strlen(v[0]) - 1])) { case 'D': algo = "DSA"; break; case 'R': algo = "RSA"; break; default: algo = ""; break; }; /* Format the date for our parse function */ g_strdelimit (v[1], "/", '-'); /* Cleanup the UID */ g_strstrip (v[2]); if (g_ascii_strcasecmp (v[2], "*** KEY REVOKED ***") == 0) { flags |= SEAHORSE_FLAG_REVOKED; has_uid = FALSE; } if (key) { seahorse_pgp_key_set_uids (SEAHORSE_PGP_KEY (key), uids); seahorse_object_list_free (uids); seahorse_pgp_key_set_subkeys (SEAHORSE_PGP_KEY (key), subkeys); seahorse_object_list_free (subkeys); uids = subkeys = NULL; key = NULL; } key = seahorse_pgp_key_new (); keys = g_list_prepend (keys, key); g_object_set (key, "location", SEAHORSE_LOCATION_REMOTE, "flags", flags, NULL); /* Add all the info to the key */ subkey = seahorse_pgp_subkey_new (); seahorse_pgp_subkey_set_keyid (subkey, fpr); fingerprint = seahorse_pgp_subkey_calc_fingerprint (fpr); seahorse_pgp_subkey_set_fingerprint (subkey, fingerprint); g_free (fingerprint); seahorse_pgp_subkey_set_flags (subkey, flags); seahorse_pgp_subkey_set_created (subkey, parse_hkp_date (v[1])); seahorse_pgp_subkey_set_length (subkey, strtol (v[0], NULL, 10)); seahorse_pgp_subkey_set_algorithm (subkey, algo); subkeys = g_list_prepend (subkeys, subkey); /* And the UID if one was found */ if (has_uid) { SeahorsePgpUid *uid = seahorse_pgp_uid_new (v[2]); uids = g_list_prepend (uids, uid); } } g_strfreev (v); /* A UID for the key */ } else if (key && g_ascii_strncasecmp (line, " ", 4) == 0) { SeahorsePgpUid *uid; g_strstrip (line); uid = seahorse_pgp_uid_new (line); uids = g_list_prepend (uids, uid); /* Signatures */ } else if (key && g_ascii_strncasecmp (line, "sig ", 4) == 0) { /* TODO: Implement signatures */ } } g_strfreev (lines); if (key) { seahorse_pgp_key_set_uids (SEAHORSE_PGP_KEY (key), g_list_reverse (uids)); seahorse_object_list_free (uids); seahorse_pgp_key_set_subkeys (SEAHORSE_PGP_KEY (key), g_list_reverse (subkeys)); seahorse_object_list_free (subkeys); } return keys; }
void properties_cb (GtkAction *action, EyesApplet *eyes_applet) { GtkWidget *pbox, *hbox; GtkWidget *vbox, *indent; GtkWidget *categories_vbox; GtkWidget *category_vbox, *control_vbox; GtkWidget *tree; GtkWidget *scrolled; GtkWidget *label; GtkListStore *model; GtkTreeViewColumn *column; GtkCellRenderer *cell; GtkTreeSelection *selection; GtkTreeIter iter; DIR *dfd; struct dirent *dp; int i; #ifdef PATH_MAX gchar filename [PATH_MAX]; #else gchar *filename; #endif gchar *title; if (eyes_applet->prop_box.pbox) { gtk_window_set_screen ( GTK_WINDOW (eyes_applet->prop_box.pbox), gtk_widget_get_screen (GTK_WIDGET (eyes_applet->applet))); gtk_window_present (GTK_WINDOW (eyes_applet->prop_box.pbox)); return; } pbox = gtk_dialog_new_with_buttons (_("Geyes Preferences"), NULL, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, GTK_STOCK_HELP, GTK_RESPONSE_HELP, NULL); gtk_window_set_screen (GTK_WINDOW (pbox), gtk_widget_get_screen (GTK_WIDGET (eyes_applet->applet))); gtk_widget_set_size_request (GTK_WIDGET (pbox), 300, 200); gtk_dialog_set_default_response(GTK_DIALOG (pbox), GTK_RESPONSE_CLOSE); gtk_dialog_set_has_separator (GTK_DIALOG (pbox), FALSE); gtk_container_set_border_width (GTK_CONTAINER (pbox), 5); gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (pbox))), 2); g_signal_connect (pbox, "response", G_CALLBACK (presponse_cb), eyes_applet); vbox = gtk_vbox_new (FALSE, 0); gtk_container_set_border_width (GTK_CONTAINER (vbox), 5); gtk_widget_show (vbox); gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (pbox))), vbox, TRUE, TRUE, 0); categories_vbox = gtk_vbox_new (FALSE, 18); gtk_box_pack_start (GTK_BOX (vbox), categories_vbox, TRUE, TRUE, 0); gtk_widget_show (categories_vbox); category_vbox = gtk_vbox_new (FALSE, 6); gtk_box_pack_start (GTK_BOX (categories_vbox), category_vbox, TRUE, TRUE, 0); gtk_widget_show (category_vbox); title = g_strconcat ("<span weight=\"bold\">", _("Themes"), "</span>", NULL); label = gtk_label_new (_(title)); gtk_label_set_use_markup (GTK_LABEL (label), TRUE); gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT); gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); gtk_box_pack_start (GTK_BOX (category_vbox), label, FALSE, FALSE, 0); g_free (title); hbox = gtk_hbox_new (FALSE, 0); gtk_box_pack_start (GTK_BOX (category_vbox), hbox, TRUE, TRUE, 0); gtk_widget_show (hbox); indent = gtk_label_new (HIG_IDENTATION); gtk_label_set_justify (GTK_LABEL (indent), GTK_JUSTIFY_LEFT); gtk_box_pack_start (GTK_BOX (hbox), indent, FALSE, FALSE, 0); gtk_widget_show (indent); control_vbox = gtk_vbox_new (FALSE, 6); gtk_box_pack_start (GTK_BOX (hbox), control_vbox, TRUE, TRUE, 0); gtk_widget_show (control_vbox); label = gtk_label_new_with_mnemonic (_("_Select a theme:")); gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); gtk_box_pack_start (GTK_BOX (control_vbox), label, FALSE, FALSE, 0); scrolled = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled), GTK_SHADOW_IN); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); model = gtk_list_store_new (TOTAL_COLS, G_TYPE_STRING, G_TYPE_STRING); tree = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model)); gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (tree), FALSE); gtk_label_set_mnemonic_widget (GTK_LABEL (label), tree); g_object_unref (model); gtk_container_add (GTK_CONTAINER (scrolled), tree); cell = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes ("not used", cell, "text", COL_THEME_NAME, NULL); gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column); selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree)); g_signal_connect (selection, "changed", G_CALLBACK (theme_selected_cb), eyes_applet); if ( ! key_writable (eyes_applet->applet, "theme_path")) { gtk_widget_set_sensitive (tree, FALSE); gtk_widget_set_sensitive (label, FALSE); } for (i = 0; i < NUM_THEME_DIRECTORIES; i++) { if ((dfd = opendir (theme_directories[i])) != NULL) { while ((dp = readdir (dfd)) != NULL) { if (dp->d_name[0] != '.') { gchar *theme_dir; gchar *theme_name; #ifdef PATH_MAX strcpy (filename, theme_directories[i]); strcat (filename, dp->d_name); #else asprintf (&filename, theme_directories[i], dp->d_name); #endif theme_dir = g_strdup_printf ("%s/", filename); theme_name = g_path_get_basename (filename); gtk_list_store_append (model, &iter); gtk_list_store_set (model, &iter, COL_THEME_DIR, &filename, COL_THEME_NAME, theme_name, -1); if (!g_ascii_strncasecmp (eyes_applet->theme_dir, theme_dir, strlen (theme_dir))) { GtkTreePath *path; path = gtk_tree_model_get_path (GTK_TREE_MODEL (model), &iter); gtk_tree_view_set_cursor (GTK_TREE_VIEW (tree), path, NULL, FALSE); gtk_tree_path_free (path); } g_free (theme_name); g_free (theme_dir); } } closedir (dfd); } } #ifndef PATH_MAX g_free (filename); #endif gtk_box_pack_start (GTK_BOX (control_vbox), scrolled, TRUE, TRUE, 0); gtk_widget_show_all (pbox); eyes_applet->prop_box.pbox = pbox; return; }
static void cmd_completion(const char *data) { GHashTable *optlist; CONFIG_NODE *node; GSList *tmp; char *key, *value; void *free_arg; int len; if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_OPTIONS | PARAM_FLAG_GETREST | PARAM_FLAG_STRIP_TRAILING_WS, "completion", &optlist, &key, &value)) return; node = iconfig_node_traverse("completions", *value != '\0'); if (node != NULL && node->type != NODE_TYPE_BLOCK) { /* FIXME: remove after 0.8.5 */ iconfig_node_remove(mainconfig->mainnode, node); node = iconfig_node_traverse("completions", *value != '\0'); } if (node == NULL || (node->value == NULL && *value == '\0')) { printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, TXT_NO_COMPLETIONS); cmd_params_free(free_arg); return; } if (g_hash_table_lookup(optlist, "delete") != NULL && *key != '\0') { printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, TXT_COMPLETION_REMOVED, key); iconfig_set_str("completions", key, NULL); signal_emit("completion removed", 1, key); } else if (*key != '\0' && *value != '\0') { int automatic = g_hash_table_lookup(optlist, "auto") != NULL; node = iconfig_node_section(node, key, NODE_TYPE_BLOCK); iconfig_node_set_str(node, "value", value); if (automatic) iconfig_node_set_bool(node, "auto", TRUE); else iconfig_node_set_str(node, "auto", NULL); printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, TXT_COMPLETION_LINE, key, value, automatic ? "yes" : "no"); signal_emit("completion added", 1, key); } else { printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, TXT_COMPLETION_HEADER); len = strlen(key); for (tmp = node->value; tmp != NULL; tmp = tmp->next) { node = tmp->data; if (len == 0 || g_ascii_strncasecmp(node->key, key, len) == 0) { printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, TXT_COMPLETION_LINE, node->key, config_node_get_str(node, "value", ""), config_node_get_bool(node, "auto", FALSE) ? "yes" : "no"); } } printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, TXT_COMPLETION_FOOTER); } cmd_params_free(free_arg); }
static void process_named_msg (session *sess, char *type, char *word[], char *word_eol[], const message_tags_data *tags_data) { server *serv = sess->server; char ip[128], nick[NICKLEN]; char *text, *ex; int len = strlen (type); /* fill in the "ip" and "nick" buffers */ ex = strchr (word[1], '!'); if (!ex) /* no '!', must be a server message */ { safe_strcpy (ip, word[1], sizeof (ip)); safe_strcpy (nick, word[1], sizeof (nick)); } else { safe_strcpy (ip, ex + 1, sizeof (ip)); ex[0] = 0; safe_strcpy (nick, word[1], sizeof (nick)); ex[0] = '!'; } if (len == 4) { guint32 t; t = WORDL((guint8)type[0], (guint8)type[1], (guint8)type[2], (guint8)type[3]); /* this should compile to a bunch of: CMP.L, JE ... nice & fast */ switch (t) { case WORDL('J','O','I','N'): { char *chan = word[3]; char *account = word[4]; char *realname = word_eol[5] + 1; if (*chan == ':') chan++; if (!serv->p_cmp (nick, serv->nick)) inbound_ujoin (serv, chan, nick, ip, tags_data); else inbound_join (serv, chan, nick, ip, account, realname, tags_data); } return; case WORDL('K','I','C','K'): { char *kicked = word[4]; char *reason = word_eol[5]; if (*kicked) { if (*reason == ':') reason++; if (!strcmp (kicked, serv->nick)) inbound_ukick (serv, word[3], nick, reason, tags_data); else inbound_kick (serv, word[3], kicked, nick, reason, tags_data); } } return; case WORDL('K','I','L','L'): EMIT_SIGNAL_TIMESTAMP (XP_TE_KILL, sess, nick, word_eol[5], NULL, NULL, 0, tags_data->timestamp); return; case WORDL('M','O','D','E'): handle_mode (serv, word, word_eol, nick, FALSE, tags_data); /* modes.c */ return; case WORDL('N','I','C','K'): inbound_newnick (serv, nick, (word_eol[3][0] == ':') ? word_eol[3] + 1 : word_eol[3], FALSE, tags_data); return; case WORDL('P','A','R','T'): { char *chan = word[3]; char *reason = word_eol[4]; if (*chan == ':') chan++; if (*reason == ':') reason++; if (!strcmp (nick, serv->nick)) inbound_upart (serv, chan, ip, reason, tags_data); else inbound_part (serv, chan, nick, ip, reason, tags_data); } return; case WORDL('P','O','N','G'): inbound_ping_reply (serv->server_session, (word[4][0] == ':') ? word[4] + 1 : word[4], word[3], tags_data); return; case WORDL('Q','U','I','T'): inbound_quit (serv, nick, ip, (word_eol[3][0] == ':') ? word_eol[3] + 1 : word_eol[3], tags_data); return; case WORDL('A','W','A','Y'): inbound_away_notify (serv, nick, (word_eol[3][0] == ':') ? word_eol[3] + 1 : NULL, tags_data); return; } goto garbage; } else if (len >= 5) { guint32 t; t = WORDL((guint8)type[0], (guint8)type[1], (guint8)type[2], (guint8)type[3]); /* this should compile to a bunch of: CMP.L, JE ... nice & fast */ switch (t) { case WORDL('A','C','C','O'): inbound_account (serv, nick, word[3], tags_data); return; case WORDL('I','N','V','I'): if (ignore_check (word[1], IG_INVI)) return; if (word[4][0] == ':') EMIT_SIGNAL_TIMESTAMP (XP_TE_INVITED, sess, word[4] + 1, nick, serv->servername, NULL, 0, tags_data->timestamp); else EMIT_SIGNAL_TIMESTAMP (XP_TE_INVITED, sess, word[4], nick, serv->servername, NULL, 0, tags_data->timestamp); return; case WORDL('N','O','T','I'): { int id = FALSE; /* identified */ char *response; text = word_eol[4]; if (*text == ':') { text++; } if (!strncmp (text, "CHALLENGE ", 10)) /* QuakeNet CHALLENGE upon our request */ { response = challengeauth_response (((ircnet *)serv->network)->user ? ((ircnet *)serv->network)->user : prefs.hex_irc_user_name, serv->password, word[5]); tcp_sendf (serv, "PRIVMSG %s :CHALLENGEAUTH %s %s %s\r\n", CHALLENGEAUTH_NICK, ((ircnet *)serv->network)->user ? ((ircnet *)serv->network)->user : prefs.hex_irc_user_name, response, CHALLENGEAUTH_ALGO); g_free (response); return; /* omit the CHALLENGE <hash> ALGOS message */ } if (serv->have_idmsg) { if (*text == '+') { id = TRUE; text++; } else if (*text == '-') text++; } if (!ignore_check (word[1], IG_NOTI)) inbound_notice (serv, word[3], nick, text, ip, id, tags_data); } return; case WORDL('P','R','I','V'): { char *to = word[3]; int len; int id = FALSE; /* identified */ if (*to) { /* Handle limited channel messages, for now no special event */ if (strchr (serv->nick_prefixes, to[0]) != NULL) to++; text = word_eol[4]; if (*text == ':') text++; if (serv->have_idmsg) { if (*text == '+') { id = TRUE; text++; } else if (*text == '-') text++; } len = strlen (text); if (text[0] == 1 && text[len - 1] == 1) /* ctcp */ { text[len - 1] = 0; text++; if (g_ascii_strncasecmp (text, "ACTION", 6) != 0) flood_check (nick, ip, serv, sess, 0); if (g_ascii_strncasecmp (text, "DCC ", 4) == 0) /* redo this with handle_quotes TRUE */ process_data_init (word[1], word_eol[1], word, word_eol, TRUE, FALSE); ctcp_handle (sess, to, nick, ip, text, word, word_eol, id, tags_data); } else { if (is_channel (serv, to)) { if (ignore_check (word[1], IG_CHAN)) return; inbound_chanmsg (serv, NULL, to, nick, text, FALSE, id, tags_data); } else { if (ignore_check (word[1], IG_PRIV)) return; inbound_privmsg (serv, nick, ip, text, id, tags_data); } } } } return; case WORDL('T','O','P','I'): inbound_topicnew (serv, nick, word[3], (word_eol[4][0] == ':') ? word_eol[4] + 1 : word_eol[4], tags_data); return; case WORDL('W','A','L','L'): text = word_eol[3]; if (*text == ':') text++; EMIT_SIGNAL_TIMESTAMP (XP_TE_WALLOPS, sess, nick, text, NULL, NULL, 0, tags_data->timestamp); return; } } else if (len == 3) { guint32 t; t = WORDL((guint8)type[0], (guint8)type[1], (guint8)type[2], (guint8)type[3]); switch (t) { case WORDL('C','A','P','\0'): if (strncasecmp (word[4], "ACK", 3) == 0) { inbound_cap_ack (serv, word[1], word[5][0] == ':' ? word_eol[5] + 1 : word_eol[5], tags_data); } else if (strncasecmp (word[4], "LS", 2) == 0) { inbound_cap_ls (serv, word[1], word[5][0] == ':' ? word_eol[5] + 1 : word_eol[5], tags_data); } else if (strncasecmp (word[4], "NAK", 3) == 0) { inbound_cap_nak (serv, tags_data); } else if (strncasecmp (word[4], "LIST", 4) == 0) { inbound_cap_list (serv, word[1], word[5][0] == ':' ? word_eol[5] + 1 : word_eol[5], tags_data); } return; } } garbage: /* unknown message */ PrintTextTimeStampf (sess, tags_data->timestamp, "GARBAGE: %s\n", word_eol[1]); }
GSList * eab_contact_list_from_string (const gchar *str) { GSList *contacts = NULL; GString *gstr = g_string_new (NULL); gchar *str_stripped; gchar *p = (gchar *) str; gchar *q; if (!p) return NULL; if (!strncmp (p, "Book: ", 6)) { p = strchr (p, '\n'); if (!p) { g_warning (G_STRLOC ": Got book but no newline!"); return NULL; } p++; } while (*p) { if (*p != '\r') g_string_append_c (gstr, *p); p++; } p = str_stripped = g_string_free (gstr, FALSE); /* Note: The vCard standard says * * vcard = "BEGIN" [ws] ":" [ws] "VCARD" [ws] 1*CRLF * items *CRLF "END" [ws] ":" [ws] "VCARD" * * which means we can have whitespace (e.g. "BEGIN : VCARD"). So we're not being * fully compliant here, although I'm not sure it matters. The ideal solution * would be to have a vcard parsing function that returned the end of the vcard * parsed. Arguably, contact list parsing should all be in libebook's e-vcard.c, * where we can do proper parsing and validation without code duplication. */ for (p = eab_strstrcase (p, "BEGIN:VCARD"); p; p = eab_strstrcase (q, "\nBEGIN:VCARD")) { gchar *card_str; if (*p == '\n') p++; for (q = eab_strstrcase (p, "END:VCARD"); q; q = eab_strstrcase (q, "END:VCARD")) { gchar *temp; q += 9; temp = q; if (*temp) temp += strspn (temp, "\r\n\t "); if (*temp == '\0' || !g_ascii_strncasecmp (temp, "BEGIN:VCARD", 11)) break; /* Found the outer END:VCARD */ } if (!q) break; card_str = g_strndup (p, q - p); contacts = g_slist_prepend (contacts, e_contact_new_from_vcard (card_str)); g_free (card_str); } g_free (str_stripped); return g_slist_reverse (contacts); }
static gint _main_helper(Options* options) { /* start off with some status messages */ #if defined(IGRAPH_VERSION) gint igraphMajor = -1, igraphMinor = -1, igraphPatch = -1; igraph_version(NULL, &igraphMajor, &igraphMinor, &igraphPatch); gchar* startupStr = g_strdup_printf("Starting %s with GLib v%u.%u.%u and IGraph v%i.%i.%i", SHADOW_VERSION_STRING, (guint)GLIB_MAJOR_VERSION, (guint)GLIB_MINOR_VERSION, (guint)GLIB_MICRO_VERSION, igraphMajor, igraphMinor, igraphPatch); #else gchar* startupStr = g_strdup_printf("Starting %s with GLib v%u.%u.%u (IGraph version not available)", SHADOW_VERSION_STRING, (guint)GLIB_MAJOR_VERSION, (guint)GLIB_MINOR_VERSION, (guint)GLIB_MICRO_VERSION); #endif message("%s", startupStr); /* avoid logging the message to stderr twice (only log if this is not a relaunch) */ if(g_getenv("SHADOW_SPAWNED") == NULL) { g_printerr("** %s\n", startupStr); } g_free(startupStr); message(SHADOW_INFO_STRING); message("logging current startup arguments and environment"); gchar** envlist = g_get_environ(); gchar** arglist = g_strsplit(options_getArgumentString(options), " ", 0); _main_logEnvironment(arglist, envlist); g_strfreev(arglist); g_strfreev(envlist); /* check if we still need to setup our required environment and relaunch */ if(g_getenv("SHADOW_SPAWNED") == NULL) { message("shadow will automatically adjust environment and relaunch"); message("loading shadow configuration file"); /* we need to relaunch. * first lets load the config file to help us setup the environment */ const GString* fileName = options_getInputXMLFilename(options); if(!fileName) { return EXIT_FAILURE; } GString* file = utility_getFileContents(fileName->str); if(!file) { critical("unable to read config file contents"); return EXIT_FAILURE; } Configuration* config = configuration_new(options, file); g_string_free(file, TRUE); file = NULL; if(!config) { critical("there was a problem parsing the Shadow config file, and we can't run without it"); return EXIT_FAILURE; } message("shadow configuration file loaded, parsed, and passed validation"); /* now start to set up the environment */ gchar** envlist = g_get_environ(); GString* commandBuffer = g_string_new(options_getArgumentString(options)); if(!envlist || !commandBuffer) { critical("there was a problem loading existing environment"); configuration_free(config); return EXIT_FAILURE; } message("setting up LD_PRELOAD environment"); /* compute the proper LD_PRELOAD value, extract the shadow preload file and * set it as a command line argument if needed */ gchar* preloadArgValue = NULL; { /* before we restart, we should: * -set the shadow preload lib as a command line arg * -make sure it does not exist in LD_PRELOAD, but otherwise leave LD_PRELOAD in place * we need to search for our preload lib. our order of preference follows. */ /* 1. existing "--preload=" option value */ if(_main_isValidPathToPreloadLib(options_getPreloadString(options))) { preloadArgValue = g_strdup(options_getPreloadString(options)); } /* 2. the 'preload' attribute value of the 'shadow' element in shadow.config.xml */ /* we only need to search if we haven't already found a valid path */ if(!preloadArgValue) { ConfigurationShadowElement* element = configuration_getShadowElement(config); if(element && element->preloadPath.isSet) { gchar* path = element->preloadPath.string->str; if(_main_isValidPathToPreloadLib(path)) { preloadArgValue = g_strdup(path); } } } /* 3. the LD_PRELOAD value */ GString* preloadEnvValueBuffer = NULL; /* we always search the env variable and remove existing Shadow preload libs */ if(g_environ_getenv(envlist, "LD_PRELOAD") != NULL) { gchar** tokens = g_strsplit(g_environ_getenv(envlist, "LD_PRELOAD"), ":", 0); for(gint i = 0; tokens[i] != NULL; i++) { /* each token in the env variable should be an absolute path */ if(_main_isValidPathToPreloadLib(tokens[i])) { /* found a valid path, only save it if we don't have one yet (from options or config) */ if(!preloadArgValue) { preloadArgValue = g_strdup(tokens[i]); } } else { /* maintain non-shadow entries */ if(preloadEnvValueBuffer) { g_string_append_printf(preloadEnvValueBuffer, ":%s", tokens[i]); } else { preloadEnvValueBuffer = g_string_new(tokens[i]); } } } g_strfreev(tokens); } /* 4. the 'environment' attribute of the 'shadow' configuration element in shadow.config.xml */ /* always go through the 'environment' attribute of the 'shadow' element to pull in any keys defined there */ { ConfigurationShadowElement* element = configuration_getShadowElement(config); if(element && element->environment.isSet) { /* entries are split by ';' */ gchar** envTokens = g_strsplit(element->environment.string->str, ";", 0); for(gint i = 0; envTokens[i] != NULL; i++) { /* each env entry is key=value, get 2 tokens max */ gchar** items = g_strsplit(envTokens[i], "=", 2); gchar* key = items[0]; gchar* value = items[1]; if(key != NULL && value != NULL) { /* check if the key is LD_PRELOAD */ if(!g_ascii_strncasecmp(key, "LD_PRELOAD", 10)) { gchar** preloadTokens = g_strsplit(value, ":", 0); for(gint j = 0; preloadTokens[j] != NULL; j++) { /* each token in the env variable should be an absolute path */ if(_main_isValidPathToPreloadLib(preloadTokens[j])) { /* found a valid path, only save it if we don't have one yet (from options or config) */ if(!preloadArgValue) { preloadArgValue = g_strdup(preloadTokens[j]); } } else { /* maintain non-shadow entries */ if(preloadEnvValueBuffer) { g_string_append_printf(preloadEnvValueBuffer, ":%s", preloadTokens[j]); } else { preloadEnvValueBuffer = g_string_new(preloadTokens[j]); } } } g_strfreev(preloadTokens); } else { /* set the key=value pair, but don't overwrite any existing settings */ envlist = g_environ_setenv(envlist, key, value, 0); } } g_strfreev(items); } g_strfreev(envTokens); } } /* save away the non-shadow preload libs */ if(preloadEnvValueBuffer) { envlist = g_environ_setenv(envlist, "LD_PRELOAD", preloadEnvValueBuffer->str, 1); g_string_free(preloadEnvValueBuffer, TRUE); preloadEnvValueBuffer = NULL; } else { envlist = g_environ_unsetenv(envlist, "LD_PRELOAD"); } /* 5. as a last hope, try looking in RPATH since shadow is built with one */ /* we only need to search if we haven't already found a valid path */ if(!preloadArgValue) { gchar* rpathStr = _main_getRPath(); if(rpathStr != NULL) { gchar** tokens = g_strsplit(rpathStr, ":", 0); for(gint i = 0; tokens[i] != NULL; i++) { GString* candidateBuffer = g_string_new(NULL); /* rpath specifies directories, so look inside */ g_string_printf(candidateBuffer, "%s/%s", tokens[i], INTERPOSELIBSTR); gchar* candidate = g_string_free(candidateBuffer, FALSE); if(_main_isValidPathToPreloadLib(candidate)) { preloadArgValue = candidate; break; } else { g_free(candidate); } } g_strfreev(tokens); } g_free(rpathStr); } /* if we still didn't find our preload lib, that is a user error */ if(!preloadArgValue) { critical("can't find path to %s, did you specify an absolute path to an existing readable file?", INTERPOSELIBSTR); configuration_free(config); return EXIT_FAILURE; } /* now that we found the correct path to the preload lib, first remove any possibly * incomplete path that might exist in the command line args, and then replace it * with the path that we found and verified is correct. */ { /* first remove all preload options */ gchar** tokens = g_strsplit(commandBuffer->str, " ", 0); g_string_free(commandBuffer, TRUE); commandBuffer = NULL; for(gint i = 0; tokens[i] != NULL; i++) { /* use -1 to search the entire string */ if(!g_ascii_strncasecmp(tokens[i], "--preload=", 10)) { /* skip this key=value string */ } else if(!g_ascii_strncasecmp(tokens[i], "-p", 2)) { /* skip this key, and also the next arg which is the value */ i++; } else { if(commandBuffer) { g_string_append_printf(commandBuffer, " %s", tokens[i]); } else { commandBuffer = g_string_new(tokens[i]); } } } g_strfreev(tokens); /* now add back in the preload option */ g_string_append_printf(commandBuffer, " --preload=%s", preloadArgValue); } } message("setting up LD_STATIC_TLS_EXTRA environment"); /* compute the proper TLS size we need for dlmopen()ing all of the plugins, * but only do this if the user didn't manually specify a size */ if(g_environ_getenv(envlist, "LD_STATIC_TLS_EXTRA") == NULL) { gchar* staticTLSValue = _main_getStaticTLSValue(options, config, preloadArgValue); envlist = g_environ_setenv(envlist, "LD_STATIC_TLS_EXTRA", staticTLSValue, 0); message("we need %s total bytes of static TLS storage", staticTLSValue); g_free(staticTLSValue); } /* cleanup unused string */ if(preloadArgValue) { g_free(preloadArgValue); preloadArgValue = NULL; } /* are we running valgrind */ if(options_doRunValgrind(options)) { message("setting up environment for valgrind"); /* make glib friendlier to valgrind */ envlist = g_environ_setenv(envlist, "G_DEBUG", "gc-friendly", 0); envlist = g_environ_setenv(envlist, "G_SLICE", "always-malloc", 0); /* add the valgrind command and some default options */ g_string_prepend(commandBuffer, "valgrind --leak-check=full --show-reachable=yes --track-origins=yes --trace-children=yes --log-file=shadow-valgrind-%p.log --error-limit=no "); } else { /* The following can be used to add internal GLib memory validation that * will abort the program if it finds an error. This is only useful outside * of the valgrind context, as otherwise valgrind will complain about * the implementation of the GLib validator. * e.g. $ G_SLICE=debug-blocks shadow --file * * envlist = g_environ_setenv(envlist, "G_SLICE", "debug-blocks", 0); */ } /* keep track that we are relaunching shadow */ envlist = g_environ_setenv(envlist, "SHADOW_SPAWNED", "TRUE", 1); gchar* command = g_string_free(commandBuffer, FALSE); gchar** arglist = g_strsplit(command, " ", 0); g_free(command); configuration_free(config); message("environment was updated; shadow is relaunching now with new environment"); Logger* logger = logger_getDefault(); if(logger) { logger_setDefault(NULL); logger_unref(logger); } /* execvpe only returns if there is an error, otherwise the current process * image is replaced with a new process */ gint returnValue = execvpe(arglist[0], arglist, envlist); /* cleanup */ if(envlist) { g_strfreev(envlist); } if(arglist) { g_strfreev(arglist); } critical("** Error %i while re-launching shadow process: %s", returnValue, g_strerror(returnValue)); return EXIT_FAILURE; } /* we dont need to relaunch, so we can run the simulation */ /* make sure we have initialized static tls */ if(!_main_verifyStaticTLS()) { critical("** Shadow Setup Check Failed: LD_STATIC_TLS_EXTRA does not contain a nonzero value"); return EXIT_FAILURE; } /* make sure we have the shadow preload lib */ if(!_main_isValidPathToPreloadLib(options_getPreloadString(options))) { critical("** Shadow Setup Check Failed: cannot find absolute path to "INTERPOSELIBSTR""); return EXIT_FAILURE; } /* now load the preload library into shadow's namespace */ if(!_main_loadShadowPreload(options)) { critical("** Shadow Setup Check Failed: unable to load preload library"); return EXIT_FAILURE; } /* tell the preload lib we are ready for action */ extern int interposer_setShadowIsLoaded(int); int interposerResult = interposer_setShadowIsLoaded(1); if(interposerResult != 0) { /* it was not intercepted, meaning our preload library is not set up properly */ critical("** Shadow Setup Check Failed: preload library is not correctly interposing functions"); return EXIT_FAILURE; } message("startup checks passed, we are ready to start simulation"); /* pause for debugger attachment if the option is set */ if(options_doRunDebug(options)) { gint pid = (gint)getpid(); message("Pausing with SIGTSTP to enable debugger attachment (pid %i)", pid); g_printerr("** Pausing with SIGTSTP to enable debugger attachment (pid %i)\n", pid); raise(SIGTSTP); message("Resuming now"); } /* allocate and initialize our main simulation driver */ gint returnCode = 0; shadowMaster = master_new(options); message("log message buffering is enabled for efficiency"); logger_setEnableBuffering(logger_getDefault(), TRUE); if(shadowMaster) { /* run the simulation */ returnCode = master_run(shadowMaster); /* cleanup */ master_free(shadowMaster); shadowMaster = NULL; } message("%s simulation was shut down cleanly, returning code %i", SHADOW_VERSION_STRING, returnCode); return returnCode; }
/* * Optionally do reassembly of the request/response line, headers, and body. */ gboolean req_resp_hdrs_do_reassembly(tvbuff_t *tvb, const int offset, packet_info *pinfo, const gboolean desegment_headers, const gboolean desegment_body) { gint next_offset; gint next_offset_sav; gint length_remaining, reported_length_remaining; int linelen; gchar *header_val; int content_length; gboolean content_length_found = FALSE; gboolean content_type_found = FALSE; gboolean chunked_encoding = FALSE; gboolean keepalive_found = FALSE; gchar *line; gchar *content_type = NULL; /* * Do header desegmentation if we've been told to. * * RFC 2616 defines HTTP messages as being either of the * Request or the Response type * (HTTP-message = Request | Response). * Request and Response are defined as: * Request = Request-Line * *(( general-header * | request-header * | entity-header ) CRLF) * CRLF * [ message-body ] * Response = Status-Line * *(( general-header * | response-header * | entity-header ) CRLF) * CRLF * [ message-body ] * that's why we can always assume two consecutive line * endings (we allow CR, LF, or CRLF, as some clients * or servers might not use a full CRLF) to mark the end * of the headers. The worst thing that would happen * otherwise would be the packet not being desegmented * or being interpreted as only headers. * * RFC 2326 says RTSP works the same way; RFC 3261 says SIP * works the same way. */ /* * If header desegmentation is activated, check that all * headers are in this tvbuff (search for an empty line * marking end of headers) or request one more byte (we * don't know how many bytes we'll need, so we just ask * for one). */ if (desegment_headers && pinfo->can_desegment) { next_offset = offset; for (;;) { next_offset_sav = next_offset; reported_length_remaining = tvb_reported_length_remaining(tvb, next_offset); /* * Request one more byte if there're no * bytes left in the reported data (if there're * bytes left in the reported data, but not in * the available data, requesting more bytes * won't help, as those bytes weren't captured). */ if (reported_length_remaining < 1) { pinfo->desegment_offset = offset; pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT; return FALSE; } length_remaining = tvb_captured_length_remaining(tvb, next_offset); /* * Request one more byte if we cannot find a * header (i.e. a line end). */ linelen = tvb_find_line_end(tvb, next_offset, length_remaining, &next_offset, TRUE); if (linelen == -1 && length_remaining >= reported_length_remaining) { /* * Not enough data; ask for one more * byte. */ pinfo->desegment_offset = offset; pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT; return FALSE; } if (linelen == 0) { /* * We found the end of the headers. */ break; } /* * Is this a Content-Length or Transfer-Encoding * header? If not, it either means that we are in * a different header line, or that we are * at the end of the headers, or that there * isn't enough data; the two latter cases * have already been handled above. */ if (desegment_body) { /* Optimization to avoid fetching the whole (potentially very long) * line and doing expensive string comparisons if the first * character doesn't match. Shaves about 20% off the load time of * one of my sample files that's HTTP-alike. */ guchar first_byte = tvb_get_guint8(tvb, next_offset_sav); if (! (first_byte == 'c' || first_byte == 'C' || first_byte == 't' || first_byte == 'T')) { continue; } /* * Check if we've found Content-Length. */ line = tvb_get_string_enc(wmem_packet_scope(), tvb, next_offset_sav, linelen, ENC_UTF_8|ENC_NA); if (g_ascii_strncasecmp(line, "Content-Length:", 15) == 0) { /* XXX - what if it doesn't fit in an int? (Do not "fix" that by making this a "long"; make it a gint64 or a guint64.) */ if (sscanf(line+15,"%i", &content_length) == 1) content_length_found = TRUE; } else if (g_ascii_strncasecmp(line, "Content-Type:", 13) == 0) { content_type_found = TRUE; content_type = line+13; while (*content_type == ' ') { content_type++; } } else if (g_ascii_strncasecmp(line, "Connection:", 11) == 0) { /* Check for keep-alive */ header_val = line+11; if(header_val){ while(*header_val==' '){ header_val++; } if(!g_ascii_strncasecmp(header_val, "Keep-Alive", 10)){ keepalive_found = TRUE; } } } else if (g_ascii_strncasecmp( line, "Transfer-Encoding:", 18) == 0) { /* * Find out if this Transfer-Encoding is * chunked. It should be, since there * really aren't any other types, but * RFC 2616 allows for them. */ gchar *p; guint len; header_val = line+18; p = header_val; len = (guint) strlen(header_val); /* Skip white space */ while (p < header_val + len && (*p == ' ' || *p == '\t')) p++; if (p <= header_val + len) { if (g_ascii_strncasecmp(p, "chunked", 7) == 0) { /* * Don't bother looking * for extensions; * since we don't * understand them, * they should be * ignored. */ chunked_encoding = TRUE; } } } } } } /* * The above loop ends when we reached the end of the headers, so * there should be content_length bytes after the 4 terminating bytes * and next_offset points to after the end of the headers. */ if (desegment_body) { if (chunked_encoding) { /* * This data is chunked, so we need to keep pulling * data until we reach the end of the stream, or a * zero sized chunk. * * XXX * This doesn't bother with trailing headers; I don't * think they are really used, and we'd have to use * is_http_request_or_reply() to determine if it was * a trailing header, or the start of a new response. */ gboolean done_chunking = FALSE; while (!done_chunking) { guint chunk_size = 0; gint chunk_offset = 0; gchar *chunk_string = NULL; gchar *c = NULL; reported_length_remaining = tvb_reported_length_remaining(tvb, next_offset); if (reported_length_remaining < 1) { pinfo->desegment_offset = offset; pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT; return FALSE; } length_remaining = tvb_captured_length_remaining(tvb, next_offset); linelen = tvb_find_line_end(tvb, next_offset, length_remaining, &chunk_offset, TRUE); if (linelen == -1 && length_remaining >= reported_length_remaining) { pinfo->desegment_offset = offset; pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT; return FALSE; } /* We have a line with the chunk size in it.*/ chunk_string = tvb_get_string(wmem_packet_scope(), tvb, next_offset, linelen); c = chunk_string; /* * We don't care about the extensions. */ if ((c = strchr(c, ';'))) { *c = '\0'; } if (sscanf(chunk_string, "%x", &chunk_size) < 1) { /* We couldn't get the chunk size, * so stop trying. */ return TRUE; } if (chunk_size > 1U<<31) { /* Chunk size is unreasonable. */ /* XXX What /is/ reasonable? */ return TRUE; } if (chunk_size == 0) { /* * This is the last chunk. Let's pull in the * trailing CRLF. */ linelen = tvb_find_line_end(tvb, chunk_offset, length_remaining, &chunk_offset, TRUE); if (linelen == -1 && length_remaining >= reported_length_remaining) { pinfo->desegment_offset = offset; pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT; return FALSE; } pinfo->desegment_offset = chunk_offset; pinfo->desegment_len = 0; done_chunking = TRUE; } else { /* * Skip to the next chunk if we * already have it */ if (reported_length_remaining > (gint) chunk_size) { next_offset = chunk_offset + chunk_size + 2; } else { /* * Fetch this chunk, plus the * trailing CRLF. */ pinfo->desegment_offset = offset; pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT; return FALSE; } } } } else if (content_length_found) { if (content_length >= 128*1024) { /* MS-RPCH stipulate that the content-length must be between 128K and 2G */ gchar *tmp; if (content_type_found && strncmp(content_type, "application/rpc", 15) == 0) { /* It looks like a RPC_IN_DATA request or a RPC_OUT_DATA response * in which the content-length is meaningless */ return TRUE; } /* Following sizeof will return the length of the string + \0 we need to not count it*/ tmp = tvb_get_string(wmem_packet_scope(), tvb, 0, sizeof("RPC_OUT_DATA") - 1); if ((strncmp(tmp, "RPC_IN_DATA", sizeof("RPC_IN_DATA") - 1) == 0) || (strncmp(tmp, "RPC_OUT_DATA", sizeof("RPC_OUT_DATA") - 1) == 0)) { return TRUE; } } /* next_offset has been set to the end of the headers */ if (!tvb_bytes_exist(tvb, next_offset, content_length)) { length_remaining = tvb_captured_length_remaining(tvb, next_offset); reported_length_remaining = tvb_reported_length_remaining(tvb, next_offset); if (length_remaining < reported_length_remaining) { /* * It's a waste of time asking for more * data, because that data wasn't captured. */ return TRUE; } if (length_remaining == -1) length_remaining = 0; pinfo->desegment_offset = offset; pinfo->desegment_len = content_length - length_remaining; return FALSE; } } else if (content_type_found && pinfo->can_desegment) { /* We found a content-type but no content-length. * This is probably a HTTP header for a session with * only one HTTP PDU and where the content spans * until the end of the tcp session, unless there * is a keepalive header present in which case we * assume there is no message body at all and thus * we won't do any reassembly. * Set up tcp reassembly until the end of this session. */ length_remaining = tvb_captured_length_remaining(tvb, next_offset); reported_length_remaining = tvb_reported_length_remaining(tvb, next_offset); if (length_remaining < reported_length_remaining) { /* * It's a waste of time asking for more * data, because that data wasn't captured. */ return TRUE; } if (keepalive_found) { /* We have a keep-alive but no content-length. * Assume there is no message body and don't * do any reassembly. */ return TRUE; } pinfo->desegment_offset = offset; pinfo->desegment_len = DESEGMENT_UNTIL_FIN; return FALSE; } } /* * No further desegmentation needed. */ return TRUE; }
int uncompress_chunk2(const gchar* path, gboolean preserve, gboolean keep_pending, GError ** error) { GError *local_error = NULL; int status = 0; TRACE("Uncompressing [%s]", path); gchar *tmp_path = NULL; gulong tmp_len; gint64 total_read; guint8* data = NULL; gint64 bufsize, nb_read; gint64 current_read; struct stat *buf = NULL; struct compressed_chunk_s *cp_chunk = NULL; struct compression_ctx_s *comp_ctx = NULL; FILE *dst = NULL; /* Check chunk exists */ buf = g_malloc0(sizeof(struct stat)); DEBUG("Checking chunk exists"); if(stat(path, buf) == -1) { GSETERROR (error, "stat() failed, chunk not found\n"); goto end; } DEBUG("File [%s] found", path); GHashTable *compress_opt = NULL; compress_opt = g_hash_table_new_full( g_str_hash, g_str_equal, g_free, g_free); if(!get_compression_info_in_attr(path, error, &compress_opt)) { GSETERROR(error, "Failed to get compression info in attr, chunk may be not compressed"); goto end; } gchar * compression = NULL; compression = (gchar*) g_hash_table_lookup(compress_opt, NS_COMPRESSION_OPTION); if (compression != NULL && g_ascii_strncasecmp(compression, NS_COMPRESSION_ON, strlen(compression)) != 0) { GSETERROR(error, "Chunk not compressed, cannot nothing to do"); goto end; } /* init compression method according to algo choice */ comp_ctx = g_malloc0(sizeof(struct compression_ctx_s)); init_compression_ctx(comp_ctx, g_hash_table_lookup(compress_opt, NS_COMPRESS_ALGO_OPTION)); cp_chunk = g_malloc0(sizeof(struct compressed_chunk_s)); if (comp_ctx->chunk_initiator(cp_chunk, path) != 0) { GSETERROR(error, "Failed to init compressed chunk context"); goto end; } DEBUG("Chunk check done"); tmp_len = strlen(path) +sizeof(".pending"); tmp_path = g_malloc0(tmp_len); g_snprintf(tmp_path, tmp_len, "%s.pending", path); DEBUG("Checking chunk not busy"); if(stat(tmp_path, buf) != -1) { DEBUG("Stats failed"); GSETERROR (error, "stat() success on pending file, cannot process : busy chunk\n"); goto end; } do { int fd; if((fd = open(tmp_path, O_WRONLY|O_CREAT|O_EXCL, 0644)) == -1) { GSETERROR(error, "Failed to create pending chunk file (%s)\n", strerror(errno)); goto end; } metautils_pclose(&fd); } while (0); if(!copy_fattr(path, tmp_path, error)) { GSETERROR(error, "Failed to copy extended attributes to destination file\n"); goto end; } TRACE("xattr copied from src to dst"); dst = fopen(tmp_path, "w"); TRACE("Destination file opened"); gint64 chunk_size; chunk_size = g_ascii_strtoll(cp_chunk->uncompressed_size, NULL, 10); total_read = 0; DEBUG("Starting, total_read = %"G_GINT64_FORMAT", chunk_size = %"G_GINT64_FORMAT, total_read, chunk_size); while(total_read < chunk_size) { bufsize = MIN(DECOMPRESSION_MAX_BUFSIZE, (chunk_size - total_read)); data = g_malloc0(bufsize); DEBUG("New buffer allocated sized %"G_GINT64_FORMAT" bytes", bufsize); nb_read = 0; current_read = 0; while(nb_read < bufsize) { current_read = comp_ctx->data_uncompressor(cp_chunk, 0, data + nb_read, bufsize - nb_read, &local_error); DEBUG("Currently read %"G_GINT64_FORMAT" bytes", current_read); if(current_read < 0) { if(local_error) { GSETERROR(error, "An error occured while decompressing chunk : %s", local_error->message); g_clear_error(&local_error); } else GSETERROR(error, "An error occured while decompressing chunk\n"); goto end; } else if (current_read == 0) { /* Premature end of file, will still write to pending */ WARN("Read 0 bytes, original chunk may have been truncated"); break; } nb_read += current_read; } TRACE("buffer filled"); errno = 0; /* write buf to dst file */ if(nb_read > 0 && fwrite(data, nb_read, 1, dst) != 1) { GSETERROR(error, "An error occured while writing data in destination file: %s", strerror(errno)); goto end; } if (data) { g_free(data); data = NULL; } if (nb_read > 0) total_read += nb_read; else break; } if(!comp_ctx->integrity_checker(cp_chunk)) { GSETERROR(error, "Seems there is an error in decompression, invalid checksum\n"); goto end; } status = 1; end: if(dst) { if(fclose(dst) != 0) WARN("Failed to fclose destination file"); dst = NULL; } if(status == 1) { if(preserve) { /* Need to set old file info in new file */ TRACE("Updating Access / Modify / Change informations"); struct utimbuf* ut = NULL; ut = g_malloc0(sizeof(struct utimbuf)); ut->actime = buf->st_atime; ut->modtime = buf->st_mtime; chown(tmp_path, buf->st_uid, buf->st_gid); if(utime(tmp_path, ut) != 0) { GSETERROR(error, "Failed to set correct access time to new file"); status = 0; } if(ut) g_free(ut); if(status == 1) { if(rename(tmp_path, path) != 0) { GSETERROR(error, "Failed to rename tmp file"); status = 0; } } else if (keep_pending) { INFO("Temporary file kept: %s", tmp_path); } else { /* remove tmp file */ DEBUG("Removing failed file"); if(remove(tmp_path) != 0) WARN("Failed to remove tmp file [%s]", tmp_path); } } else { DEBUG("Renaming pending file\n"); if(rename(tmp_path, path) != 0) { GSETERROR(error, "Failed to rename tmp file"); status = 0; } } } else if (keep_pending) { INFO("Temporary file kept: %s", tmp_path); } else { /* remove tmp file */ DEBUG("Removing pending file\n"); if(remove(tmp_path) != 0) WARN("Failed to remove tmp file [%s]", tmp_path); } if(compress_opt) g_hash_table_destroy(compress_opt); if(buf) g_free(buf); if(data) g_free(data); if(tmp_path) g_free(tmp_path); return status; }
static gboolean emfe_text_html_format (EMailFormatterExtension *extension, EMailFormatter *formatter, EMailFormatterContext *context, EMailPart *part, GOutputStream *stream, GCancellable *cancellable) { if (g_cancellable_is_cancelled (cancellable)) return FALSE; if (context->mode == E_MAIL_FORMATTER_MODE_RAW) { e_mail_formatter_format_text ( formatter, part, stream, cancellable); } else if (context->mode == E_MAIL_FORMATTER_MODE_PRINTING) { GOutputStream *decoded_stream; GString *string; gchar *pos; GList *tags, *iter; gboolean valid; gchar *tag; const gchar *document_end; gpointer data; gsize length; gint i; decoded_stream = g_memory_output_stream_new_resizable (); /* FORMATTER FIXME: See above */ e_mail_formatter_format_text ( formatter, part, decoded_stream, cancellable); data = g_memory_output_stream_get_data ( G_MEMORY_OUTPUT_STREAM (decoded_stream)); length = g_memory_output_stream_get_data_size ( G_MEMORY_OUTPUT_STREAM (decoded_stream)); string = g_string_new_len ((gchar *) data, length); g_object_unref (decoded_stream); if (!g_utf8_validate (string->str, -1, NULL)) { gchar *valid_utf8; valid_utf8 = e_util_utf8_make_valid (string->str); g_string_free (string, TRUE); string = g_string_new (valid_utf8); g_free (valid_utf8); } tags = NULL; pos = string->str; valid = FALSE; do { gchar *tmp; gchar *closing; gchar *opening; tmp = g_utf8_find_next_char (pos, NULL); pos = g_utf8_strchr (tmp, -1, '<'); if (!pos) break; opening = pos; closing = g_utf8_strchr (pos, -1, '>'); /* Find where the actual tag name begins */ while (tag = g_utf8_find_next_char (pos, NULL), tag != NULL) { gunichar c = g_utf8_get_char (tag); if (!g_unichar_isspace (c)) break; } if (g_ascii_strncasecmp (tag, "style", 5) == 0) { tags = g_list_append ( tags, get_tag (string->str, "style", opening, closing)); } else if (g_ascii_strncasecmp (tag, "script", 6) == 0) { tags = g_list_append ( tags, get_tag (string->str, "script", opening, closing)); } else if (g_ascii_strncasecmp (tag, "link", 4) == 0) { tags = g_list_append ( tags, get_tag (string->str, "link", opening, closing)); } else if (g_ascii_strncasecmp (tag, "body", 4) == 0) { valid = TRUE; break; } } while (pos); /* Something's wrong, let's write the entire HTML and hope * that WebKit can handle it */ if (!valid) { EMailFormatterContext c = { .part_list = context->part_list, .flags = context->flags, .mode = E_MAIL_FORMATTER_MODE_RAW, }; emfe_text_html_format ( extension, formatter, &c, part, stream, cancellable); return FALSE; } /* include the "body" as well -----v */ g_string_erase (string, 0, tag - string->str + 4); g_string_prepend (string, "<div "); for (iter = tags; iter; iter = iter->next) { if (iter->data) g_string_prepend (string, iter->data); } g_list_free_full (tags, g_free); document_end = NULL; /* We can probably use ASCII functions here */ if (g_strrstr (string->str, "</body>")) { document_end = ">ydob/<"; } if (g_strrstr (string->str, "</html>")) { if (document_end) { document_end = ">lmth/<>ydob/<"; } else { document_end = ">lmth/<"; } } if (document_end) { length = strlen (document_end); tag = string->str + string->len - 1; i = 0; valid = FALSE; while (i < length - 1) { gunichar c; c = g_utf8_get_char (tag); if (g_unichar_isspace (c)) { tag = g_utf8_find_prev_char (string->str, tag); continue; } c = g_unichar_tolower (c); if (c == document_end[i]) { tag = g_utf8_find_prev_char (string->str, tag); i++; valid = TRUE; continue; } tag = g_utf8_find_prev_char (string->str, tag); valid = FALSE; } } else { /* do not cut, if there is no end tag */ valid = FALSE; } if (valid) g_string_truncate (string, tag - string->str); g_output_stream_write_all ( stream, string->str, string->len, NULL, cancellable, NULL); g_string_free (string, TRUE); } else {