g_hash_table_foreach(table, hash_free_strings_func, NULL);
}
+static void hash_free_value_mem_func(gpointer key, gpointer value,
+ gpointer data)
+{
+ g_free(value);
+}
+
+void hash_free_value_mem(GHashTable *table)
+{
+ g_hash_table_foreach(table, hash_free_value_mem_func, NULL);
+}
+
void ptr_array_free_strings(GPtrArray *array)
{
gint i;
return atoi(nstr);
}
+/* convert integer into string,
+ nstr must be not lower than 11 characters length */
+gchar *itos_buf(gchar *nstr, gint n)
+{
+ g_snprintf(nstr, 11, "%d", n);
+ return nstr;
+}
+
/* convert integer into string */
gchar *itos(gint n)
{
static gchar nstr[11];
- g_snprintf(nstr, 11, "%d", n);
- return nstr;
+ return itos_buf(nstr, n);
}
gchar *to_human_readable(off_t size)
{
- static gchar str[9];
- gint count;
- guint32 div = 1;
-
- for (count = 0; count < 3; count++) {
- if (size / div < 1024)
- break;
- else
- div *= 1024;
- }
+ static gchar str[10];
- switch (count) {
- case 0: g_snprintf(str, sizeof(str), "%dB", (gint)size); break;
- case 1: g_snprintf(str, sizeof(str), "%.1fKB", (gfloat)size / div);
- break;
- case 2: g_snprintf(str, sizeof(str), "%.1fMB", (gfloat)size / div);
- break;
- default:
- g_snprintf(str, sizeof(str), "%.1fGB", (gfloat)size / div);
- break;
- }
+ 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;
}
else
return strcmp(s1, s2);
}
-
+/* strstr with NULL-checking */
+gchar *strstr2(const gchar *s1, const gchar *s2)
+{
+ if (s1 == NULL || s2 == NULL)
+ return NULL;
+ else
+ return strstr(s1, s2);
+}
/* compare paths */
gint path_cmp(const gchar *s1, const gchar *s2)
{
return str;
}
+/* remove trailing character */
+gchar *strtailchomp(gchar *str, gchar tail_char)
+{
+ register gchar *s;
+
+ if (!*str) return str;
+ if (tail_char == '\0') return str;
+
+ for (s = str + strlen(str) - 1; s >= str && *s == tail_char; s--)
+ *s = '\0';
+
+ return str;
+}
+
+
/* Similar to `strstr' but this function ignores the case of both strings. */
gchar *strcasestr(const gchar *haystack, const gchar *needle)
{
{
gint mbl;
const wchar_t *wp;
- gchar tmp[MB_CUR_MAX];
+ gchar tmp[MB_LEN_MAX];
/* skip head space */
for (wp = s; *wp != (wchar_t)0 && iswspace(*wp); wp++)
/* compare subjects */
gint subject_compare(const gchar *s1, const gchar *s2)
{
- gint retval;
gchar *str1, *str2;
if (!s1 || !s2) return -1;
if (!*str1 || !*str2) return -1;
- retval = strcmp(str1, str2);
- //if (retval == 0)
- // g_print("\ns1 = %s\ns2 = %s\n"
- // "str1 = %s\nstr2 = %s\nmatched.\n",
- // s1, s2, str1, str2);
-
- return retval;
+ return strcmp(str1, str2);
}
void trim_subject(gchar *str)
*destp = '\0';
}
+void extract_one_parenthesis_with_skip_quote(gchar *str, gchar quote_chr,
+ gchar op, gchar cl)
+{
+ register gchar *srcp, *destp;
+ gint in_brace;
+ gboolean in_quote = FALSE;
+
+ srcp = destp = str;
+
+ if ((srcp = strchr_with_skip_quote(destp, quote_chr, op))) {
+ memmove(destp, srcp + 1, strlen(srcp));
+ in_brace = 1;
+ while(*destp) {
+ if (*destp == op && !in_quote)
+ in_brace++;
+ else if (*destp == cl && !in_quote)
+ in_brace--;
+ else if (*destp == quote_chr)
+ in_quote ^= TRUE;
+
+ if (in_brace == 0)
+ break;
+
+ destp++;
+ }
+ }
+ *destp = '\0';
+}
+
void extract_parenthesis_with_skip_quote(gchar *str, gchar quote_chr,
gchar op, gchar cl)
{
srcp = destp = str;
- while ((srcp = strchr_with_skip_quote(destp, '"', op))) {
+ while ((srcp = strchr_with_skip_quote(destp, quote_chr, op))) {
if (destp > str)
*destp++ = ' ';
memmove(destp, srcp + 1, strlen(srcp));
}
}
+void unfold_line(gchar *str)
+{
+ register gchar *p = str;
+ register gint spc;
+
+ while (*p) {
+ if (*p == '\n' || *p == '\r') {
+ *p++ = ' ';
+ spc = 0;
+ while (isspace(*(p + spc)))
+ spc++;
+ if (spc)
+ memmove(p, p + spc, strlen(p + spc) + 1);
+ } else
+ p++;
+ }
+}
+
void subst_char(gchar *str, gchar orig, gchar subst)
{
register gchar *p = str;
gint get_quote_level(const gchar *str)
{
- size_t firstquotepos;
- size_t lastquotepos = -1;
+ const gchar *first_pos;
+ const gchar *last_pos;
const gchar *p = str;
- const gchar *pos;
- gint quotelevel = -1;
- gint i = 0;
+ gint quote_level = -1;
/* speed up line processing by only searching to the last '>' */
- if ((pos = strchr(str, '>')) != NULL) {
- firstquotepos = pos - str;
- lastquotepos = strrchr(str, '>') - str + 1;
-
+ if ((first_pos = strchr(str, '>')) != NULL) {
/* skip a line if it contains a '<' before the initial '>' */
- if (memchr(str, '<', pos - str) != NULL)
+ if (memchr(str, '<', first_pos - str) != NULL)
return -1;
+ last_pos = strrchr(first_pos, '>');
} else
return -1;
- while (i < lastquotepos) {
- while (i < lastquotepos) {
- if (isspace(*p) || (*p == '\t')) {
+ while (p <= last_pos) {
+ while (p < last_pos) {
+ if (isspace(*p))
p++;
- i++;
- } else
+ else
break;
}
- if (i >= lastquotepos)
- break;
if (*p == '>')
- quotelevel++;
- else if ((*p != '-') && !isspace(*p) && (i < lastquotepos)) {
+ quote_level++;
+ else if (*p != '-' && !isspace(*p) && p <= last_pos) {
/* any characters are allowed except '-' and space */
- while ((*p != '-') && (*p != '>') && !isspace(*p) &&
- (i < lastquotepos)) {
+ while (*p != '-' && *p != '>' && !isspace(*p) &&
+ p < last_pos)
p++;
- i++;
- }
if (*p == '>')
- quotelevel++;
- else if ((i >= lastquotepos) || isspace(*p))
+ quote_level++;
+ else
break;
}
p++;
- i++;
}
- return quotelevel;
+ return quote_level;
}
GList *uri_list_extract_filenames(const gchar *uri_list)
return imap_cache_dir;
}
+gchar *get_mbox_cache_dir(void)
+{
+ static gchar *mbox_cache_dir = NULL;
+
+ if (!mbox_cache_dir)
+ mbox_cache_dir = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
+ MBOX_CACHE_DIR, NULL);
+
+ return mbox_cache_dir;
+}
+
gchar *get_mime_tmp_dir(void)
{
static gchar *mime_tmp_dir = NULL;
return s.st_size;
}
+off_t get_left_file_size(FILE *fp)
+{
+ glong pos;
+ glong end;
+ off_t size;
+
+ if ((pos = ftell(fp)) < 0) {
+ perror("ftell");
+ return -1;
+ }
+ if (fseek(fp, 0L, SEEK_END) < 0) {
+ perror("fseek");
+ return -1;
+ }
+ if ((end = ftell(fp)) < 0) {
+ perror("fseek");
+ return -1;
+ }
+ size = end - pos;
+ if (fseek(fp, pos, SEEK_SET) < 0) {
+ perror("fseek");
+ return -1;
+ }
+
+ return size;
+}
+
gboolean file_exist(const gchar *file, gboolean allow_fifo)
{
struct stat s;
return 0;
}
+gint remove_numbered_files(const gchar *dir, guint first, guint last)
+{
+ DIR *dp;
+ struct dirent *d;
+ gchar *prev_dir;
+ gint fileno;
+
+ prev_dir = g_get_current_dir();
+
+ if (chdir(dir) < 0) {
+ FILE_OP_ERROR(dir, "chdir");
+ return -1;
+ }
+
+ if ((dp = opendir(".")) == NULL) {
+ FILE_OP_ERROR(dir, "opendir");
+ return -1;
+ }
+
+ while ((d = readdir(dp)) != NULL) {
+ fileno = to_number(d->d_name);
+ if (fileno >= 0 && first <= fileno && fileno <= last) {
+ if (unlink(d->d_name) < 0)
+ FILE_OP_ERROR(d->d_name, "unlink");
+ }
+ }
+
+ closedir(dp);
+
+ if (chdir(prev_dir) < 0) {
+ FILE_OP_ERROR(prev_dir, "chdir");
+ g_free(prev_dir);
+ return -1;
+ }
+
+ g_free(prev_dir);
+
+ return 0;
+}
+
+gint remove_all_numbered_files(const gchar *dir)
+{
+ return remove_numbered_files(dir, 0, UINT_MAX);
+}
+
gint remove_dir_recursive(const gchar *dir)
{
struct stat s;
struct dirent *d;
gchar *prev_dir;
- //g_print("dir = %s\n", dir);
+ /* g_print("dir = %s\n", dir); */
if (stat(dir, &s) < 0) {
FILE_OP_ERROR(dir, "stat");
}
prev_dir = g_get_current_dir();
- //g_print("prev_dir = %s\n", prev_dir);
+ /* g_print("prev_dir = %s\n", prev_dir); */
if (!path_cmp(prev_dir, dir)) {
g_free(prev_dir);
continue;
}
- //g_print("removing %s\n", d->d_name);
+ /* g_print("removing %s\n", d->d_name); */
if (S_ISDIR(s.st_mode)) {
if (remove_dir_recursive(d->d_name) < 0) {
return 0;
}
+gint move_file(const gchar *src, const gchar *dest)
+{
+ if (is_file_exist(dest)) {
+ g_warning(_("move_file(): file %s already exists."), dest);
+ return -1;
+ }
+
+ if (rename(src, dest) == 0) return 0;
+
+ if (EXDEV != errno) {
+ FILE_OP_ERROR(src, "rename");
+ return -1;
+ }
+
+ if (copy_file(src, dest) < 0) return -1;
+
+ unlink(src);
+
+ return 0;
+}
+
gint change_file_mode_rw(FILE *fp, const gchar *file)
{
#if HAVE_FCHMOD
return 0;
}
-gint execute_command_line(const gchar *cmdline)
+gint execute_sync(gchar *const argv[])
+{
+ pid_t pid;
+
+ if ((pid = fork()) < 0) {
+ perror("fork");
+ return -1;
+ }
+
+ if (pid == 0) { /* child process */
+ execvp(argv[0], argv);
+
+ perror("execvp");
+ _exit(1);
+ }
+
+ waitpid(pid, NULL, 0);
+
+ return 0;
+}
+
+gint execute_command_line(const gchar *cmdline, gboolean async)
{
gchar **argv;
gint i;
}
}
- ret = execute_async(argv);
+ if (async)
+ ret = execute_async(argv);
+ else
+ ret = execute_sync(argv);
g_strfreev(argv);
return ret;
g_snprintf(buf, sizeof(buf), default_cmdline, uri);
}
- execute_command_line(buf);
+ execute_command_line(buf, TRUE);
return 0;
}
day, dd, mon, yyyy, hh, mm, ss, tzoffset(&t));
}
-void debug_print(const gchar *format, ...)
+static FILE *log_fp = NULL;
+
+void set_log_file(const gchar *filename)
+{
+ if (log_fp) return;
+ log_fp = fopen(filename, "w");
+ if (!log_fp)
+ FILE_OP_ERROR(filename, "fopen");
+}
+
+void close_log_file(void)
+{
+ if (log_fp) {
+ fclose(log_fp);
+ log_fp = NULL;
+ }
+}
+
+static guint log_verbosity_count = 0;
+
+void log_verbosity_set(gboolean verbose)
+{
+ if (verbose)
+ log_verbosity_count++;
+ else if (log_verbosity_count > 0)
+ log_verbosity_count--;
+}
+
+void debug_print_real(const gchar *format, ...)
{
va_list args;
gchar buf[BUFFSIZE];
{
va_list args;
gchar buf[BUFFSIZE];
+ gchar *logbuf;
+ gchar timestr[6];
+ time_t t;
va_start(args, format);
g_vsnprintf(buf, sizeof(buf), format, args);
va_end(args);
+
+ time(&t);
+ strftime(timestr, 6, "%H:%M", localtime(&t));
+ logbuf = g_strdup_printf("[%s] %s", timestr, buf);
- if (debug_mode) fputs(buf, stdout);
- log_window_append(buf, LOG_NORMAL);
- statusbar_puts_all(buf);
+ if (debug_mode) fputs(logbuf, stdout);
+ log_window_append(logbuf, LOG_NORMAL);
+ if (log_fp) {
+ fputs(logbuf, log_fp);
+ fflush(log_fp);
+ }
+ if (log_verbosity_count)
+ statusbar_puts_all(buf);
+ g_free(logbuf);
}
void log_message(const gchar *format, ...)
if (debug_mode) g_message("%s", buf);
log_window_append(buf, LOG_MSG);
+ if (log_fp) {
+ fputs("message: ", log_fp);
+ fputs(buf, log_fp);
+ fflush(log_fp);
+ }
+ statusbar_puts_all(buf);
}
void log_warning(const gchar *format, ...)
g_warning("%s", buf);
log_window_append(buf, LOG_WARN);
+ if (log_fp) {
+ fputs("*** warning: ", log_fp);
+ fputs(buf, log_fp);
+ fflush(log_fp);
+ }
}
void log_error(const gchar *format, ...)
g_warning("%s", buf);
log_window_append(buf, LOG_ERROR);
+ if (log_fp) {
+ fputs("*** error: ", log_fp);
+ fputs(buf, log_fp);
+ fflush(log_fp);
+ }
}