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.
*/
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
- const gchar *homeenv = NULL;
+ static const gchar *homeenv = NULL;
if (homeenv)
return homeenv;
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)
"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;
}
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;