/* notmuch - Not much of an email program, (just index and search)
*
* Copyright © 2009 Carl Worth
*
* 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
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://www.gnu.org/licenses/ .
*
* Author: Carl Worth <cworth@cworth.org>
*/
#include "notmuch-client.h"
#include <unistd.h>
typedef struct _filename_node {
char *filename;
time_t mtime;
struct _filename_node *next;
} _filename_node_t;
typedef struct _filename_list {
unsigned count;
_filename_node_t *head;
_filename_node_t **tail;
} _filename_list_t;
typedef struct {
int output_is_a_tty;
int verbose;
const char **new_tags;
size_t new_tags_length;
const char **new_ignore;
size_t new_ignore_length;
int total_files;
int processed_files;
int added_messages, removed_messages, renamed_messages;
struct timeval tv_start;
_filename_list_t *removed_files;
_filename_list_t *removed_directories;
_filename_list_t *directory_mtimes;
notmuch_bool_t synchronize_flags;
} add_files_state_t;
static volatile sig_atomic_t do_print_progress = 0;
static void
handle_sigalrm (unused (int signal))
{
do_print_progress = 1;
}
static volatile sig_atomic_t interrupted;
static void
handle_sigint (unused (int sig))
{
static char msg[] = "Stopping... \n";
/* This write is "opportunistic", so it's okay to ignore the
* result. It is not required for correctness, and if it does
* fail or produce a short write, we want to get out of the signal
* handler as quickly as possible, not retry it. */
IGNORE_RESULT (write (2, msg, sizeof(msg)-1));
interrupted = 1;
}
static _filename_list_t *
_filename_list_create (const void *ctx)
{
_filename_list_t *list;
list = talloc (ctx, _filename_list_t);
if (list == NULL)
return NULL;
list->head = NULL;
list->tail = &list->head;
list->count = 0;
return list;
}
static _filename_node_t *
_filename_list_add (_filename_list_t *list,
const char *filename)
{
_filename_node_t *node = talloc (list, _filename_node_t);
list->count++;
node->filename = talloc_strdup (list, filename);
node->next = NULL;
*(list->tail) = node;
list->tail = &node->next;
return node;
}
static void
generic_print_progress (const char *action, const char *object,
struct timeval tv_start, unsigned processed, unsigned total)
{
struct timeval tv_now;
double elapsed_overall, rate_overall;
gettimeofday (&tv_now, NULL);
elapsed_overall = notmuch_time_elapsed (tv_start, tv_now);
rate_overall = processed / elapsed_overall;
printf ("%s %d ", action, processed);
if (total) {
printf ("of %d %s", total, object);
if (processed > 0 && elapsed_overall > 0.5) {
double time_remaining = ((total - processed) / rate_overall);
printf (" (");
notmuch_time_print_formatted_seconds (time_remaining);
printf (" remaining)");
}
} else {
printf ("%s", object);
if (elapsed_overall > 0.5)
printf (" (%d %s/sec.)", (int) rate_overall, object);
}
printf (".\033[K\r");
fflush (stdout);
}
static int
dirent_sort_inode (const struct dirent **a, const struct dirent **b)
{
return ((*a)->d_ino < (*b<