#include <sys/utsname.h>
#endif
+#include <fcntl.h>
+
#ifdef G_OS_WIN32
# include <direct.h>
# include <io.h>
-# include <fcntl.h>
# include <w32lib.h>
#endif
return chmod(path, mode);
#endif
}
+
+FILE* g_fopen(const gchar *filename, const gchar *mode)
+{
+#ifdef G_OS_WIN32
+ char *name = g_win32_locale_filename_from_utf8(filename);
+ FILE* fp = fopen(name, mode);
+ g_free(name);
+ return fp;
+#else
+ return fopen(filename, mode);
+#endif
+}
#endif /* GLIB_CHECK_VERSION && G_OS_UNIX */
#ifdef G_OS_WIN32
-gint mkstemp_name(const gchar *template, gchar **name_used)
+gint mkstemp_name(gchar *template, gchar **name_used)
{
static gulong count=0; /* W32-_mktemp only supports up to 27
tempfiles... */
#endif /* G_OS_WIN32 */
#ifdef G_OS_WIN32
-gint mkstemp(const gchar *template)
+gint mkstemp(gchar *template)
{
gchar *dummyname;
gint res = mkstemp_name(template, &dummyname);
d = (d*100) >> divisor; \
}
-gchar *to_human_readable(off_t size)
+gchar *to_human_readable(goffset size)
{
static gchar str[14];
static gchar *b_format = NULL, *kb_format = NULL,
gb_format = _("%.2fGB");
}
- if (size < (off_t)1024) {
+ if (size < (goffset)1024) {
g_snprintf(str, sizeof(str), b_format, (gint)size);
return str;
- } else if (size >> 10 < (off_t)1024) {
+ } else if (size >> 10 < (goffset)1024) {
divide(size, 10, t, r);
g_snprintf(str, sizeof(str), kb_format, t, r);
return str;
- } else if (size >> 20 < (off_t)1024) {
+ } else if (size >> 20 < (goffset)1024) {
divide(size, 20, t, r);
g_snprintf(str, sizeof(str), mb_format, t, r);
return str;
} else {
- g_snprintf(str, sizeof(str), gb_format, (gfloat)size / (1 << 30));
+ g_snprintf(str, sizeof(str), gb_format, (gfloat)(size >> 30));
return str;
}
}
if (rename_force(out, file) < 0)
goto unlinkout;
+ g_free(out);
return 0;
unlinkout:
- g_unlink(out);
+ claws_unlink(out);
freeout:
g_free(out);
return -1;
const gchar *haystack_ = (const gchar *)haystack;
const gchar *needle_ = (const gchar *)needle;
const gchar *haystack_cur = (const gchar *)haystack;
+ size_t haystack_left = haystacklen;
if (needlelen == 1)
return memchr(haystack_, *needle_, haystacklen);
- while ((haystack_cur = memchr(haystack_cur, *needle_, haystacklen))
+ while ((haystack_cur = memchr(haystack_cur, *needle_, haystack_left))
!= NULL) {
if (haystacklen - (haystack_cur - haystack_) < needlelen)
break;
if (memcmp(haystack_cur + 1, needle_ + 1, needlelen - 1) == 0)
return (gpointer)haystack_cur;
- else
+ else{
haystack_cur++;
+ haystack_left = haystacklen - (haystack_cur - haystack_);
+ }
}
return NULL;
static gchar *decode_uri_gdup(const gchar *encoded_uri)
{
gchar *buffer = g_malloc(strlen(encoded_uri)+1);
- decode_uri(buffer, encoded_uri);
+ decode_uri_with_plus(buffer, encoded_uri, FALSE);
return buffer;
}
-gint scan_mailto_url(const gchar *mailto, gchar **to, gchar **cc, gchar **bcc,
+gint scan_mailto_url(const gchar *mailto, gchar **from, gchar **to, gchar **cc, gchar **bcc,
gchar **subject, gchar **body, gchar ***attach)
{
gchar *tmp_mailto;
const gchar *forbidden_uris[] = { ".gnupg/",
"/etc/passwd",
"/etc/shadow",
+ ".ssh/",
+ "../",
NULL };
gint num_attach = 0;
gchar **my_att = NULL;
if (*value == '\0') continue;
- if (cc && !g_ascii_strcasecmp(field, "cc")) {
+ if (from && !g_ascii_strcasecmp(field, "from")) {
+ if (!*from) {
+ *from = decode_uri_gdup(value);
+ } else {
+ gchar *tmp = decode_uri_gdup(value);
+ gchar *new_from = g_strdup_printf("%s, %s", *from, tmp);
+ g_free(*from);
+ *from = new_from;
+ }
+ } else if (cc && !g_ascii_strcasecmp(field, "cc")) {
if (!*cc) {
*cc = decode_uri_gdup(value);
} else {
*subject = decode_uri_gdup(value);
} else if (body && !*body && !g_ascii_strcasecmp(field, "body")) {
*body = decode_uri_gdup(value);
+ } else if (body && !*body && !g_ascii_strcasecmp(field, "insert")) {
+ gchar *tmp = decode_uri_gdup(value);
+ if (!g_file_get_contents(value, body, NULL, NULL)) {
+ g_error("Error: couldn't set insert file '%s' in body\n", value);
+ }
+ g_free(tmp);
+ tmp = NULL;
} else if (attach && !g_ascii_strcasecmp(field, "attach")) {
int i = 0;
gchar *tmp = decode_uri_gdup(value);
if (tmp) {
/* attach is correct */
num_attach++;
- printf("realloc my_att %d\n", (num_attach+1));
my_att = g_realloc(my_att, (sizeof(char *))*(num_attach+1));
my_att[num_attach-1] = tmp;
my_att[num_attach] = NULL;
}
while ((dir_name = g_dir_read_name(dp)) != NULL) {
- if (g_unlink(dir_name) < 0)
+ if (claws_unlink(dir_name) < 0)
FILE_OP_ERROR(dir_name, "unlink");
}
if (file_no > 0 && first <= file_no && file_no <= last) {
if (is_dir_exist(dir_name))
continue;
- if (g_unlink(dir_name) < 0)
+ if (claws_unlink(dir_name) < 0)
FILE_OP_ERROR(dir_name, "unlink");
}
}
debug_print("removing unwanted file %d from %s\n", file_no, dir);
if (is_dir_exist(dir_name))
continue;
- if (g_unlink(dir_name) < 0)
+ if (claws_unlink(dir_name) < 0)
FILE_OP_ERROR(dir_name, "unlink");
}
}
}
if (!S_ISDIR(s.st_mode)) {
- if (g_unlink(dir) < 0) {
+ if (claws_unlink(dir) < 0) {
FILE_OP_ERROR(dir, "unlink");
return -1;
}
return -1;
}
} else {
- if (g_unlink(dir_name) < 0)
+ if (claws_unlink(dir_name) < 0)
FILE_OP_ERROR(dir_name, "unlink");
}
}
return -1;
}
if (is_file_exist(newpath)) {
- if (g_unlink(newpath) < 0)
+ if (claws_unlink(newpath) < 0)
FILE_OP_ERROR(newpath, "unlink");
}
#endif
g_warning("writing to %s failed.\n", dest);
fclose(dest_fp);
fclose(src_fp);
- g_unlink(dest);
+ claws_unlink(dest);
return -1;
}
}
}
if (err) {
- g_unlink(dest);
+ claws_unlink(dest);
return -1;
}
g_warning("writing to %s failed.\n", dest);
fclose(dest_fp);
fclose(src_fp);
- g_unlink(dest);
+ claws_unlink(dest);
if (dest_bak) {
if (rename_force(dest_bak, dest) < 0)
FILE_OP_ERROR(dest_bak, "rename");
}
if (err) {
- g_unlink(dest);
+ claws_unlink(dest);
if (dest_bak) {
if (rename_force(dest_bak, dest) < 0)
FILE_OP_ERROR(dest_bak, "rename");
}
if (keep_backup == FALSE && dest_bak)
- g_unlink(dest_bak);
+ claws_unlink(dest_bak);
g_free(dest_bak);
if (copy_file(src, dest, FALSE) < 0) return -1;
- g_unlink(src);
+ claws_unlink(src);
return 0;
}
if (err) {
g_warning("writing to %s failed.\n", dest);
- g_unlink(dest);
+ claws_unlink(dest);
return -1;
}
g_warning("writing to %s failed.\n", dest);
fclose(dest_fp);
fclose(src_fp);
- g_unlink(dest);
+ claws_unlink(dest);
return -1;
}
}
}
if (err) {
- g_unlink(dest);
+ claws_unlink(dest);
return -1;
}
if (move_file(tmp_file, file, TRUE) < 0) {
g_warning("can't replace %s .\n", file);
- g_unlink(tmp_file);
+ claws_unlink(tmp_file);
g_free(tmp_file);
return -1;
}
gchar *fname;
gint fd;
FILE *fp;
+#ifndef G_OS_WIN32
gchar buf[2]="\0";
+#endif
tmpdir = get_tmp_dir();
tmplen = strlen(tmpdir);
return tmpfile();
#ifndef G_OS_WIN32
- g_unlink(fname);
+ claws_unlink(fname);
/* verify that we can write in the file after unlinking */
if (write(fd, buf, 1) < 0) {
if (fwrite(str, 1, len, fp) != len) {
FILE_OP_ERROR(file, "fwrite");
fclose(fp);
- g_unlink(file);
+ claws_unlink(file);
return -1;
}
if (fclose(fp) == EOF) {
FILE_OP_ERROR(file, "fclose");
- g_unlink(file);
+ claws_unlink(file);
return -1;
}
return 0;
}
-gchar *file_read_to_str(const gchar *file)
-{
- FILE *fp;
- gchar *str;
-
- g_return_val_if_fail(file != NULL, NULL);
-
- if ((fp = g_fopen(file, "rb")) == NULL) {
- FILE_OP_ERROR(file, "fopen");
- return NULL;
- }
-
- str = file_read_stream_to_str(fp);
-
- fclose(fp);
-
- return str;
-}
-
-gchar *file_read_stream_to_str(FILE *fp)
+static gchar *file_read_stream_to_str_full(FILE *fp, gboolean recode)
{
GByteArray *array;
guchar buf[BUFSIZ];
str = (gchar *)array->data;
g_byte_array_free(array, FALSE);
- if (!g_utf8_validate(str, -1, NULL)) {
+ if (recode && !g_utf8_validate(str, -1, NULL)) {
const gchar *src_codeset, *dest_codeset;
gchar *tmp = NULL;
src_codeset = conv_get_locale_charset_str();
return str;
}
+static gchar *file_read_to_str_full(const gchar *file, gboolean recode)
+{
+ FILE *fp;
+ gchar *str;
+ struct stat s;
+#ifndef G_OS_WIN32
+ gint fd, err;
+ struct timeval timeout = {1, 0};
+ fd_set fds;
+ int fflags = 0;
+#endif
+
+ g_return_val_if_fail(file != NULL, NULL);
+
+ if (g_stat(file, &s) != 0) {
+ FILE_OP_ERROR(file, "stat");
+ return NULL;
+ }
+ if (S_ISDIR(s.st_mode)) {
+ g_warning("%s: is a directory\n", file);
+ return NULL;
+ }
+
+#ifdef G_OS_WIN32
+ fp = fopen (file, "rb");
+ if (fp == NULL) {
+ FILE_OP_ERROR(file, "open");
+ return NULL;
+ }
+#else
+ /* test whether the file is readable without blocking */
+ fd = open(file, O_RDONLY | O_NONBLOCK);
+ if (fd == -1) {
+ FILE_OP_ERROR(file, "open");
+ return NULL;
+ }
+
+ FD_ZERO(&fds);
+ FD_SET(fd, &fds);
+
+ /* allow for one second */
+ err = select(fd+1, &fds, NULL, NULL, &timeout);
+ if (err <= 0 || !FD_ISSET(fd, &fds)) {
+ if (err < 0) {
+ FILE_OP_ERROR(file, "select");
+ } else {
+ g_warning("%s: doesn't seem readable\n", file);
+ }
+ close(fd);
+ return NULL;
+ }
+
+ /* Now clear O_NONBLOCK */
+ if ((fflags = fcntl(fd, F_GETFL)) < 0) {
+ FILE_OP_ERROR(file, "fcntl (F_GETFL)");
+ close(fd);
+ return NULL;
+ }
+ if (fcntl(fd, F_SETFL, (fflags & ~O_NONBLOCK)) < 0) {
+ FILE_OP_ERROR(file, "fcntl (F_SETFL)");
+ close(fd);
+ return NULL;
+ }
+
+ /* get the FILE pointer */
+ fp = fdopen(fd, "rb");
+
+ if (fp == NULL) {
+ FILE_OP_ERROR(file, "fdopen");
+ close(fd); /* if fp isn't NULL, we'll use fclose instead! */
+ return NULL;
+ }
+#endif
+
+ str = file_read_stream_to_str_full(fp, recode);
+
+ fclose(fp);
+
+ return str;
+}
+
+gchar *file_read_to_str(const gchar *file)
+{
+ return file_read_to_str_full(file, TRUE);
+}
+gchar *file_read_stream_to_str(FILE *fp)
+{
+ return file_read_stream_to_str_full(fp, TRUE);
+}
+
+gchar *file_read_to_str_no_recode(const gchar *file)
+{
+ return file_read_to_str_full(file, FALSE);
+}
+gchar *file_read_stream_to_str_no_recode(FILE *fp)
+{
+ return file_read_stream_to_str_full(fp, FALSE);
+}
char *fgets_crlf(char *buf, int size, FILE *stream)
{
{
struct tm gmt, *lt;
gint off;
+#ifndef G_OS_WIN32
struct tm buf1, buf2;
+#endif
gmt = *gmtime_r(now, &buf1);
lt = localtime_r(now, &buf2);
struct tm gmt, *lt;
gint off;
gchar sign = '+';
+#ifndef G_OS_WIN32
struct tm buf1, buf2;
+#endif
gmt = *gmtime_r(now, &buf1);
lt = localtime_r(now, &buf2);
time_t t;
gchar day[4], mon[4];
gint dd, hh, mm, ss, yyyy;
+#ifndef G_OS_WIN32
struct tm buf1;
gchar buf2[BUFFSIZE];
+#endif
t = time(NULL);
lt = localtime_r(&t, &buf1);
* for a "clean" subject line. If no prefix was found, 0
* is returned.
*/
+static regex_t u_regex;
+static gboolean u_init_;
+
+void utils_free_regex(void)
+{
+ if (u_init_) {
+ regfree(&u_regex);
+ u_init_ = FALSE;
+ }
+}
+
int subject_get_prefix_length(const gchar *subject)
{
/*!< Array with allowable reply prefixes regexps. */
"Antwort\\:", /* "Antwort:" (German Lotus Notes) */
"Res\\:", /* "Res:" (Brazilian Outlook) */
"Fw\\:", /* "Fw:" Forward */
+ "Fwd\\:", /* "Fwd:" Forward */
"Enc\\:", /* "Enc:" Forward (Brazilian Outlook) */
"Odp\\:", /* "Odp:" Re (Polish Outlook) */
"Rif\\:", /* "Rif:" (Italian Outlook) */
const int PREFIXES = sizeof prefixes / sizeof prefixes[0];
int n;
regmatch_t pos;
- static regex_t regex;
- static gboolean init_;
if (!subject) return 0;
if (!*subject) return 0;
- if (!init_) {
+ if (!u_init_) {
GString *s = g_string_new("");
for (n = 0; n < PREFIXES; n++)
/* We now have something like "^\ *((PREFIX1\ ?)|(PREFIX2\ ?))+"
* TODO: Should this be "^\ *(((PREFIX1)|(PREFIX2))\ ?)+" ??? */
- if (regcomp(®ex, s->str, REG_EXTENDED | REG_ICASE)) {
+ if (regcomp(&u_regex, s->str, REG_EXTENDED | REG_ICASE)) {
debug_print("Error compiling regexp %s\n", s->str);
g_string_free(s, TRUE);
return 0;
} else {
- init_ = TRUE;
+ u_init_ = TRUE;
g_string_free(s, TRUE);
}
}
- if (!regexec(®ex, subject, 1, &pos, 0) && pos.rm_so != -1)
+ if (!regexec(&u_regex, subject, 1, &pos, 0) && pos.rm_so != -1)
return pos.rm_eo;
else
return 0;
struct tm *lt;
time_t t;
gchar *addr;
+#ifndef G_OS_WIN32
struct tm buft;
+#endif
t = time(NULL);
lt = localtime_r(&t, &buft);
const gchar *s_daynames[] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL};
const gchar *s_monthnames[] = {NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL};
+
+gint daynames_len[] = {0,0,0,0,0,0,0};
+gint monthnames_len[] = {0,0,0,0,0,0,
+ 0,0,0,0,0,0};
+gint s_daynames_len[] = {0,0,0,0,0,0,0};
+gint s_monthnames_len[] = {0,0,0,0,0,0,
+ 0,0,0,0,0,0};
const gchar *s_am_up = NULL;
const gchar *s_pm_up = NULL;
const gchar *s_am_low = NULL;
const gchar *s_pm_low = NULL;
+
+gint s_am_up_len = 0;
+gint s_pm_up_len = 0;
+gint s_am_low_len = 0;
+gint s_pm_low_len = 0;
+
const gchar *def_loc_format = NULL;
const gchar *date_loc_format = NULL;
const gchar *time_loc_format = NULL;
static void init_time_names(void)
{
+ int i = 0;
+
daynames[0] = Q_("Complete day name for use by strftime|Sunday");
daynames[1] = Q_("Complete day name for use by strftime|Monday");
daynames[2] = Q_("Complete day name for use by strftime|Tuesday");
daynames[4] = Q_("Complete day name for use by strftime|Thursday");
daynames[5] = Q_("Complete day name for use by strftime|Friday");
daynames[6] = Q_("Complete day name for use by strftime|Saturday");
-
+
monthnames[0] = Q_("Complete month name for use by strftime|January");
monthnames[1] = Q_("Complete month name for use by strftime|February");
monthnames[2] = Q_("Complete month name for use by strftime|March");
s_monthnames[10] = Q_("Abbr. month name for use by strftime|Nov");
s_monthnames[11] = Q_("Abbr. month name for use by strftime|Dec");
+ for (i = 0; i < 7; i++) {
+ daynames_len[i] = strlen(daynames[i]);
+ s_daynames_len[i] = strlen(s_daynames[i]);
+ }
+ for (i = 0; i < 12; i++) {
+ monthnames_len[i] = strlen(monthnames[i]);
+ s_monthnames_len[i] = strlen(s_monthnames[i]);
+ }
+
s_am_up = Q_("For use by strftime (morning)|AM");
s_pm_up = Q_("For use by strftime (afternoon)|PM");
s_am_low = Q_("For use by strftime (morning, lowercase)|am");
s_pm_low = Q_("For use by strftime (afternoon, lowercase)|pm");
+ s_am_up_len = strlen(s_am_up);
+ s_pm_up_len = strlen(s_pm_up);
+ s_am_low_len = strlen(s_am_low);
+ s_pm_low_len = strlen(s_pm_low);
+
def_loc_format = Q_("For use by strftime (default date+time format)|%a %b %e %H:%M:%S %Y");
date_loc_format = Q_("For use by strftime (default date format)|%m/%d/%y");
time_loc_format = Q_("For use by strftime (default time format)|%H:%M:%S");
*curpos = '%';
break;
case 'a':
- len = strlen(s_daynames[lt->tm_wday]); CHECK_SIZE();
+ len = s_daynames_len[lt->tm_wday]; CHECK_SIZE();
strncpy2(curpos, s_daynames[lt->tm_wday], buflen - total_done);
break;
case 'A':
- len = strlen(daynames[lt->tm_wday]); CHECK_SIZE();
+ len = daynames_len[lt->tm_wday]; CHECK_SIZE();
strncpy2(curpos, daynames[lt->tm_wday], buflen - total_done);
break;
case 'b':
case 'h':
- len = strlen(s_monthnames[lt->tm_mon]); CHECK_SIZE();
+ len = s_monthnames_len[lt->tm_mon]; CHECK_SIZE();
strncpy2(curpos, s_monthnames[lt->tm_mon], buflen - total_done);
break;
case 'B':
- len = strlen(monthnames[lt->tm_mon]); CHECK_SIZE();
+ len = monthnames_len[lt->tm_mon]; CHECK_SIZE();
strncpy2(curpos, monthnames[lt->tm_mon], buflen - total_done);
break;
case 'c':
break;
case 'p':
if (lt->tm_hour >= 12) {
- len = strlen(s_pm_up); CHECK_SIZE();
- snprintf(curpos, buflen-total_done, s_pm_up);
+ len = s_pm_up_len; CHECK_SIZE();
+ snprintf(curpos, buflen-total_done, "%s", s_pm_up);
} else {
- len = strlen(s_am_up); CHECK_SIZE();
- snprintf(curpos, buflen-total_done, s_am_up);
+ len = s_am_up_len; CHECK_SIZE();
+ snprintf(curpos, buflen-total_done, "%s", s_am_up);
}
break;
case 'P':
if (lt->tm_hour >= 12) {
- len = strlen(s_pm_low); CHECK_SIZE();
- snprintf(curpos, buflen-total_done, s_pm_low);
+ len = s_pm_low_len; CHECK_SIZE();
+ snprintf(curpos, buflen-total_done, "%s", s_pm_low);
} else {
- len = strlen(s_am_low); CHECK_SIZE();
- snprintf(curpos, buflen-total_done, s_am_low);
+ len = s_am_low_len; CHECK_SIZE();
+ snprintf(curpos, buflen-total_done, "%s", s_am_low);
}
break;
case 'r':
*curpos++ = '0'+(lt->tm_min % 10);
break;
case 's':
- snprintf(subbuf, buflen - total_done, "%ld", mktime(lt));
+ snprintf(subbuf, 64, "%ld", mktime(lt));
len = strlen(subbuf); CHECK_SIZE();
strncpy2(curpos, subbuf, buflen - total_done);
break;
format++;
break;
default:
- g_warning("format error (%c)", *format);
+ if (format && *format)
+ g_warning("format error (%c)", *format);
*curpos = '\0';
return total_done;
}
*curpos++ = '\0';
return total_done;
}
+
+gboolean prefs_common_get_use_shred(void);
+
+
+#ifdef G_OS_WIN32
+#define WEXITSTATUS(x) (x)
+#endif
+
+int claws_unlink(const gchar *filename)
+{
+ struct stat s;
+ static int found_shred = -1;
+ static const gchar *args[4];
+
+ if (filename == NULL)
+ return 0;
+
+ if (prefs_common_get_use_shred()) {
+ if (found_shred == -1) {
+ /* init */
+ args[0] = g_find_program_in_path("shred");
+ debug_print("found shred: %s\n", args[0]);
+ found_shred = (args[0] != NULL) ? 1:0;
+ args[1] = "-f";
+ args[3] = NULL;
+ }
+ if (found_shred == 1) {
+ if (g_stat(filename, &s) == 0 && S_ISREG(s.st_mode)) {
+ if (s.st_nlink == 1) {
+ gint status=0;
+ args[2] = filename;
+ g_spawn_sync(NULL, (gchar **)args, NULL, 0,
+ NULL, NULL, NULL, NULL, &status, NULL);
+ debug_print("%s %s exited with status %d\n",
+ args[0], filename, WEXITSTATUS(status));
+ if (truncate(filename, 0) < 0)
+ g_warning("couln't truncate");
+ }
+ }
+ }
+ }
+ return g_unlink(filename);
+}