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;
  }
}
示例#3
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;
}
示例#4
0
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;
  }
}
示例#5
0
/*
 * 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;
}
示例#6
0
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;
}
示例#7
0
EXPORT bool_t str_has_prefix_nocase (const char * str, const char * prefix)
{
    return ! g_ascii_strncasecmp (str, prefix, strlen (prefix));
}
示例#8
0
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;
}
示例#9
0
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;
}
示例#10
0
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;
}
示例#11
0
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 "";
}
示例#12
0
/*
 * 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;
}
示例#13
0
/**
 * 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;
}
示例#14
0
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);
}
示例#15
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;
}
示例#16
0
文件: ctcp.c 项目: Cynede/hexchat
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);
	}
}
示例#17
0
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;
}
示例#18
0
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;
}
示例#19
0
/*
 * 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;
}
示例#21
0
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);
  }
}
示例#22
0
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 &lt;<a href="/pks/lookup?op=get&search=0x3CB3B415">[email protected]</a>&gt; */

	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; 
}
示例#23
0
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;
}
示例#24
0
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);
}
示例#25
0
文件: proto-irc.c 项目: N3X15/hexchat
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]);
}
示例#26
0
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);
}
示例#27
0
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;
}
示例#28
0
/*
 * 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;
}
示例#29
0
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 {