/*
* Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2002 Hiroyuki Yamamoto
+ * Copyright (C) 1999-2003 Hiroyuki Yamamoto
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
}
/* Examine if next block is non-ASCII string */
-gboolean is_next_nonascii(const wchar_t *s)
+gboolean is_next_nonascii(const guchar *s)
{
- const wchar_t *wp;
+ const guchar *p;
/* skip head space */
- for (wp = s; *wp != (wchar_t)0 && iswspace(*wp); wp++)
+ for (p = s; *p != '\0' && isspace(*p); p++)
;
- for (; *wp != (wchar_t)0 && !iswspace(*wp); wp++) {
- if (*wp > 127)
+ for (; *p != '\0' && !isspace(*p); p++) {
+ if (*p > 127 || *p < 32)
return TRUE;
}
return FALSE;
}
-/* Examine if next block is multi-byte string */
-gboolean is_next_mbs(const wchar_t *s)
+gint get_next_word_len(const gchar *s)
{
- gint mbl;
- const wchar_t *wp;
- gchar tmp[MB_LEN_MAX];
+ gint len = 0;
- /* skip head space */
- for (wp = s; *wp != (wchar_t)0 && iswspace(*wp); wp++)
- ;
- for (; *wp != (wchar_t)0 && !iswspace(*wp); wp++) {
- mbl = wctomb(tmp, *wp);
- if (mbl > 1)
- return TRUE;
- }
-
- return FALSE;
-}
-
-wchar_t *find_wspace(const wchar_t *s)
-{
- const wchar_t *wp;
-
- for (wp = s; *wp != (wchar_t)0 && iswspace(*wp); wp++)
+ for (; *s != '\0' && !isspace(*s); s++, len++)
;
- for (; *wp != (wchar_t)0; wp++) {
- if (iswspace(*wp))
- return (wchar_t *)wp;
- }
- return NULL;
+ return len;
}
/* compare subjects */
gchar *abbrev_group;
gchar *ap;
const gchar *p = group;
- gint count = 0;
+ const gchar *last;
+ last = group + strlen(group);
abbrev_group = ap = g_malloc(strlen(group) + 1);
while (*p) {
while (*p == '.')
*ap++ = *p++;
-
- if ((strlen( p) + count) > len && strchr(p, '.')) {
+ if ((ap - abbrev_group) + (last - p) > len && strchr(p, '.')) {
*ap++ = *p++;
while (*p != '.') p++;
} else {
- strcpy( ap, p);
+ strcpy(ap, p);
return abbrev_group;
}
- count = count + 2;
}
*ap = '\0';
while (len > 0) {
n_write = write(dest_fd, bufp, len);
if (n_write <= 0) {
- g_warning(_("writing to %s failed.\n"), dest);
+ g_warning("writing to %s failed.\n", dest);
close(dest_fd);
close(src_fd);
unlink(dest);
close(dest_fd);
if (n_read < 0 || get_file_size(src) != get_file_size(dest)) {
- g_warning(_("File copy from %s to %s failed.\n"), src, dest);
+ g_warning("File copy from %s to %s failed.\n", src, dest);
unlink(dest);
if (dest_bak) {
if (rename(dest_bak, dest) < 0)
if (change_file_mode_rw(dest_fp, dest) < 0) {
FILE_OP_ERROR(dest, "chmod");
- g_warning(_("can't change file mode\n"));
+ g_warning("can't change file mode\n");
}
while ((n_read = fread(buf, sizeof(gchar), sizeof(buf), src_fp)) > 0) {
if (n_read < sizeof(buf) && ferror(src_fp))
break;
if (fwrite(buf, n_read, 1, dest_fp) < 1) {
- g_warning(_("writing to %s failed.\n"), dest);
+ g_warning("writing to %s failed.\n", dest);
fclose(dest_fp);
fclose(src_fp);
unlink(dest);
if (change_file_mode_rw(dest_fp, dest) < 0) {
FILE_OP_ERROR(dest, "chmod");
- g_warning(_("can't change file mode\n"));
+ g_warning("can't change file mode\n");
}
while ((n_read = fread(buf, sizeof(gchar), sizeof(buf), src_fp)) > 0) {
if (n_read < sizeof(buf) && ferror(src_fp))
break;
if (fwrite(buf, n_read, 1, dest_fp) < 1) {
- g_warning(_("writing to %s failed.\n"), dest);
+ g_warning("writing to %s failed.\n", dest);
fclose(dest_fp);
fclose(src_fp);
unlink(dest);
if (n_read < to_read && ferror(fp))
break;
if (fwrite(buf, n_read, 1, dest_fp) < 1) {
- g_warning(_("writing to %s failed.\n"), dest);
+ g_warning("writing to %s failed.\n", dest);
fclose(dest_fp);
unlink(dest);
return -1;
/* convert line endings into CRLF. If the last line doesn't end with
* linebreak, add it.
*/
+gchar *canonicalize_str(const gchar *str)
+{
+ const gchar *p;
+ guint new_len = 0;
+ gchar *out, *outp;
+
+ for (p = str; *p != '\0'; ++p) {
+ if (*p != '\r') {
+ ++new_len;
+ if (*p == '\n')
+ ++new_len;
+ }
+ }
+ if (p == str || *(p - 1) != '\n')
+ new_len += 2;
+
+ out = outp = g_malloc(new_len + 1);
+ for (p = str; *p != '\0'; ++p) {
+ if (*p != '\r') {
+ if (*p == '\n')
+ *outp++ = '\r';
+ *outp++ = *p;
+ }
+ }
+ if (p == str || *(p - 1) != '\n') {
+ *outp++ = '\r';
+ *outp++ = '\n';
+ }
+ *outp = '\0';
+
+ return out;
+}
+
gint canonicalize_file(const gchar *src, const gchar *dest)
{
FILE *src_fp, *dest_fp;
}
if (ferror(src_fp)) {
- FILE_OP_ERROR(src, "fread");
+ FILE_OP_ERROR(src, "fgets");
err = TRUE;
}
fclose(src_fp);
return 0;
}
+gint uncanonicalize_file(const gchar *src, const gchar *dest)
+{
+ FILE *src_fp, *dest_fp;
+ gchar buf[BUFFSIZE];
+ gboolean err = FALSE;
+
+ if ((src_fp = fopen(src, "rb")) == NULL) {
+ FILE_OP_ERROR(src, "fopen");
+ return -1;
+ }
+
+ if ((dest_fp = fopen(dest, "wb")) == NULL) {
+ FILE_OP_ERROR(dest, "fopen");
+ fclose(src_fp);
+ return -1;
+ }
+
+ if (change_file_mode_rw(dest_fp, dest) < 0) {
+ FILE_OP_ERROR(dest, "chmod");
+ g_warning("can't change file mode\n");
+ }
+
+ while (fgets(buf, sizeof(buf), src_fp) != NULL) {
+ strcrchomp(buf);
+ if (fputs(buf, dest_fp) == EOF) {
+ g_warning("writing to %s failed.\n", dest);
+ fclose(dest_fp);
+ fclose(src_fp);
+ unlink(dest);
+ return -1;
+ }
+ }
+
+ if (ferror(src_fp)) {
+ FILE_OP_ERROR(src, "fgets");
+ err = TRUE;
+ }
+ fclose(src_fp);
+ if (fclose(dest_fp) == EOF) {
+ FILE_OP_ERROR(dest, "fclose");
+ err = TRUE;
+ }
+
+ if (err) {
+ unlink(dest);
+ return -1;
+ }
+
+ return 0;
+}
+
+gint uncanonicalize_file_replace(const gchar *file)
+{
+ gchar *tmp_file;
+
+ tmp_file = get_tmp_file();
+
+ if (uncanonicalize_file(file, tmp_file) < 0) {
+ g_free(tmp_file);
+ return -1;
+ }
+
+ if (move_file(tmp_file, file, TRUE) < 0) {
+ g_warning("can't replace %s .\n", file);
+ unlink(tmp_file);
+ g_free(tmp_file);
+ return -1;
+ }
+
+ g_free(tmp_file);
+ return 0;
+}
+
gint change_file_mode_rw(FILE *fp, const gchar *file)
{
#if HAVE_FCHMOD
gint open_uri(const gchar *uri, const gchar *cmdline)
{
- static gchar *default_cmdline = "netscape -remote openURL(%s,raise)";
gchar buf[BUFFSIZE];
gchar *p;
gchar encoded_uri[BUFFSIZE];
g_snprintf(buf, sizeof(buf), cmdline, encoded_uri);
else {
if (cmdline)
- g_warning(_("Open URI command line is invalid: `%s'"),
+ g_warning("Open URI command line is invalid: `%s'",
cmdline);
- g_snprintf(buf, sizeof(buf), default_cmdline, encoded_uri);
+ g_snprintf(buf, sizeof(buf), DEFAULT_BROWSER_CMD, encoded_uri);
}
execute_command_line(buf, TRUE);
return fdopen(fd, "w+");
}
+
+/* allow Mutt-like patterns in quick search */
+gchar *expand_search_string(const gchar *search_string)
+{
+ int i = 0;
+ gchar term_char, save_char;
+ gchar *cmd_start, *cmd_end;
+ GString *matcherstr;
+ gchar *returnstr = NULL;
+ gchar *copy_str;
+ gboolean casesens, dontmatch;
+ /* list of allowed pattern abbreviations */
+ struct {
+ gchar *abbreviated; /* abbreviation */
+ gchar *command; /* actual matcher command */
+ gint numparams; /* number of params for cmd */
+ gboolean qualifier; /* do we append regexpcase */
+ gboolean quotes; /* do we need quotes */
+ }
+ cmds[] = {
+ { "a", "all", 0, FALSE, FALSE },
+ { "ag", "age_greater", 1, FALSE, FALSE },
+ { "al", "age_lower", 1, FALSE, FALSE },
+ { "b", "body_part", 1, TRUE, TRUE },
+ { "B", "message", 1, TRUE, TRUE },
+ { "c", "cc", 1, TRUE, TRUE },
+ { "C", "to_or_cc", 1, TRUE, TRUE },
+ { "D", "deleted", 0, FALSE, FALSE },
+ { "e", "header \"Sender\"", 1, TRUE, TRUE },
+ { "E", "execute", 1, FALSE, TRUE },
+ { "f", "from", 1, TRUE, TRUE },
+ { "F", "forwarded", 0, FALSE, FALSE },
+ { "h", "headers_part", 1, TRUE, TRUE },
+ { "i", "header \"Message-Id\"", 1, TRUE, TRUE },
+ { "I", "inreplyto", 1, TRUE, TRUE },
+ { "L", "locked", 0, FALSE, FALSE },
+ { "n", "newsgroups", 1, TRUE, TRUE },
+ { "N", "new", 0, FALSE, FALSE },
+ { "O", "~new", 0, FALSE, FALSE },
+ { "r", "replied", 0, FALSE, FALSE },
+ { "R", "~unread", 0, FALSE, FALSE },
+ { "s", "subject", 1, TRUE, TRUE },
+ { "se", "score_equal", 1, FALSE, FALSE },
+ { "sg", "score_greater", 1, FALSE, FALSE },
+ { "sl", "score_lower", 1, FALSE, FALSE },
+ { "Se", "size_equal", 1, FALSE, FALSE },
+ { "Sg", "size_greater", 1, FALSE, FALSE },
+ { "Ss", "size_smaller", 1, FALSE, FALSE },
+ { "t", "to", 1, TRUE, TRUE },
+ { "T", "marked", 0, FALSE, FALSE },
+ { "U", "unread", 0, FALSE, FALSE },
+ { "x", "header \"References\"", 1, TRUE, TRUE },
+ { "y", "header \"X-Label\"", 1, TRUE, TRUE },
+ { "&", "&", 0, FALSE, FALSE },
+ { "|", "|", 0, FALSE, FALSE },
+ { NULL, NULL, 0, FALSE, FALSE }
+ };
+
+ if (search_string == NULL)
+ return NULL;
+
+ copy_str = g_strdup(search_string);
+
+ /* if it's a full command don't process it so users
+ can still do something like from regexpcase "foo" */
+ for (i = 0; cmds[i].command; i++) {
+ const gchar *tmp_search_string = search_string;
+ cmd_start = cmds[i].command;
+ /* allow logical NOT */
+ if (*tmp_search_string == '~')
+ tmp_search_string++;
+ if (!strncmp(tmp_search_string, cmd_start, strlen(cmd_start)))
+ break;
+ }
+ if (cmds[i].command)
+ return copy_str;
+
+ matcherstr = g_string_sized_new(16);
+ cmd_start = cmd_end = copy_str;
+ while (cmd_end && *cmd_end) {
+ /* skip all white spaces */
+ while (*cmd_end && isspace(*cmd_end))
+ cmd_end++;
+
+ /* extract a command */
+ while (*cmd_end && !isspace(*cmd_end))
+ cmd_end++;
+
+ /* save character */
+ save_char = *cmd_end;
+ *cmd_end = '\0';
+
+ dontmatch = FALSE;
+ casesens = FALSE;
+
+ /* ~ and ! mean logical NOT */
+ if (*cmd_start == '~' || *cmd_start == '!')
+ {
+ dontmatch = TRUE;
+ cmd_start++;
+ }
+ /* % means case sensitive match */
+ if (*cmd_start == '%')
+ {
+ casesens = TRUE;
+ cmd_start++;
+ }
+
+ /* find matching abbreviation */
+ for (i = 0; cmds[i].command; i++) {
+ if (!strcmp(cmd_start, cmds[i].abbreviated)) {
+ /* restore character */
+ *cmd_end = save_char;
+
+ /* copy command */
+ if (matcherstr->len > 0) {
+ g_string_append(matcherstr, " ");
+ }
+ if (dontmatch)
+ g_string_append(matcherstr, "~");
+ g_string_append(matcherstr, cmds[i].command);
+ g_string_append(matcherstr, " ");
+
+ /* stop if no params required */
+ if (cmds[i].numparams == 0)
+ break;
+
+ /* extract a parameter, allow quotes */
+ cmd_end++;
+ cmd_start = cmd_end;
+ if (*cmd_start == '"') {
+ term_char = '"';
+ cmd_end++;
+ }
+ else
+ term_char = ' ';
+
+ /* extract actual parameter */
+ while ((*cmd_end) && (*cmd_end != term_char))
+ cmd_end++;
+
+ if (*cmd_end && (*cmd_end != term_char))
+ break;
+
+ if (*cmd_end == '"')
+ cmd_end++;
+
+ save_char = *cmd_end;
+ *cmd_end = '\0';
+
+ if (cmds[i].qualifier) {
+ if (casesens)
+ g_string_append(matcherstr, "regexp ");
+ else
+ g_string_append(matcherstr, "regexpcase ");
+ }
+
+ /* do we need to add quotes ? */
+ if (cmds[i].quotes && term_char != '"')
+ g_string_append(matcherstr, "\"");
+
+ /* copy actual parameter */
+ g_string_append(matcherstr, cmd_start);
+
+ /* do we need to add quotes ? */
+ if (cmds[i].quotes && term_char != '"')
+ g_string_append(matcherstr, "\"");
+
+ /* restore original character */
+ *cmd_end = save_char;
+
+ break;
+ }
+ }
+
+ if (*cmd_end) {
+ cmd_end++;
+ cmd_start = cmd_end;
+ }
+ }
+
+ g_free(copy_str);
+ returnstr = matcherstr->str;
+ g_string_free(matcherstr, FALSE);
+ return returnstr;
+}
+
+guint g_stricase_hash(gconstpointer gptr)
+{
+ guint hash_result = 0;
+ const char *str;
+
+ for (str = gptr; str && *str; str++) {
+ if (isupper(*str)) hash_result += (*str + ' ');
+ else hash_result += *str;
+ }
+
+ return hash_result;
+}
+
+gint g_stricase_equal(gconstpointer gptr1, gconstpointer gptr2)
+{
+ const char *str1 = gptr1;
+ const char *str2 = gptr2;
+
+ return !strcasecmp(str1, str2);
+}
+