gint mkstemp_name(const gchar *template, gchar **name_used)
{
static gulong count=0; /* W32-_mktemp only supports up to 27
- tempfiles... */
+ tempfiles... */
int tmpfd;
*name_used = g_strdup_printf("%s.%ld",_mktemp(template),count++);
tmpfd = open (*name_used, (O_CREAT | O_RDWR | O_BINARY),
- (S_IRUSR | S_IWUSR));
+ (S_IRUSR | S_IWUSR));
tempfiles=g_slist_append(tempfiles, g_strdup(*name_used));
if (tmpfd<0) {
return itos_buf(nstr, n);
}
+#define divide(num,divisor,i,d) \
+{ \
+ register int tmp; \
+ i = num/divisor; \
+ tmp = i*divisor; \
+ d = num-tmp; \
+ if (d > 1000) d /= 1000; \
+ else if (d > 100) d /= 100; \
+ else if (d > 10) d /= 10; \
+}
+
gchar *to_human_readable(off_t size)
{
static gchar str[14];
-
- if (size < 1024)
- g_snprintf(str, sizeof(str), _("%dB"), (gint)size);
- else if (size >> 10 < 1024)
- g_snprintf(str, sizeof(str), _("%.1fKB"), (gfloat)size / (1 << 10));
- else if (size >> 20 < 1024)
- g_snprintf(str, sizeof(str), _("%.2fMB"), (gfloat)size / (1 << 20));
- else
- g_snprintf(str, sizeof(str), _("%.2fGB"), (gfloat)size / (1 << 30));
-
- return str;
+ static gchar *b_format = NULL, *kb_format = NULL,
+ *mb_format = NULL, *gb_format = NULL;
+ register int t = 0, r = 0;
+ if (b_format == NULL) {
+ b_format = _("%dB");
+ kb_format = _("%d.%dKB");
+ mb_format = _("%.2fMB");
+ gb_format = _("%.2fGB");
+ }
+
+ if (size < 1024) {
+ g_snprintf(str, sizeof(str), b_format, (gint)size);
+ return str;
+ } else if (size >> 10 < 1024) {
+ divide(size, (1 << 10), t, r);
+ g_snprintf(str, sizeof(str), kb_format, t, r);
+ return str;
+ } else if (size >> 20 < 1024) {
+ g_snprintf(str, sizeof(str), mb_format, (gfloat)size / (1 << 20));
+ return str;
+ } else {
+ g_snprintf(str, sizeof(str), gb_format, (gfloat)size / (1 << 30));
+ return str;
+ }
}
/* strcmp with NULL-checking */
gint path_cmp(const gchar *s1, const gchar *s2)
{
gint len1, len2;
- int rc;
+ int rc;
#ifdef G_OS_WIN32
- gchar *s1buf, *s2buf;
+ gchar *s1buf, *s2buf;
#endif
if (s1 == NULL || s2 == NULL) return -1;
if (*s1 == '\0' || *s2 == '\0') return -1;
#ifdef G_OS_WIN32
- s1buf = g_strdup (s1);
- s2buf = g_strdup (s2);
- subst_char (s1buf, '/', G_DIR_SEPARATOR);
- subst_char (s2buf, '/', G_DIR_SEPARATOR);
- s1 = s1buf;
- s2 = s2buf;
+ s1buf = g_strdup (s1);
+ s2buf = g_strdup (s2);
+ subst_char (s1buf, '/', G_DIR_SEPARATOR);
+ subst_char (s2buf, '/', G_DIR_SEPARATOR);
+ s1 = s1buf;
+ s2 = s2buf;
#endif /* !G_OS_WIN32 */
len1 = strlen(s1);
rc = strncmp(s1, s2, MAX(len1, len2));
#ifdef G_OS_WIN32
- g_free (s1buf);
- g_free (s2buf);
+ g_free (s1buf);
+ g_free (s2buf);
#endif /* !G_OS_WIN32 */
- return rc;
+ return rc;
}
/* remove trailing return code */
strncpy(escaped_utf8uri, p, q - p + 1);
escaped_utf8uri[q - p + 1] = '\0';
decode_uri(file, escaped_utf8uri);
- /*
+ /*
* g_filename_from_uri() rejects escaped/locale encoded uri
* string which come from Nautilus.
*/
gboolean is_uri_string(const gchar *str)
{
+ while (str && *str && g_ascii_isspace(*str))
+ str++;
return (g_ascii_strncasecmp(str, "http://", 7) == 0 ||
g_ascii_strncasecmp(str, "https://", 8) == 0 ||
g_ascii_strncasecmp(str, "ftp://", 6) == 0 ||
gchar *get_uri_path(const gchar *uri)
{
+ while (uri && *uri && g_ascii_isspace(*uri))
+ uri++;
if (g_ascii_strncasecmp(uri, "http://", 7) == 0)
return (gchar *)(uri + 7);
else if (g_ascii_strncasecmp(uri, "https://", 8) == 0)
if (w32_errno == 0)
w32_errno = ec;
FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM, NULL, w32_errno,
- MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
- strerr, DIM (strerr)-1, NULL);
+ MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
+ strerr, DIM (strerr)-1, NULL);
return strerr;
}
{
void * fnc = GetProcAddress (hd, sym);
if (!fnc)
- return NULL;
+ return NULL;
return fnc;
}
return NULL;
initialized = 1;
for (i=0, handle = NULL; !handle && dllnames[i]; i++)
- {
- handle = dlopen (dllnames[i], RTLD_LAZY);
- if (handle)
- {
- func = dlsym (handle, "SHGetFolderPathA");
- if (!func)
- {
- dlclose (handle);
- handle = NULL;
- }
- }
- }
+ {
+ handle = dlopen (dllnames[i], RTLD_LAZY);
+ if (handle)
+ {
+ func = dlsym (handle, "SHGetFolderPathA");
+ if (!func)
+ {
+ dlclose (handle);
+ handle = NULL;
+ }
+ }
+ }
}
if (func)
else
return -1;
}
+
+/* Returns a static string with the directroy from which the module
+ has been loaded. Returns an empty string on error. */
+static char *w32_get_module_dir(void)
+{
+ static char *moddir;
+
+ if (!moddir) {
+ char name[MAX_PATH+10];
+ char *p;
+
+ if ( !GetModuleFileNameA (0, name, sizeof (name)-10) )
+ *name = 0;
+ else {
+ p = strrchr (name, '\\');
+ if (p)
+ *p = 0;
+ else
+ *name = 0;
+ }
+ moddir = g_strdup (name);
+ }
+ return moddir;
+}
+#endif /* G_OS_WIN32 */
+
+/* Return a static string with the locale dir. */
+const gchar *get_locale_dir(void)
+{
+ static gchar *loc_dir;
+
+#ifdef G_OS_WIN32
+ if (!loc_dir)
+ loc_dir = g_strconcat(w32_get_module_dir(), G_DIR_SEPARATOR_S,
+ "\\share\\locale", NULL);
#endif
+ if (!loc_dir)
+ loc_dir = LOCALEDIR;
+
+ return loc_dir;
+}
+
const gchar *get_home_dir(void)
{
#ifdef G_OS_WIN32
static char home_dir[MAX_PATH] = "";
- if (home_dir[0] == '\0')
- {
- if (w32_shgetfolderpath
+ if (home_dir[0] == '\0') {
+ if (w32_shgetfolderpath
(NULL, CSIDL_APPDATA|CSIDL_FLAG_CREATE,
NULL, 0, home_dir) < 0)
strcpy (home_dir, "C:\\Sylpheed");
}
return home_dir;
#else
- return g_get_home_dir();
+ static const gchar *homeenv = NULL;
+
+ if (homeenv)
+ return homeenv;
+
+ if (!homeenv && g_getenv("HOME") != NULL)
+ homeenv = g_strdup(g_getenv("HOME"));
+ if (!homeenv)
+ homeenv = g_get_home_dir();
+
+ return homeenv;
#endif
}
static gchar *plugin_dir = NULL;
if (!plugin_dir)
- plugin_dir = g_strconcat(sylpheed_get_startup_dir(),
- "\\lib\\sylpheed-claws\\plugins\\",
- NULL);
+ plugin_dir = g_strconcat(w32_get_module_dir(),
+ "\\lib\\sylpheed-claws\\plugins\\",
+ NULL);
return plugin_dir;
#else
- return PLUGINDIR;
+ if (is_dir_exist(PLUGINDIR))
+ return PLUGINDIR;
+ else {
+ static gchar *plugin_dir = NULL;
+ if (!plugin_dir)
+ plugin_dir = g_strconcat(get_rc_dir(),
+ G_DIR_SEPARATOR_S, "plugins",
+ G_DIR_SEPARATOR_S, NULL);
+ return plugin_dir;
+ }
#endif
}
* straightforward for Unix but more complex for Windows. */
gboolean is_relative_filename(const gchar *file)
{
- if (!file)
- return TRUE;
+ if (!file)
+ return TRUE;
#ifdef G_OS_WIN32
- if ( *file == '\\' && file[1] == '\\' && strchr (file+2, '\\') )
- return FALSE; /* Prefixed with a hostname - this can't
- * be a relative name. */
+ if ( *file == '\\' && file[1] == '\\' && strchr (file+2, '\\') )
+ return FALSE; /* Prefixed with a hostname - this can't
+ * be a relative name. */
- if ( ((*file >= 'a' && *file <= 'z')
- || (*file >= 'A' && *file <= 'Z'))
- && file[1] == ':')
- file += 2; /* Skip drive letter. */
+ if ( ((*file >= 'a' && *file <= 'z')
+ || (*file >= 'A' && *file <= 'Z'))
+ && file[1] == ':')
+ file += 2; /* Skip drive letter. */
- return !(*file == '\\' || *file == '/');
+ return !(*file == '\\' || *file == '/');
#else
- return !(*file == G_DIR_SEPARATOR);
+ return !(*file == G_DIR_SEPARATOR);
#endif
}
* boundary := 0*69<bchars> bcharsnospace
* bchars := bcharsnospace / " "
* bcharsnospace := DIGIT / ALPHA / "'" / "(" / ")" /
- * "+" / "_" / "," / "-" / "." /
- * "/" / ":" / "=" / "?"
+ * "+" / "_" / "," / "-" / "." /
+ * "/" / ":" / "=" / "?"
*
* some special characters removed because of buggy MTAs
*/
gchar *fname;
gint fd;
FILE *fp;
+ gchar buf[2]="\0";
tmpdir = get_tmp_dir();
tmplen = strlen(tmpdir);
#ifndef G_OS_WIN32
g_unlink(fname);
+
+ /* verify that we can write in the file after unlinking */
+ if (write(fd, buf, 1) < 0) {
+ close(fd);
+ return tmpfile();
+ }
+
#endif
fp = fdopen(fd, "w+b");
if (!fp)
close(fd);
- else
+ else {
+ rewind(fp);
return fp;
+ }
+
#endif /* HAVE_MKSTEMP || G_OS_WIN32 */
return tmpfile();
int fd;
#ifdef G_OS_WIN32
char *template = g_strdup_printf ("%s%csylpheed.XXXXXX",
- dir, G_DIR_SEPARATOR);
+ dir, G_DIR_SEPARATOR);
fd = mkstemp_name(template, filename);
g_free(template);
#else
const char * debug_srcname(const char *file)
{
- const char *s = strrchr (file, '/');
- return s? s+1:file;
+ const char *s = strrchr (file, '/');
+ return s? s+1:file;
}
/*!< Array with allowable reply prefixes regexps. */
static const gchar * const prefixes[] = {
"Re\\:", /* "Re:" */
+ "RE\\:", /* "RE:" (outlook) */
"Re\\[[1-9][0-9]*\\]\\:", /* "Re[XXX]:" (non-conforming news mail clients) */
"Antw\\:", /* "Antw:" (Dutch / German Outlook) */
"Aw\\:", /* "Aw:" (German) */
"Fw\\:", /* "Fw:" Forward */
"Enc\\:", /* "Enc:" Forward (Brazilian Outlook) */
"Odp\\:", /* "Odp:" Re (Polish Outlook) */
- "Rif\\:" /* "Rif:" (Italian Outlook) */
+ "Rif\\:", /* "Rif:" (Italian Outlook) */
+ "SV\\:", /* "SV" (Norwegian) */
+ "Sv\\:", /* "Sv" (Norwegian) */
+ "VS\\:", /* "VS" (Norwegian) */
+ "Vs\\:", /* "Vs" (Norwegian) */
+ "AD\\:", /* "AD" (Norwegian) */
+ "Ad\\:" /* "Ad" (Norwegian) */
/* add more */
};
const int PREFIXES = sizeof prefixes / sizeof prefixes[0];
const char *str;
for (str = gptr; str && *str; str++) {
- if (isupper((guchar)*str)) hash_result += (*str + ' ');
- else hash_result += *str;
+ hash_result += toupper(*str);
}
return hash_result;
const char *str1 = gptr1;
const char *str2 = gptr2;
- return !g_utf8_collate(str1, str2);
+ return !strcasecmp(str1, str2);
}
gint g_int_compare(gconstpointer a, gconstpointer b)
gchar *make_uri_string(const gchar *bp, const gchar *ep)
{
+ while (bp && *bp && g_ascii_isspace(*bp))
+ bp++;
return g_strndup(bp, ep - bp);
}
"tc", "td", "tf", "tg", "th", "tj", "tk", "tm", "tn", "to",
"tp", "tr", "tt", "tv", "tw", "tz", "ua", "ug", "uk", "um",
"us", "uy", "uz", "va", "vc", "ve", "vg", "vi", "vn", "vu",
- "wf", "ws", "ye", "yt", "yu", "za", "zm", "zw"
+ "wf", "ws", "ye", "yt", "yu", "za", "zm", "zw"
};
gint n;
GHashTable *htab = g_hash_table_new(g_stricase_hash, g_stricase_equal);
last_dot = ep_;
if (*(last_dot + 1) == '.') {
if (prelast_dot == NULL)
- return FALSE;
+ return FALSE;
last_dot = prelast_dot;
break;
}
gchar *tmp;
gchar *result;
+ while (bp && *bp && g_ascii_isspace(*bp))
+ bp++;
tmp = g_strndup(bp, ep - bp);
result = g_strconcat("http://", tmp, NULL);
g_free(tmp);
return result;
}
-static gchar *mailcap_get_command_in_file(const gchar *path, const gchar *type)
+static gchar *mailcap_get_command_in_file(const gchar *path, const gchar *type, const gchar *file_to_open)
{
FILE *fp = fopen(path, "rb");
gchar buf[BUFFSIZE];
if (!fp)
return NULL;
while (fgets(buf, sizeof (buf), fp) != NULL) {
- gchar **parts = g_strsplit(buf, ";", -1);
+ gchar **parts = g_strsplit(buf, ";", 3);
gchar *trimmed = parts[0];
while (trimmed[0] == ' ')
trimmed++;
trimmed[strlen(trimmed)-1] = '\0';
if (!strcmp(trimmed, type)) {
+ gboolean needsterminal = FALSE;
+ if (parts[2] && strstr(parts[2], "needsterminal")) {
+ needsterminal = TRUE;
+ }
+ if (parts[2] && strstr(parts[2], "test=")) {
+ gchar *orig_testcmd = g_strdup(strstr(parts[2], "test=")+5);
+ gchar *testcmd = orig_testcmd;
+ if (strstr(testcmd,";"))
+ *(strstr(testcmd,";")) = '\0';
+ while (testcmd[0] == ' ')
+ testcmd++;
+ while (testcmd[strlen(testcmd)-1] == '\n')
+ testcmd[strlen(testcmd)-1] = '\0';
+ while (testcmd[strlen(testcmd)-1] == '\r')
+ testcmd[strlen(testcmd)-1] = '\0';
+ while (testcmd[strlen(testcmd)-1] == ' ')
+ testcmd[strlen(testcmd)-1] = '\0';
+
+ if (strstr(testcmd, "%s")) {
+ gchar *tmp = g_strdup_printf(testcmd, file_to_open);
+ gint res = system(tmp);
+ g_free(tmp);
+ g_free(orig_testcmd);
+
+ if (res != 0) {
+ g_strfreev(parts);
+ continue;
+ }
+ } else {
+ gint res = system(testcmd);
+ g_free(orig_testcmd);
+
+ if (res != 0) {
+ g_strfreev(parts);
+ continue;
+ }
+ }
+ }
+
trimmed = parts[1];
while (trimmed[0] == ' ')
trimmed++;
- while (trimmed[strlen(trimmed)-1] == ' ')
- trimmed[strlen(trimmed)-1] = '\0';
while (trimmed[strlen(trimmed)-1] == '\n')
trimmed[strlen(trimmed)-1] = '\0';
while (trimmed[strlen(trimmed)-1] == '\r')
trimmed[strlen(trimmed)-1] = '\0';
+ while (trimmed[strlen(trimmed)-1] == ' ')
+ trimmed[strlen(trimmed)-1] = '\0';
result = g_strdup(trimmed);
g_strfreev(parts);
fclose(fp);
- if (strstr(result, "%s") && !strstr(result, "'%s'")) {
+ /* if there are no single quotes around %s, add them.
+ * '.*%s.*' is ok, as in display 'png:%s'
+ */
+ if (strstr(result, "%s")
+ && !(strstr(result, "'") < strstr(result,"%s") &&
+ strstr(strstr(result,"%s"), "'"))) {
gchar *start = g_strdup(result);
gchar *end = g_strdup(strstr(result, "%s")+2);
gchar *tmp;
g_free(result);
result = tmp;
}
+ if (needsterminal) {
+ gchar *tmp = g_strdup_printf("xterm -e %s", result);
+ g_free(result);
+ result = tmp;
+ }
return result;
}
g_strfreev(parts);
fclose(fp);
return NULL;
}
-gchar *mailcap_get_command_for_type(const gchar *type)
+gchar *mailcap_get_command_for_type(const gchar *type, const gchar *file_to_open)
{
gchar *result = NULL;
gchar *path = NULL;
+ if (type == NULL)
+ return NULL;
path = g_strconcat(get_home_dir(), G_DIR_SEPARATOR_S, ".mailcap", NULL);
- result = mailcap_get_command_in_file(path, type);
+ result = mailcap_get_command_in_file(path, type, file_to_open);
g_free(path);
if (result)
return result;
- result = mailcap_get_command_in_file("/etc/mailcap", type);
+ result = mailcap_get_command_in_file("/etc/mailcap", type, file_to_open);
return result;
}
+void mailcap_update_default(const gchar *type, const gchar *command)
+{
+ gchar *path = NULL, *outpath = NULL;
+ path = g_strconcat(get_home_dir(), G_DIR_SEPARATOR_S, ".mailcap", NULL);
+ outpath = g_strconcat(get_home_dir(), G_DIR_SEPARATOR_S, ".mailcap.new", NULL);
+ FILE *fp = fopen(path, "rb");
+ FILE *outfp = fopen(outpath, "wb");
+ gchar buf[BUFFSIZE];
+
+ if (!fp) {
+ g_free(path);
+ g_free(outpath);
+ return;
+ }
+ if (!outfp) {
+ g_free(path);
+ g_free(outpath);
+ fclose(fp);
+ return;
+ }
+ while (fgets(buf, sizeof (buf), fp) != NULL) {
+ gchar **parts = g_strsplit(buf, ";", 3);
+ gchar *trimmed = parts[0];
+ while (trimmed[0] == ' ')
+ trimmed++;
+ while (trimmed[strlen(trimmed)-1] == ' ')
+ trimmed[strlen(trimmed)-1] = '\0';
+
+ if (!strcmp(trimmed, type)) {
+ g_strfreev(parts);
+ continue;
+ }
+ else {
+ fputs(buf, outfp);
+ }
+ g_strfreev(parts);
+ }
+ fprintf(outfp, "%s; %s\n", type, command);
+ fclose(fp);
+ fclose(outfp);
+ g_rename(outpath, path);
+}
+
gint copy_dir(const gchar *src, const gchar *dst)
{
GDir *dir;