Browse Source

pre-calculate channel and box lists (as far as possible)

... instead of determining them on the fly, because
- it enables early display of totals (to be used soon)
- it enables re-use of the data (to be used at some point)
- the code is less cryptic

note that we leak the data created in main(), consistently with other
configuration-related data.
wip/server-refactor
Oswald Buddenhagen 10 years ago
parent
commit
1de3ecd883
  1. 315
      src/main.c

315
src/main.c

@ -234,17 +234,89 @@ typedef struct box_ent {
int present[2]; int present[2];
} box_ent_t; } box_ent_t;
typedef struct chan_ent {
struct chan_ent *next;
channel_conf_t *conf;
box_ent_t *boxes;
char boxlist;
} chan_ent_t;
static chan_ent_t *
add_channel( chan_ent_t ***chanapp, channel_conf_t *chan, int ops[] )
{
chan_ent_t *ce = nfcalloc( sizeof(*ce) );
ce->conf = chan;
merge_actions( chan, ops, XOP_HAVE_TYPE, OP_MASK_TYPE, OP_MASK_TYPE );
merge_actions( chan, ops, XOP_HAVE_CREATE, OP_CREATE, 0 );
merge_actions( chan, ops, XOP_HAVE_REMOVE, OP_REMOVE, 0 );
merge_actions( chan, ops, XOP_HAVE_EXPUNGE, OP_EXPUNGE, 0 );
**chanapp = ce;
*chanapp = &ce->next;
return ce;
}
static chan_ent_t *
add_named_channel( chan_ent_t ***chanapp, char *channame, int ops[] )
{
channel_conf_t *chan;
chan_ent_t *ce;
box_ent_t *boxes = 0, **mboxapp = &boxes, *mbox;
char *boxp, *nboxp;
int boxl, boxlist = 0;
if ((boxp = strchr( channame, ':' )))
*boxp++ = 0;
for (chan = channels; chan; chan = chan->next)
if (!strcmp( chan->name, channame ))
goto gotchan;
error( "No channel or group named '%s' defined.\n", channame );
return 0;
gotchan:
if (boxp) {
if (!chan->patterns) {
error( "Cannot override mailbox in channel '%s' - no Patterns.\n", channame );
return 0;
}
boxlist = 1;
do {
nboxp = strpbrk( boxp, ",\n" );
if (nboxp) {
boxl = nboxp - boxp;
*nboxp++ = 0;
} else {
boxl = strlen( boxp );
}
mbox = nfmalloc( sizeof(*mbox) );
if (boxl)
mbox->name = nfstrndup( boxp, boxl );
else
mbox->name = nfstrndup( "INBOX", 5 );
mbox->present[M] = mbox->present[S] = BOX_POSSIBLE;
mbox->next = 0;
*mboxapp = mbox;
mboxapp = &mbox->next;
boxp = nboxp;
} while (boxp);
}
ce = add_channel( chanapp, chan, ops );
ce->boxes = boxes;
ce->boxlist = boxlist;
return ce;
}
typedef struct { typedef struct {
int t[2]; int t[2];
channel_conf_t *chan; channel_conf_t *chan;
driver_t *drv[2]; driver_t *drv[2];
store_t *ctx[2]; store_t *ctx[2];
box_ent_t *boxes; chan_ent_t *chanptr;
string_list_t *chanptr; box_ent_t *boxptr;
char *names[2]; char *names[2];
char **argv; int ret, multiple, all, list, state[2];
int oind, ret, multiple, all, list, ops[2], state[2]; char done, skip, cben;
char done, skip, cben, boxlist;
} main_vars_t; } main_vars_t;
#define AUX &mvars->t[t] #define AUX &mvars->t[t]
@ -262,9 +334,12 @@ int
main( int argc, char **argv ) main( int argc, char **argv )
{ {
main_vars_t mvars[1]; main_vars_t mvars[1];
chan_ent_t *chans = 0, **chanapp = &chans;
group_conf_t *group; group_conf_t *group;
channel_conf_t *chan;
string_list_t *channame;
char *config = 0, *opt, *ochar; char *config = 0, *opt, *ochar;
int cops = 0, op, pseudo = 0; int oind, cops = 0, op, ops[2] = { 0, 0 }, pseudo = 0;
tzset(); tzset();
gethostname( Hostname, sizeof(Hostname) ); gethostname( Hostname, sizeof(Hostname) );
@ -280,22 +355,22 @@ main( int argc, char **argv )
memset( mvars, 0, sizeof(*mvars) ); memset( mvars, 0, sizeof(*mvars) );
mvars->t[1] = 1; mvars->t[1] = 1;
for (mvars->oind = 1, ochar = 0; ; ) { for (oind = 1, ochar = 0; ; ) {
if (!ochar || !*ochar) { if (!ochar || !*ochar) {
if (mvars->oind >= argc) if (oind >= argc)
break; break;
if (argv[mvars->oind][0] != '-') if (argv[oind][0] != '-')
break; break;
if (argv[mvars->oind][1] == '-') { if (argv[oind][1] == '-') {
opt = argv[mvars->oind++] + 2; opt = argv[oind++] + 2;
if (!*opt) if (!*opt)
break; break;
if (!strcmp( opt, "config" )) { if (!strcmp( opt, "config" )) {
if (mvars->oind >= argc) { if (oind >= argc) {
error( "--config requires an argument.\n" ); error( "--config requires an argument.\n" );
return 1; return 1;
} }
config = argv[mvars->oind++]; config = argv[oind++];
} else if (starts_with( opt, -1, "config=", 7 )) } else if (starts_with( opt, -1, "config=", 7 ))
config = opt + 7; config = opt + 7;
else if (!strcmp( opt, "all" )) else if (!strcmp( opt, "all" ))
@ -319,9 +394,9 @@ main( int argc, char **argv )
} else if (!strcmp( opt, "debug" )) } else if (!strcmp( opt, "debug" ))
DFlags |= DEBUG | QUIET; DFlags |= DEBUG | QUIET;
else if (!strcmp( opt, "pull" )) else if (!strcmp( opt, "pull" ))
cops |= XOP_PULL, mvars->ops[M] |= XOP_HAVE_TYPE; cops |= XOP_PULL, ops[M] |= XOP_HAVE_TYPE;
else if (!strcmp( opt, "push" )) else if (!strcmp( opt, "push" ))
cops |= XOP_PUSH, mvars->ops[M] |= XOP_HAVE_TYPE; cops |= XOP_PUSH, ops[M] |= XOP_HAVE_TYPE;
else if (starts_with( opt, -1, "create", 6 )) { else if (starts_with( opt, -1, "create", 6 )) {
opt += 6; opt += 6;
op = OP_CREATE|XOP_HAVE_CREATE; op = OP_CREATE|XOP_HAVE_CREATE;
@ -329,12 +404,12 @@ main( int argc, char **argv )
if (!*opt) if (!*opt)
cops |= op; cops |= op;
else if (!strcmp( opt, "-master" )) else if (!strcmp( opt, "-master" ))
mvars->ops[M] |= op; ops[M] |= op;
else if (!strcmp( opt, "-slave" )) else if (!strcmp( opt, "-slave" ))
mvars->ops[S] |= op; ops[S] |= op;
else else
goto badopt; goto badopt;
mvars->ops[M] |= op & (XOP_HAVE_CREATE|XOP_HAVE_REMOVE|XOP_HAVE_EXPUNGE); ops[M] |= op & (XOP_HAVE_CREATE|XOP_HAVE_REMOVE|XOP_HAVE_EXPUNGE);
} else if (starts_with( opt, -1, "remove", 6 )) { } else if (starts_with( opt, -1, "remove", 6 )) {
opt += 6; opt += 6;
op = OP_REMOVE|XOP_HAVE_REMOVE; op = OP_REMOVE|XOP_HAVE_REMOVE;
@ -344,15 +419,15 @@ main( int argc, char **argv )
op = OP_EXPUNGE|XOP_HAVE_EXPUNGE; op = OP_EXPUNGE|XOP_HAVE_EXPUNGE;
goto lcop; goto lcop;
} else if (!strcmp( opt, "no-expunge" )) } else if (!strcmp( opt, "no-expunge" ))
mvars->ops[M] |= XOP_HAVE_EXPUNGE; ops[M] |= XOP_HAVE_EXPUNGE;
else if (!strcmp( opt, "no-create" )) else if (!strcmp( opt, "no-create" ))
mvars->ops[M] |= XOP_HAVE_CREATE; ops[M] |= XOP_HAVE_CREATE;
else if (!strcmp( opt, "no-remove" )) else if (!strcmp( opt, "no-remove" ))
mvars->ops[M] |= XOP_HAVE_REMOVE; ops[M] |= XOP_HAVE_REMOVE;
else if (!strcmp( opt, "full" )) else if (!strcmp( opt, "full" ))
mvars->ops[M] |= XOP_HAVE_TYPE|XOP_PULL|XOP_PUSH; ops[M] |= XOP_HAVE_TYPE|XOP_PULL|XOP_PUSH;
else if (!strcmp( opt, "noop" )) else if (!strcmp( opt, "noop" ))
mvars->ops[M] |= XOP_HAVE_TYPE; ops[M] |= XOP_HAVE_TYPE;
else if (starts_with( opt, -1, "pull", 4 )) { else if (starts_with( opt, -1, "pull", 4 )) {
op = XOP_PULL; op = XOP_PULL;
lcac: lcac:
@ -380,19 +455,19 @@ main( int argc, char **argv )
op |= OP_FLAGS; op |= OP_FLAGS;
else { else {
badopt: badopt:
error( "Unknown option '%s'\n", argv[mvars->oind - 1] ); error( "Unknown option '%s'\n", argv[oind - 1] );
return 1; return 1;
} }
switch (op & XOP_MASK_DIR) { switch (op & XOP_MASK_DIR) {
case XOP_PULL: mvars->ops[S] |= op & OP_MASK_TYPE; break; case XOP_PULL: ops[S] |= op & OP_MASK_TYPE; break;
case XOP_PUSH: mvars->ops[M] |= op & OP_MASK_TYPE; break; case XOP_PUSH: ops[M] |= op & OP_MASK_TYPE; break;
default: cops |= op; break; default: cops |= op; break;
} }
mvars->ops[M] |= XOP_HAVE_TYPE; ops[M] |= XOP_HAVE_TYPE;
} }
continue; continue;
} }
ochar = argv[mvars->oind++] + 1; ochar = argv[oind++] + 1;
if (!*ochar) { if (!*ochar) {
error( "Invalid option '-'\n" ); error( "Invalid option '-'\n" );
return 1; return 1;
@ -410,24 +485,24 @@ main( int argc, char **argv )
ochar++; ochar++;
pseudo = 1; pseudo = 1;
} }
if (mvars->oind >= argc) { if (oind >= argc) {
error( "-c requires an argument.\n" ); error( "-c requires an argument.\n" );
return 1; return 1;
} }
config = argv[mvars->oind++]; config = argv[oind++];
break; break;
case 'C': case 'C':
op = OP_CREATE|XOP_HAVE_CREATE; op = OP_CREATE|XOP_HAVE_CREATE;
cop: cop:
if (*ochar == 'm') if (*ochar == 'm')
mvars->ops[M] |= op, ochar++; ops[M] |= op, ochar++;
else if (*ochar == 's') else if (*ochar == 's')
mvars->ops[S] |= op, ochar++; ops[S] |= op, ochar++;
else if (*ochar == '-') else if (*ochar == '-')
ochar++; ochar++;
else else
cops |= op; cops |= op;
mvars->ops[M] |= op & (XOP_HAVE_CREATE|XOP_HAVE_REMOVE|XOP_HAVE_EXPUNGE); ops[M] |= op & (XOP_HAVE_CREATE|XOP_HAVE_REMOVE|XOP_HAVE_EXPUNGE);
break; break;
case 'R': case 'R':
op = OP_REMOVE|XOP_HAVE_REMOVE; op = OP_REMOVE|XOP_HAVE_REMOVE;
@ -439,7 +514,7 @@ main( int argc, char **argv )
cops |= XOP_PULL|XOP_PUSH; cops |= XOP_PULL|XOP_PUSH;
/* fallthrough */ /* fallthrough */
case '0': case '0':
mvars->ops[M] |= XOP_HAVE_TYPE; ops[M] |= XOP_HAVE_TYPE;
break; break;
case 'n': case 'n':
case 'd': case 'd':
@ -462,13 +537,13 @@ main( int argc, char **argv )
} }
if (op & OP_MASK_TYPE) if (op & OP_MASK_TYPE)
switch (op & XOP_MASK_DIR) { switch (op & XOP_MASK_DIR) {
case XOP_PULL: mvars->ops[S] |= op & OP_MASK_TYPE; break; case XOP_PULL: ops[S] |= op & OP_MASK_TYPE; break;
case XOP_PUSH: mvars->ops[M] |= op & OP_MASK_TYPE; break; case XOP_PUSH: ops[M] |= op & OP_MASK_TYPE; break;
default: cops |= op; break; default: cops |= op; break;
} }
else else
cops |= op; cops |= op;
mvars->ops[M] |= XOP_HAVE_TYPE; ops[M] |= XOP_HAVE_TYPE;
break; break;
case 'L': case 'L':
op = XOP_PULL; op = XOP_PULL;
@ -518,33 +593,42 @@ main( int argc, char **argv )
} }
#endif #endif
if (merge_ops( cops, mvars->ops )) if (merge_ops( cops, ops ))
return 1; return 1;
if (load_config( config, pseudo )) if (load_config( config, pseudo ))
return 1; return 1;
if (!mvars->all && !argv[mvars->oind]) {
fputs( "No channel specified. Try '" EXE " -h'\n", stderr );
return 1;
}
if (!channels) { if (!channels) {
fputs( "No channels defined. Try 'man " EXE "'\n", stderr ); fputs( "No channels defined. Try 'man " EXE "'\n", stderr );
return 1; return 1;
} }
mvars->chan = channels; if (mvars->all) {
if (mvars->all) for (chan = channels; chan; chan = chan->next)
mvars->multiple = channels->next != 0; add_channel( &chanapp, chan, ops );
else if (argv[mvars->oind + 1]) } else {
mvars->multiple = 1; for (; argv[oind]; oind++) {
else for (group = groups; group; group = group->next) {
for (group = groups; group; group = group->next) if (!strcmp( group->name, argv[oind] )) {
if (!strcmp( group->name, argv[mvars->oind] )) { for (channame = group->channels; channame; channame = channame->next)
mvars->multiple = 1; if (!add_named_channel( &chanapp, channame->string, ops ))
break; mvars->ret = 1;
goto gotgrp;
}
} }
mvars->argv = argv; if (!add_named_channel( &chanapp, argv[oind], ops ))
mvars->ret = 1;
gotgrp: ;
}
}
if (!chans) {
fputs( "No channel specified. Try '" EXE " -h'\n", stderr );
return 1;
}
mvars->chanptr = chans;
mvars->multiple = !!chans->next;
mvars->cben = 1; mvars->cben = 1;
sync_chans( mvars, E_START ); sync_chans( mvars, E_START );
main_loop(); main_loop();
@ -558,7 +642,6 @@ main( int argc, char **argv )
static void store_opened( store_t *ctx, void *aux ); static void store_opened( store_t *ctx, void *aux );
static void store_listed( int sts, void *aux ); static void store_listed( int sts, void *aux );
static int sync_listed_boxes( main_vars_t *mvars, box_ent_t *mbox ); static int sync_listed_boxes( main_vars_t *mvars, box_ent_t *mbox );
static void done_sync_dyn( int sts, void *aux );
static void done_sync_2_dyn( int sts, void *aux ); static void done_sync_2_dyn( int sts, void *aux );
static void done_sync( int sts, void *aux ); static void done_sync( int sts, void *aux );
@ -567,10 +650,8 @@ static void done_sync( int sts, void *aux );
static void static void
sync_chans( main_vars_t *mvars, int ent ) sync_chans( main_vars_t *mvars, int ent )
{ {
group_conf_t *group;
channel_conf_t *chan;
box_ent_t *mbox, *nmbox, **mboxapp; box_ent_t *mbox, *nmbox, **mboxapp;
char *channame, **boxes[2], *boxp, *nboxp; char **boxes[2];
const char *labels[2]; const char *labels[2];
int t, mb, sb, cmp; int t, mb, sb, cmp;
@ -580,68 +661,8 @@ sync_chans( main_vars_t *mvars, int ent )
case E_OPEN: goto opened; case E_OPEN: goto opened;
case E_SYNC: goto syncone; case E_SYNC: goto syncone;
} }
for (;;) { do {
mvars->boxlist = 0; mvars->chan = mvars->chanptr->conf;
mvars->boxes = 0;
if (!mvars->all) {
if (mvars->chanptr)
channame = mvars->chanptr->string;
else {
for (group = groups; group; group = group->next)
if (!strcmp( group->name, mvars->argv[mvars->oind] )) {
mvars->chanptr = group->channels;
channame = mvars->chanptr->string;
goto gotgrp;
}
channame = mvars->argv[mvars->oind];
gotgrp: ;
}
if ((boxp = strchr( channame, ':' )))
*boxp++ = 0;
for (chan = channels; chan; chan = chan->next)
if (!strcmp( chan->name, channame ))
goto gotchan;
error( "No channel or group named '%s' defined.\n", channame );
mvars->ret = 1;
goto gotnone;
gotchan:
mvars->chan = chan;
if (boxp) {
if (!chan->patterns) {
error( "Cannot override mailbox in channel '%s' - no Patterns.\n", channame );
mvars->ret = 1;
goto gotnone;
}
mvars->boxlist = 1;
mboxapp = &mvars->boxes;
for (;;) {
nboxp = strpbrk( boxp, ",\n" );
if (nboxp) {
t = nboxp - boxp;
*nboxp++ = 0;
} else {
t = strlen( boxp );
}
mbox = nfmalloc( sizeof(*mbox) );
if (t)
mbox->name = nfstrndup( boxp, t );
else
mbox->name = nfstrndup( "INBOX", 5 );
mbox->present[M] = mbox->present[S] = BOX_POSSIBLE;
mbox->next = 0;
*mboxapp = mbox;
mboxapp = &mbox->next;
if (!nboxp)
break;
boxp = nboxp;
}
}
}
merge_actions( mvars->chan, mvars->ops, XOP_HAVE_TYPE, OP_MASK_TYPE, OP_MASK_TYPE );
merge_actions( mvars->chan, mvars->ops, XOP_HAVE_CREATE, OP_CREATE, 0 );
merge_actions( mvars->chan, mvars->ops, XOP_HAVE_REMOVE, OP_REMOVE, 0 );
merge_actions( mvars->chan, mvars->ops, XOP_HAVE_EXPUNGE, OP_EXPUNGE, 0 );
info( "Channel %s\n", mvars->chan->name ); info( "Channel %s\n", mvars->chan->name );
mvars->skip = mvars->cben = 0; mvars->skip = mvars->cben = 0;
for (t = 0; t < 2; t++) { for (t = 0; t < 2; t++) {
@ -675,11 +696,11 @@ sync_chans( main_vars_t *mvars, int ent )
if (mvars->state[M] != ST_OPEN || mvars->state[S] != ST_OPEN) if (mvars->state[M] != ST_OPEN || mvars->state[S] != ST_OPEN)
return; return;
if (!mvars->boxlist && mvars->chan->patterns) { if (!mvars->chanptr->boxlist && mvars->chan->patterns) {
mvars->boxlist = 1; mvars->chanptr->boxlist = 2;
boxes[M] = filter_boxes( mvars->ctx[M]->boxes, mvars->chan->boxes[M], mvars->chan->patterns ); boxes[M] = filter_boxes( mvars->ctx[M]->boxes, mvars->chan->boxes[M], mvars->chan->patterns );
boxes[S] = filter_boxes( mvars->ctx[S]->boxes, mvars->chan->boxes[S], mvars->chan->patterns ); boxes[S] = filter_boxes( mvars->ctx[S]->boxes, mvars->chan->boxes[S], mvars->chan->patterns );
mboxapp = &mvars->boxes; mboxapp = &mvars->chanptr->boxes;
for (mb = sb = 0; boxes[M][mb] || boxes[S][sb]; ) { for (mb = sb = 0; boxes[M][mb] || boxes[S][sb]; ) {
mbox = nfmalloc( sizeof(*mbox) ); mbox = nfmalloc( sizeof(*mbox) );
if (!(cmp = !boxes[M][mb] - !boxes[S][sb]) && !(cmp = cmp_box_names( boxes[M] + mb, boxes[S] + sb ))) { if (!(cmp = !boxes[M][mb] - !boxes[S][sb]) && !(cmp = cmp_box_names( boxes[M] + mb, boxes[S] + sb ))) {
@ -706,14 +727,15 @@ sync_chans( main_vars_t *mvars, int ent )
free( boxes[M] ); free( boxes[M] );
free( boxes[S] ); free( boxes[S] );
} }
mvars->boxptr = mvars->chanptr->boxes;
if (mvars->list && mvars->multiple) if (mvars->list && mvars->multiple)
printf( "%s:\n", mvars->chan->name ); printf( "%s:\n", mvars->chan->name );
syncml: syncml:
mvars->done = mvars->cben = 0; mvars->done = mvars->cben = 0;
if (mvars->boxlist) { if (mvars->chanptr->boxlist) {
while ((mbox = mvars->boxes)) { while ((mbox = mvars->boxptr)) {
mvars->boxes = mbox->next; mvars->boxptr = mbox->next;
if (sync_listed_boxes( mvars, mbox )) if (sync_listed_boxes( mvars, mbox ))
goto syncw; goto syncw;
} }
@ -743,23 +765,18 @@ sync_chans( main_vars_t *mvars, int ent )
mvars->skip = mvars->cben = 1; mvars->skip = mvars->cben = 1;
return; return;
} }
for (nmbox = mvars->boxes; (mbox = nmbox); ) { if (mvars->chanptr->boxlist == 2) {
nmbox = mbox->next; for (nmbox = mvars->chanptr->boxes; (mbox = nmbox); ) {
free( mbox->name ); nmbox = mbox->next;
free( mbox ); free( mbox->name );
free( mbox );
}
mvars->chanptr->boxes = 0;
mvars->chanptr->boxlist = 0;
} }
next2: next2:
if (mvars->all) { ;
if (!(mvars->chan = mvars->chan->next)) } while ((mvars->chanptr = mvars->chanptr->next));
break;
} else {
if (mvars->chanptr && (mvars->chanptr = mvars->chanptr->next))
continue;
gotnone:
if (!mvars->argv[++mvars->oind])
break;
}
}
for (t = 0; t < N_DRIVERS; t++) for (t = 0; t < N_DRIVERS; t++)
drivers[t]->cleanup(); drivers[t]->cleanup();
} }
@ -789,7 +806,7 @@ store_opened( store_t *ctx, void *aux )
return; return;
} }
mvars->ctx[t] = ctx; mvars->ctx[t] = ctx;
if (!mvars->skip && !mvars->boxlist && mvars->chan->patterns && !ctx->listed) { if (!mvars->skip && !mvars->chanptr->boxlist && mvars->chan->patterns && !ctx->listed) {
for (flags = 0, cpat = mvars->chan->patterns; cpat; cpat = cpat->next) { for (flags = 0, cpat = mvars->chan->patterns; cpat; cpat = cpat->next) {
const char *pat = cpat->string; const char *pat = cpat->string;
if (*pat != '!') { if (*pat != '!') {
@ -873,35 +890,21 @@ sync_listed_boxes( main_vars_t *mvars, box_ent_t *mbox )
if (!mvars->list) { if (!mvars->list) {
nfasprintf( &mvars->names[M], "%s%s", mpfx, mbox->name ); nfasprintf( &mvars->names[M], "%s%s", mpfx, mbox->name );
nfasprintf( &mvars->names[S], "%s%s", spfx, mbox->name ); nfasprintf( &mvars->names[S], "%s%s", spfx, mbox->name );
free( mbox->name );
sync_boxes( mvars->ctx, (const char **)mvars->names, mbox->present, mvars->chan, done_sync_2_dyn, mvars ); sync_boxes( mvars->ctx, (const char **)mvars->names, mbox->present, mvars->chan, done_sync_2_dyn, mvars );
free( mbox );
return 1; return 1;
} }
printf( "%s%s <=> %s%s\n", mpfx, mbox->name, spfx, mbox->name ); printf( "%s%s <=> %s%s\n", mpfx, mbox->name, spfx, mbox->name );
} else { } else {
if (!mvars->list) { if (!mvars->list) {
mvars->names[M] = mvars->names[S] = mbox->name; mvars->names[M] = mvars->names[S] = mbox->name;
sync_boxes( mvars->ctx, (const char **)mvars->names, mbox->present, mvars->chan, done_sync_dyn, mvars ); sync_boxes( mvars->ctx, (const char **)mvars->names, mbox->present, mvars->chan, done_sync, mvars );
free( mbox );
return 1; return 1;
} }
puts( mbox->name ); puts( mbox->name );
} }
free( mbox->name );
free( mbox );
return 0; return 0;
} }
static void
done_sync_dyn( int sts, void *aux )
{
main_vars_t *mvars = (main_vars_t *)aux;
free( mvars->names[M] );
done_sync( sts, aux );
}
static void static void
done_sync_2_dyn( int sts, void *aux ) done_sync_2_dyn( int sts, void *aux )
{ {

Loading…
Cancel
Save