54 |
}; |
}; |
55 |
|
|
56 |
static int action; /* Action to perform */ |
static int action; /* Action to perform */ |
57 |
static int mode_public = 1; /* Create public sequences */ |
static int seq_flags = 0; /* Create public sequences; |
58 |
static int mode_zero = 1; /* Zero the sequence before addition */ |
Do not zero the sequence before addition */ |
59 |
static list_t seq_list; /* List of sequence names to operate upon */ |
static list_t seq_list; /* List of sequence names to operate upon */ |
60 |
|
|
61 |
static char *mbox_dir; |
static char *mbox_dir; |
72 |
} |
} |
73 |
|
|
74 |
static int |
static int |
75 |
opt_handler (int key, char *arg, void *unused) |
opt_handler (int key, char *arg, void *unused, struct argp_state *state) |
76 |
{ |
{ |
77 |
switch (key) |
switch (key) |
78 |
{ |
{ |
92 |
break; |
break; |
93 |
|
|
94 |
case ARG_PUBLIC: |
case ARG_PUBLIC: |
95 |
mode_public = is_true (arg); |
if (is_true (arg)) |
96 |
|
seq_flags &= ~SEQ_PRIVATE; |
97 |
|
else |
98 |
|
seq_flags |= SEQ_PRIVATE; |
99 |
break; |
break; |
100 |
|
|
101 |
case ARG_NOPUBLIC: |
case ARG_NOPUBLIC: |
102 |
mode_public = 0; |
seq_flags |= SEQ_PRIVATE; |
103 |
break; |
break; |
104 |
|
|
105 |
case ARG_ZERO: |
case ARG_ZERO: |
106 |
mode_zero = is_true (arg); |
if (is_true (arg)) |
107 |
|
seq_flags |= SEQ_ZERO; |
108 |
|
else |
109 |
|
seq_flags &= ~SEQ_ZERO; |
110 |
break; |
break; |
111 |
|
|
112 |
case ARG_NOZERO: |
case ARG_NOZERO: |
113 |
mode_zero = 0; |
seq_flags &= ~SEQ_ZERO; |
114 |
break; |
break; |
115 |
|
|
116 |
default: |
default: |
119 |
return 0; |
return 0; |
120 |
} |
} |
121 |
|
|
|
static char * |
|
|
private_sequence_name (char *name) |
|
|
{ |
|
|
char *p; |
|
|
|
|
|
asprintf (&p, "atr-%s-%s", name, mbox_dir); |
|
|
return p; |
|
|
} |
|
|
|
|
|
static char * |
|
|
read_sequence (char *name, int public) |
|
|
{ |
|
|
char *value; |
|
|
|
|
|
if (public) |
|
|
value = mh_global_sequences_get (name, NULL); |
|
|
else |
|
|
{ |
|
|
char *p = private_sequence_name (name); |
|
|
value = mh_global_context_get (p, NULL); |
|
|
free (p); |
|
|
} |
|
|
return value; |
|
|
} |
|
|
|
|
|
static void |
|
|
write_sequence (char *name, char *value, int public) |
|
|
{ |
|
|
if (public) |
|
|
mh_global_sequences_set (name, value); |
|
|
else |
|
|
{ |
|
|
char *p = private_sequence_name (name); |
|
|
mh_global_context_set (p, value); |
|
|
free (p); |
|
|
} |
|
|
} |
|
|
|
|
|
static void |
|
|
delete_sequence (char *name, int public) |
|
|
{ |
|
|
write_sequence (name, NULL, public); |
|
|
} |
|
|
|
|
122 |
static int |
static int |
123 |
action_add (void *item, void *data) |
action_add (void *item, void *data) |
124 |
{ |
{ |
125 |
char *name = item; |
mh_seq_add ((char *)item, (mh_msgset_t *)data, seq_flags); |
|
mh_msgset_t *mset = data; |
|
|
char *value = read_sequence (name, mode_public); |
|
|
char *new_value, *p; |
|
|
char buf[64]; |
|
|
size_t i, len; |
|
|
|
|
|
delete_sequence (name, !mode_public); |
|
|
|
|
|
if (mode_zero) |
|
|
value = NULL; |
|
|
|
|
|
if (value) |
|
|
len = strlen (value); |
|
|
else |
|
|
len = 0; |
|
|
len++; |
|
|
for (i = 0; i < mset->count; i++) |
|
|
{ |
|
|
snprintf (buf, sizeof buf, "%lu", (unsigned long) mset->list[i]); |
|
|
len += strlen (buf) + 1; |
|
|
} |
|
|
|
|
|
new_value = xmalloc (len + 1); |
|
|
if (value) |
|
|
strcpy (new_value, value); |
|
|
else |
|
|
new_value[0] = 0; |
|
|
p = new_value + strlen (new_value); |
|
|
*p++ = ' '; |
|
|
for (i = 0; i < mset->count; i++) |
|
|
{ |
|
|
p += sprintf (p, "%lu", (unsigned long) mset->list[i]); |
|
|
*p++ = ' '; |
|
|
} |
|
|
*p = 0; |
|
|
write_sequence (name, new_value, mode_public); |
|
|
return 0; |
|
|
} |
|
|
|
|
|
static int |
|
|
cmp_msgnum (const void *a, const void *b) |
|
|
{ |
|
|
const size_t *as = a; |
|
|
const size_t *bs = b; |
|
|
|
|
|
if (*as < *bs) |
|
|
return -1; |
|
|
if (*as > *bs) |
|
|
return 1; |
|
126 |
return 0; |
return 0; |
127 |
} |
} |
128 |
|
|
129 |
static int |
static int |
130 |
action_delete (void *item, void *data) |
action_delete (void *item, void *data) |
131 |
{ |
{ |
132 |
char *name = item; |
mh_seq_delete ((char *)item, (mh_msgset_t *)data, seq_flags); |
|
mh_msgset_t *mset = data; |
|
|
char *value = read_sequence (name, mode_public); |
|
|
char *p; |
|
|
int argc, i; |
|
|
char **argv; |
|
|
|
|
|
if (!value) |
|
|
return 0; |
|
|
|
|
|
if (argcv_get (value, "", NULL, &argc, &argv)) |
|
|
return 0; |
|
|
|
|
|
for (i = 0; i < argc; i++) |
|
|
{ |
|
|
char *p; |
|
|
size_t num = strtoul (argv[i], &p, 10); |
|
|
|
|
|
if (*p) |
|
|
continue; |
|
|
|
|
|
if (bsearch (&num, mset->list, mset->count, sizeof (mset->list[0]), |
|
|
cmp_msgnum)) |
|
|
{ |
|
|
free (argv[i]); |
|
|
argv[i] = NULL; |
|
|
} |
|
|
} |
|
|
|
|
|
p = value; |
|
|
for (i = 0; i < argc; i++) |
|
|
{ |
|
|
if (argv[i]) |
|
|
{ |
|
|
strcpy (p, argv[i]); |
|
|
p += strlen (p); |
|
|
*p++ = ' '; |
|
|
} |
|
|
} |
|
|
*p = 0; |
|
|
write_sequence (name, value, mode_public); |
|
|
argcv_free (argc, argv); |
|
|
|
|
133 |
return 0; |
return 0; |
134 |
} |
} |
135 |
|
|
139 |
char *name = item; |
char *name = item; |
140 |
char *val; |
char *val; |
141 |
|
|
142 |
val = read_sequence (name, 1); |
val = mh_seq_read (name, 0); |
143 |
if (val) |
if (val) |
144 |
printf ("%s: %s\n", name, val); |
printf ("%s: %s\n", name, val); |
145 |
else if ((val = read_sequence (name, 0))) |
else if ((val = mh_seq_read (name, SEQ_PRIVATE))) |
146 |
printf ("%s (%s): %s\n", name, _("private"), val); |
printf ("%s (%s): %s\n", name, _("private"), val); |
147 |
return 0; |
return 0; |
148 |
} |
} |
188 |
url_t url; |
url_t url; |
189 |
|
|
190 |
mu_init_nls (); |
mu_init_nls (); |
191 |
mh_argp_parse (argc, argv, options, mh_option, args_doc, doc, |
mh_argp_parse (argc, argv, 0, options, mh_option, args_doc, doc, |
192 |
opt_handler, NULL, &index); |
opt_handler, NULL, &index); |
193 |
|
|
194 |
mbox = mh_open_folder (current_folder, 0); |
mbox = mh_open_folder (current_folder, 0); |