/*
* Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2003 Hiroyuki Yamamoto
+ * Copyright (C) 1999-2004 Hiroyuki Yamamoto & The Sylpheed-Claws Team
*
* 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
#include <dirent.h>
#include <time.h>
#include <regex.h>
+#include <sys/utsname.h>
#include "intl.h"
#include "utils.h"
gint str_case_equal(gconstpointer v, gconstpointer v2)
{
- return strcasecmp((const gchar *)v, (const gchar *)v2) == 0;
+ return g_strcasecmp((const gchar *)v, (const gchar *)v2) == 0;
}
guint str_case_hash(gconstpointer key)
}
}
+gboolean str_find(const gchar *haystack, const gchar *needle)
+{
+ return strstr(haystack, needle) != NULL ? TRUE : FALSE;
+}
+
+gboolean str_case_find(const gchar *haystack, const gchar *needle)
+{
+ return strcasestr(haystack, needle) != NULL ? TRUE : FALSE;
+}
+
+gboolean str_find_equal(const gchar *haystack, const gchar *needle)
+{
+ return strcmp(haystack, needle) == 0;
+}
+
+gboolean str_case_find_equal(const gchar *haystack, const gchar *needle)
+{
+ return strcasecmp(haystack, needle) == 0;
+}
+
gint to_number(const gchar *nstr)
{
- register const gchar *p;
+ register const guchar *p;
if (*nstr == '\0') return -1;
return NULL;
while (haystack_len >= needle_len) {
- if (!strncasecmp(haystack, needle, needle_len))
+ if (!g_strncasecmp(haystack, needle, needle_len))
return (gchar *)haystack;
else {
haystack++;
return NULL;
}
+gpointer my_memmem(gconstpointer haystack, size_t haystacklen,
+ gconstpointer needle, size_t needlelen)
+{
+ const gchar *haystack_ = (const gchar *)haystack;
+ const gchar *needle_ = (const gchar *)needle;
+ const gchar *haystack_cur = (const gchar *)haystack;
+
+ if (needlelen == 1)
+ return memchr(haystack_, *needle_, haystacklen);
+
+ while ((haystack_cur = memchr(haystack_cur, *needle_, haystacklen))
+ != NULL) {
+ if (haystacklen - (haystack_cur - haystack_) < needlelen)
+ break;
+ if (memcmp(haystack_cur + 1, needle_ + 1, needlelen - 1) == 0)
+ return (gpointer)haystack_cur;
+ else
+ haystack_cur++;
+ }
+
+ return NULL;
+}
+
/* Copy no more than N characters of SRC to DEST, with NULL terminating. */
gchar *strncpy2(gchar *dest, const gchar *src, size_t n)
{
return FALSE;
}
-gint get_next_word_len(const gchar *s)
+gint get_next_word_len(const guchar *s)
{
gint len = 0;
trim_subject_for_sort(str1);
trim_subject_for_sort(str2);
- return strcasecmp(str1, str2);
+ return g_strcasecmp(str1, str2);
}
void trim_subject_for_compare(gchar *str)
void trim_subject(gchar *str)
{
- register gchar *srcp, *destp;
+ register guchar *srcp, *destp;
gchar op, cl;
gint in_brace;
void eliminate_parenthesis(gchar *str, gchar op, gchar cl)
{
- register gchar *srcp, *destp;
+ register guchar *srcp, *destp;
gint in_brace;
srcp = destp = str;
void eliminate_quote(gchar *str, gchar quote_chr)
{
- register gchar *srcp, *destp;
+ register guchar *srcp, *destp;
srcp = destp = str;
void eliminate_address_comment(gchar *str)
{
- register gchar *srcp, *destp;
+ register guchar *srcp, *destp;
gint in_brace;
srcp = destp = str;
void remove_space(gchar *str)
{
- register gchar *p = str;
+ register guchar *p = str;
register gint spc;
while (*p) {
void unfold_line(gchar *str)
{
- register gchar *p = str;
+ register guchar *p = str;
register gint spc;
while (*p) {
subst_chars(str, " \t\r\n\"/\\", '_');
}
+void subst_for_shellsafe_filename(gchar *str)
+{
+ subst_for_filename(str);
+ subst_chars(str, "|&;()<>'!{}[]",'_');
+}
+
gboolean is_header_line(const gchar *str)
{
if (str[0] == ':') return FALSE;
gint get_quote_level(const gchar *str, const gchar *quote_chars)
{
- const gchar *first_pos;
- const gchar *last_pos;
- const gchar *p = str;
+ const guchar *first_pos;
+ const guchar *last_pos;
+ const guchar *p = str;
gint quote_level = -1;
/* speed up line processing by only searching to the last '>' */
if ((first_pos = line_has_quote_char(str, quote_chars)) != NULL) {
/* skip a line if it contains a '<' before the initial '>' */
- if (memchr(str, '<', first_pos - str) != NULL)
+ if (memchr(str, '<', first_pos - (const guchar *)str) != NULL)
return -1;
last_pos = line_has_quote_char_last(first_pos, quote_chars);
} else
n++;
str = s_cl + 1;
- while (*str && isspace(*str)) str++;
+ while (*str && isspace(*(guchar *)str)) str++;
if (*str != op) {
string_list = g_slist_prepend(string_list,
g_strdup(""));
GList *uri_list_extract_filenames(const gchar *uri_list)
{
GList *result = NULL;
- const gchar *p, *q;
+ const guchar *p, *q;
gchar *file;
p = uri_list;
return result;
}
-#define HEX_TO_INT(val, hex) \
-{ \
- gchar c = hex; \
- \
- if ('0' <= c && c <= '9') { \
- val = c - '0'; \
- } else if ('a' <= c && c <= 'f') { \
- val = c - 'a' + 10; \
- } else if ('A' <= c && c <= 'F') { \
- val = c - 'A' + 10; \
- } else { \
- val = 0; \
- } \
+/* Converts two-digit hexadecimal to decimal. Used for unescaping escaped
+ * characters
+ */
+static gint axtoi(const gchar *hexstr)
+{
+ gint hi, lo, result;
+
+ hi = hexstr[0];
+ if ('0' <= hi && hi <= '9') {
+ hi -= '0';
+ } else
+ if ('a' <= hi && hi <= 'f') {
+ hi -= ('a' - 10);
+ } else
+ if ('A' <= hi && hi <= 'F') {
+ hi -= ('A' - 10);
+ }
+
+ lo = hexstr[1];
+ if ('0' <= lo && lo <= '9') {
+ lo -= '0';
+ } else
+ if ('a' <= lo && lo <= 'f') {
+ lo -= ('a'-10);
+ } else
+ if ('A' <= lo && lo <= 'F') {
+ lo -= ('A' - 10);
+ }
+ result = lo + (16 * hi);
+ return result;
+}
+
+gboolean is_uri_string(const gchar *str)
+{
+ return (g_strncasecmp(str, "http://", 7) == 0 ||
+ g_strncasecmp(str, "https://", 8) == 0 ||
+ g_strncasecmp(str, "ftp://", 6) == 0 ||
+ g_strncasecmp(str, "www.", 4) == 0);
+}
+
+gchar *get_uri_path(const gchar *uri)
+{
+ if (g_strncasecmp(uri, "http://", 7) == 0)
+ return (gchar *)(uri + 7);
+ else if (g_strncasecmp(uri, "https://", 8) == 0)
+ return (gchar *)(uri + 8);
+ else if (g_strncasecmp(uri, "ftp://", 6) == 0)
+ return (gchar *)(uri + 6);
+ else
+ return (gchar *)uri;
+}
+
+/* Decodes URL-Encoded strings (i.e. strings in which spaces are replaced by
+ * plusses, and escape characters are used)
+ */
+void decode_uri(gchar *decoded_uri, const gchar *encoded_uri)
+{
+ gchar *dec = decoded_uri;
+ const gchar *enc = encoded_uri;
+
+ while (*enc) {
+ if (*enc == '%') {
+ enc++;
+ if (isxdigit((guchar)enc[0]) &&
+ isxdigit((guchar)enc[1])) {
+ *dec = axtoi(enc);
+ dec++;
+ enc += 2;
+ }
+ } else {
+ if (*enc == '+')
+ *dec = ' ';
+ else
+ *dec = *enc;
+ dec++;
+ enc++;
+ }
+ }
+
+ *dec = '\0';
}
gint scan_mailto_url(const gchar *mailto, gchar **to, gchar **cc, gchar **bcc,
static gchar *domain_name = NULL;
if (!domain_name) {
- gchar buf[128] = "";
struct hostent *hp;
+ struct utsname uts;
- if (gethostname(buf, sizeof(buf)) < 0) {
+ if (uname(&uts) < 0) {
perror("gethostname");
domain_name = "unknown";
} else {
- buf[sizeof(buf) - 1] = '\0';
- if ((hp = my_gethostbyname(buf)) == NULL) {
+ if ((hp = my_gethostbyname(uts.nodename)) == NULL) {
perror("gethostbyname");
- domain_name = g_strdup(buf);
+ domain_name = g_strdup(uts.nodename);
} else {
domain_name = g_strdup(hp->h_name);
}
return TRUE;
}
+gboolean dirent_is_regular_file(struct dirent *d)
+{
+ struct stat s;
+
+#ifdef HAVE_DIRENT_D_TYPE
+ if (d->d_type == DT_REG)
+ return TRUE;
+ else if (d->d_type != DT_UNKNOWN)
+ return FALSE;
+#endif
+
+ return (stat(d->d_name, &s) == 0 && S_ISREG(s.st_mode));
+}
+
+gboolean dirent_is_directory(struct dirent *d)
+{
+ struct stat s;
+
+#ifdef HAVE_DIRENT_D_TYPE
+ if (d->d_type == DT_DIR)
+ return TRUE;
+ else if (d->d_type != DT_UNKNOWN)
+ return FALSE;
+#endif
+
+ return (stat(d->d_name, &s) == 0 && S_ISDIR(s.st_mode));
+}
+
gint change_dir(const gchar *dir)
{
gchar *prevdir = NULL;
!strcmp(d->d_name, ".."))
continue;
- if (stat(d->d_name, &s) < 0) {
- FILE_OP_ERROR(d->d_name, "stat");
- continue;
- }
-
/* g_print("removing %s\n", d->d_name); */
- if (S_ISDIR(s.st_mode)) {
+ if (dirent_is_directory(d)) {
if (remove_dir_recursive(d->d_name) < 0) {
g_warning("can't remove directory\n");
return -1;
return 0;
}
-gint copy_file_part(FILE *fp, off_t offset, size_t length, const gchar *dest)
+gint copy_file_part_to_fp(FILE *fp, off_t offset, size_t length, FILE *dest_fp)
{
- FILE *dest_fp;
gint n_read;
gint bytes_left, to_read;
gchar buf[BUFSIZ];
- gboolean err = FALSE;
if (fseek(fp, offset, SEEK_SET) < 0) {
perror("fseek");
return -1;
}
- if ((dest_fp = fopen(dest, "wb")) == NULL) {
- FILE_OP_ERROR(dest, "fopen");
- return -1;
- }
-
- if (change_file_mode_rw(dest_fp, dest) < 0) {
- FILE_OP_ERROR(dest, "chmod");
- g_warning("can't change file mode\n");
- }
-
bytes_left = length;
to_read = MIN(bytes_left, sizeof(buf));
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);
- fclose(dest_fp);
- unlink(dest);
return -1;
}
bytes_left -= n_read;
if (ferror(fp)) {
perror("fread");
- err = TRUE;
+ return -1;
}
- if (fclose(dest_fp) == EOF) {
+
+ return 0;
+}
+
+gint copy_file_part(FILE *fp, off_t offset, size_t length, const gchar *dest)
+{
+ FILE *dest_fp;
+ gboolean err = FALSE;
+
+ if ((dest_fp = fopen(dest, "wb")) == NULL) {
+ FILE_OP_ERROR(dest, "fopen");
+ return -1;
+ }
+
+ if (change_file_mode_rw(dest_fp, dest) < 0) {
+ FILE_OP_ERROR(dest, "chmod");
+ g_warning("can't change file mode\n");
+ }
+
+ if (copy_file_part_to_fp(fp, offset, length, dest_fp) < 0)
+ err = TRUE;
+
+ if (!err && fclose(dest_fp) == EOF) {
FILE_OP_ERROR(dest, "fclose");
err = TRUE;
}
if (err) {
+ g_warning("writing to %s failed.\n", dest);
unlink(dest);
return -1;
}
* doesn't do any harm.
*/
for (i = 0; i < sizeof(buf_uniq) - 1; i++)
- buf_uniq[i] = tbl[(random() ^ pid) % (sizeof(tbl) - 1)];
+ buf_uniq[i] = tbl[(rand() ^ pid) % (sizeof(tbl) - 1)];
buf_uniq[i] = '\0';
get_rfc822_date(buf_date, sizeof(buf_date));
subst_char(buf_date, ',', '_');
subst_char(buf_date, ':', '_');
- return g_strdup_printf("%s=_%s_%s", prefix ? prefix : "Multipart",
+ return g_strdup_printf("%s_%s_%s", prefix ? prefix : "Multipart",
buf_date, buf_uniq);
}
tmpdir = get_tmp_dir();
tmplen = strlen(tmpdir);
progname = g_get_prgname();
+ if (progname == NULL)
+ progname = "sylpheed-claws";
proglen = strlen(progname);
Xalloca(fname, tmplen + 1 + proglen + sizeof(suffix),
return tmpfile());
return tmpfile();
}
+FILE *get_tmpfile_in_dir(const gchar *dir, gchar **filename)
+{
+ int fd;
+
+ *filename = g_strdup_printf("%s%csylpheed.XXXXXX", dir, G_DIR_SEPARATOR);
+ fd = mkstemp(*filename);
+
+ return fdopen(fd, "w+");
+}
+
FILE *str_open_as_stream(const gchar *str)
{
FILE *fp;
gint execute_async(gchar *const argv[])
{
pid_t pid;
+ gint status;
if ((pid = fork()) < 0) {
perror("fork");
_exit(0);
}
- waitpid(pid, NULL, 0);
+ waitpid(pid, &status, 0);
- return 0;
+ if (WIFEXITED(status))
+ return WEXITSTATUS(status);
+ else
+ return -1;
}
gint execute_sync(gchar *const argv[])
{
pid_t pid;
+ gint status;
if ((pid = fork()) < 0) {
perror("fork");
_exit(1);
}
- waitpid(pid, NULL, 0);
+ waitpid(pid, &status, 0);
- return 0;
+ if (WIFEXITED(status))
+ return WEXITSTATUS(status);
+ else
+ return -1;
}
gint execute_command_line(const gchar *cmdline, gboolean async)
gchar **argv;
gint ret;
+ debug_print("executing: %s\n", cmdline);
+
argv = strsplit_with_quote(cmdline, " ", 0);
if (async)
ret = execute_async(argv);
else
ret = execute_sync(argv);
+
g_strfreev(argv);
return ret;
encoded_uri[k] = 0;
}
-/* Converts two-digit hexadecimal to decimal. Used for unescaping escaped
- * characters
- */
-static gint axtoi(const gchar *hexstr)
-{
- gint hi, lo, result;
-
- hi = hexstr[0];
- if ('0' <= hi && hi <= '9') {
- hi -= '0';
- } else
- if ('a' <= hi && hi <= 'f') {
- hi -= ('a' - 10);
- } else
- if ('A' <= hi && hi <= 'F') {
- hi -= ('A' - 10);
- }
-
- lo = hexstr[1];
- if ('0' <= lo && lo <= '9') {
- lo -= '0';
- } else
- if ('a' <= lo && lo <= 'f') {
- lo -= ('a'-10);
- } else
- if ('A' <= lo && lo <= 'F') {
- lo -= ('A' - 10);
- }
- result = lo + (16 * hi);
- return result;
-}
-
-
-/* Decodes URL-Encoded strings (i.e. strings in which spaces are replaced by
- * plusses, and escape characters are used)
- */
-
-void decode_uri(gchar *decoded_uri, const gchar *encoded_uri)
-{
- const gchar *encoded;
- gchar *decoded;
-
- encoded = encoded_uri;
- decoded = decoded_uri;
-
- while (*encoded) {
- if (*encoded == '%') {
- encoded++;
- if (isxdigit(encoded[0])
- && isxdigit(encoded[1])) {
- *decoded = (gchar) axtoi(encoded);
- decoded++;
- encoded += 2;
- }
- }
- else if (*encoded == '+') {
- *decoded = ' ';
- decoded++;
- encoded++;
- }
- else {
- *decoded = *encoded;
- decoded++;
- encoded++;
- }
- }
-
- *decoded = '\0';
-}
-
-
gint open_uri(const gchar *uri, const gchar *cmdline)
{
gchar buf[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 "
+ "(there must be only one '%%s'): %s",
cmdline);
g_snprintf(buf, sizeof(buf), DEFAULT_BROWSER_CMD, encoded_uri);
}
-
+
execute_command_line(buf, TRUE);
return 0;
remoteoffset = 0;
} else if (strlen(zone3) == 3) {
for (p = ustzstr; *p != '\0'; p += 3) {
- if (!strncasecmp(p, zone3, 3)) {
+ if (!g_strncasecmp(p, zone3, 3)) {
iustz = ((gint)(p - ustzstr) / 3 + 1) / 2 - 8;
remoteoffset = iustz * 3600;
break;
"Antwort\\:", /* "Antwort:" (German Lotus Notes) */
"Res\\:", /* "Res:" (Brazilian Outlook) */
"Fw\\:", /* "Fw:" Forward */
- "Enc\\:" /* "Enc:" Forward (Brazilian Outlook) */
+ "Enc\\:", /* "Enc:" Forward (Brazilian Outlook) */
+ "Odp\\:", /* "Odp:" Re (Polish Outlook) */
+ "Rif\\:" /* "Rif:" (Italian Outlook) */
/* add more */
};
const int PREFIXES = sizeof prefixes / sizeof prefixes[0];
return 0;
}
-FILE *get_tmpfile_in_dir(const gchar *dir, gchar **filename)
-{
- int fd;
-
- *filename = g_strdup_printf("%s%csylpheed.XXXXXX", dir, G_DIR_SEPARATOR);
- fd = mkstemp(*filename);
-
- 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 + ' ');
+ if (isupper((guchar)*str)) hash_result += (*str + ' ');
else hash_result += *str;
}
const char *str1 = gptr1;
const char *str2 = gptr2;
- return !strcasecmp(str1, str2);
+ return !g_strcasecmp(str1, str2);
}
gint g_int_compare(gconstpointer a, gconstpointer b)
return GPOINTER_TO_INT(a) - GPOINTER_TO_INT(b);
}
-gchar *generate_msgid(const gchar *address, gchar *buf, gint len)
+gchar *generate_msgid(gchar *buf, gint len)
{
- /* steal from compose.c::compose_generate_msgid() */
struct tm *lt;
time_t t;
gchar *addr;
t = time(NULL);
lt = localtime(&t);
- if (address && *address) {
- if (strchr(address, '@'))
- addr = g_strdup(address);
- else
- addr = g_strconcat(address, "@", get_domain_name(), NULL);
- } else
- addr = g_strconcat(g_get_user_name(), "@", get_domain_name(),
- NULL);
+ addr = g_strconcat("@", get_domain_name(), NULL);
- g_snprintf(buf, len, "%04d%02d%02d%02d%02d%02d.%08x.%s",
+ g_snprintf(buf, len, "%04d%02d%02d%02d%02d%02d.%08x%s",
lt->tm_year + 1900, lt->tm_mon + 1,
lt->tm_mday, lt->tm_hour,
lt->tm_min, lt->tm_sec,
- (guint)random(), addr);
+ (guint) rand(), addr);
g_free(addr);
return buf;
}
+
+
+/*
+ quote_cmd_argument()
+
+ return a quoted string safely usable in argument of a command.
+
+ code is extracted and adapted from etPan! project -- DINH V. HoĆ .
+*/
+
+gint quote_cmd_argument(gchar * result, guint size,
+ const gchar * path)
+{
+ const gchar * p;
+ gchar * result_p;
+ guint remaining;
+
+ result_p = result;
+ remaining = size;
+
+ for(p = path ; * p != '\0' ; p ++) {
+
+ if (isalnum((guchar)*p) || (* p == '/')) {
+ if (remaining > 0) {
+ * result_p = * p;
+ result_p ++;
+ remaining --;
+ }
+ else {
+ result[size - 1] = '\0';
+ return -1;
+ }
+ }
+ else {
+ if (remaining >= 2) {
+ * result_p = '\\';
+ result_p ++;
+ * result_p = * p;
+ result_p ++;
+ remaining -= 2;
+ }
+ else {
+ result[size - 1] = '\0';
+ return -1;
+ }
+ }
+ }
+ if (remaining > 0) {
+ * result_p = '\0';
+ }
+ else {
+ result[size - 1] = '\0';
+ return -1;
+ }
+
+ return 0;
+}
+
+typedef struct
+{
+ GNode *parent;
+ GNodeMapFunc func;
+ gpointer data;
+} GNodeMapData;
+
+static void g_node_map_recursive(GNode *node, gpointer data)
+{
+ GNodeMapData *mapdata = (GNodeMapData *) data;
+ GNode *newnode;
+ GNodeMapData newmapdata;
+ gpointer newdata;
+
+ newdata = mapdata->func(node->data, mapdata->data);
+ if (newdata != NULL) {
+ newnode = g_node_new(newdata);
+ g_node_append(mapdata->parent, newnode);
+
+ newmapdata.parent = newnode;
+ newmapdata.func = mapdata->func;
+ newmapdata.data = mapdata->data;
+
+ g_node_children_foreach(node, G_TRAVERSE_ALL, g_node_map_recursive, &newmapdata);
+ }
+}
+
+GNode *g_node_map(GNode *node, GNodeMapFunc func, gpointer data)
+{
+ GNode *root;
+ GNodeMapData mapdata;
+
+ g_return_val_if_fail(node != NULL, NULL);
+ g_return_val_if_fail(func != NULL, NULL);
+
+ root = g_node_new(func(node->data, data));
+
+ mapdata.parent = root;
+ mapdata.func = func;
+ mapdata.data = data;
+
+ g_node_children_foreach(node, G_TRAVERSE_ALL, g_node_map_recursive, &mapdata);
+
+ return root;
+}
+
+#define HEX_TO_INT(val, hex) \
+{ \
+ gchar c = hex; \
+ \
+ if ('0' <= c && c <= '9') { \
+ val = c - '0'; \
+ } else if ('a' <= c && c <= 'f') { \
+ val = c - 'a' + 10; \
+ } else if ('A' <= c && c <= 'F') { \
+ val = c - 'A' + 10; \
+ } else { \
+ val = -1; \
+ } \
+}
+
+gboolean get_hex_value(guchar *out, gchar c1, gchar c2)
+{
+ gint hi, lo;
+
+ HEX_TO_INT(hi, c1);
+ HEX_TO_INT(lo, c2);
+
+ if (hi == -1 || lo == -1)
+ return FALSE;
+
+ *out = (hi << 4) + lo;
+ return TRUE;
+}
+
+#define INT_TO_HEX(hex, val) \
+{ \
+ if ((val) < 10) \
+ hex = '0' + (val); \
+ else \
+ hex = 'A' + (val) - 10; \
+}
+
+void get_hex_str(gchar *out, guchar ch)
+{
+ gchar hex;
+
+ INT_TO_HEX(hex, ch >> 4);
+ *out++ = hex;
+ INT_TO_HEX(hex, ch & 0x0f);
+ *out++ = hex;
+}