static char rcsid[] = "@(#)$Id: aliases.c,v 1.8.40.1 2007/08/25 07:45:27 hurtta Exp $"; /****************************************************************************** * The Elm (ME+) Mail System - $Revision: 1.8.40.1 $ $State: Exp $ * * Author: Kari Hurtta (was hurtta+elm@ozone.FMI.FI) *****************************************************************************/ #include "def_aliases.h" DEBUG_VAR(Debug,__FILE__,"alias"); struct alias_view { int classnum; int index; }; static struct AliasView ** aliasview_list = NULL; static int aliasview_list_len = 0; struct AliasView * new_aliasview() { int idx; struct AliasView **X; struct AliasView *r = safe_malloc(sizeof (*r)); /* bzero is defined hdrs/defs.h */ bzero((void *)r,sizeof (*r)); r->magic = ALIASVIEW_magic; r->aliasclasscount = 0; r->aliasclass = NULL; r->view = NULL; r->view_len = 0; r->normal_alias_len = 0; for (idx = 0; idx < aliasview_list_len; idx++) if (!aliasview_list[idx]) { DPRINT(Debug,7,(&Debug, "malloc_view: Re-using aliasview index %d\n", idx)); goto found; } X = safe_realloc(aliasview_list,(aliasview_list_len+1)* sizeof (*X)); X[aliasview_list_len] = NULL; aliasview_list = X; idx = aliasview_list_len++; DPRINT(Debug,7,(&Debug, "malloc_view: Allocing new aliasview index %d\n", idx)); found: aliasview_list[idx] = r; return r; } static void reset_aliasview P_((struct AliasView *aview)); static void reset_aliasview(aview) struct AliasView *aview; { if (aview->view) { free(aview->view); aview->view = NULL; } aview->view_len = 0; aview->normal_alias_len = 0; } static void free_aliasview1 P_((struct AliasView **x)); static void free_aliasview1(x) struct AliasView **x; { struct AliasView *r = *x; if (r->aliasclass) { int i; for (i = 0; i < r->aliasclasscount; i++) { if (r->aliasclass[i].atype->magic != ALIASTYPE_magic) panic("ALIAS VIEW PANIC",__FILE__,__LINE__,"free_aliasview", "bad aliastype magic",0); r->aliasclass[i].atype->at_free_it(& (r->aliasclass[i]) ); r->aliasclass[i].atype = NULL; /* Invalidate */ } free(r->aliasclass); r->aliasclass = NULL; } r->aliasclasscount = 0; reset_aliasview(r); r->magic = 0; /* Invalidate */ free(r); r = NULL; *x = r; } void free_aliasview(x) struct AliasView **x; { int i; struct AliasView *r = *x; if (r->magic != ALIASVIEW_magic) panic("ALIAS VIEW PANIC",__FILE__,__LINE__,"free_aliasview", "bad aliasview magic",0); for ( i = 0; i < aliasview_list_len; i++) { if (aliasview_list[i] == r) { SIGDPRINT(Debug,7,(&Debug, "free_aliasview: Aliasview index %d goes free\n", i)); aliasview_list[i] = NULL; goto okei; } } panic("MBX VIEW PANIC",__FILE__,__LINE__,"free_aliasview", "aliasview not found from list",0); okei: free_aliasview1(&r); *x = r; } void free_all_aliasviews() { if (aliasview_list) { int i; for ( i = 0; i < aliasview_list_len; i++) { if (aliasview_list[i]) { SIGDPRINT(Debug,7,(&Debug,"free_all_aliasviews: [%d]\n", i)); if (aliasview_list[i]->magic != ALIASVIEW_magic) panic("MBX VIEW PANIC",__FILE__,__LINE__,"free_all_aliasviews", "Bad magic number",0); free_aliasview1(& (aliasview_list[i])); } } free(aliasview_list); aliasview_list = NULL; } aliasview_list_len = 0; } struct aliasclass * add_aliasclass(x,t) struct AliasView *x; struct alias_type *t; { if (t->magic != ALIASTYPE_magic) panic("ALIAS VIEW PANIC",__FILE__,__LINE__,"add_aliasclass", "bad aliastype magic",0); x->aliasclass = safe_realloc(x->aliasclass, ( x->aliasclasscount +1) * sizeof (x->aliasclass[0])); x->aliasclass[x->aliasclasscount].atype = t; x->aliasclass[x->aliasclasscount].p.dummy = NULL; t->at_init_it(& (x->aliasclass[x->aliasclasscount])); return (& (x->aliasclass[x->aliasclasscount++])); } struct alias_rec * give_alias(aview,index) struct AliasView *aview; int index; { int cx; int cindex; if (aview->magic != ALIASVIEW_magic) panic("ALIAS VIEW PANIC",__FILE__,__LINE__,"give_alias", "bad aliasview magic",0); if (index < 0 || index >= aview->view_len) panic("ALIAS VIEW PANIC",__FILE__,__LINE__,"give_alias", "bad index",0); cx = aview->view[index].classnum; cindex = aview->view[index].index; if (cx < 0 || cx >= aview->aliasclasscount) panic("ALIAS VIEW PANIC",__FILE__,__LINE__,"give_alias", "bad class number",0); if (aview->aliasclass[cx].atype->magic != ALIASTYPE_magic) panic("ALIAS VIEW PANIC",__FILE__,__LINE__,"give_alias", "bad aliastype magic",0); return aview->aliasclass[cx].atype-> at_it_give_alias( & (aview->aliasclass[cx] ), cindex); } int get_alias_count(aview) struct AliasView *aview; { return aview->normal_alias_len; } int get_total_alias_count(aview) struct AliasView *aview; { return aview->view_len; } /* current == index+1 value is used only by caller */ int get_alias_current(aview) struct AliasView *aview; { return aview->current; } void set_alias_current(aview,cur) struct AliasView *aview; int cur; { if (aview->magic != ALIASVIEW_magic) panic("ALIAS VIEW PANIC",__FILE__,__LINE__,"set_alias_current", "bad aliasview magic",0); aview->current = cur; } int get_alias_selected(aview) struct AliasView *aview; { return aview->selected; } void set_alias_selected(aview,sel) struct AliasView *aview; int sel; { if (aview->magic != ALIASVIEW_magic) panic("ALIAS VIEW PANIC",__FILE__,__LINE__,"set_alias_selected", "bad aliasview magic",0); aview->selected = sel; } static void rebuild_aliasview P_((struct AliasView *aview)); static void rebuild_aliasview(aview) struct AliasView *aview; { int len = 0; int i; int dup = 0; int x; reset_aliasview(aview); for (i = 0; i < aview->aliasclasscount; i++) { len += aview->aliasclass[i].atype-> at_get_count_it(& (aview->aliasclass[i])); } DPRINT(Debug,4, (&Debug, "rebuild_aliasview: len=%d\n",len)); if (len < 1) return; aview->view = safe_malloc(len * sizeof (aview->view[0])); x = 0; for (i = 0; i < aview->aliasclasscount && x < len; i++) { int y; int count = aview->aliasclass[i].atype-> at_get_count_it(& (aview->aliasclass[i])); for (y = 0; y < count && x < len; y++) { struct alias_rec *a; int D; aview->view[x].classnum = i; aview->view[x].index = y; a = aview->aliasclass[i].atype-> at_it_give_alias( & (aview->aliasclass[i] ), y); if (a) { int isdup = 0; /* Check for duplicates ... */ for (D = 0; D < x; D++) { int cx = aview->view[D].classnum; int cindex = aview->view[D].index; struct alias_rec *b = aview->aliasclass[cx].atype-> at_it_give_alias( & (aview->aliasclass[cx] ), cindex); if (b && 0 == strcmp(b->alias,a->alias)) { DPRINT(Debug,14, (&Debug, "rebuild_aliasview: %d [%d/%d] is previous same alias than [%d/%d] \"%s\"\n", D,cx,cindex, i,y, b->alias)); isdup++; break; } if (cx >= i) break; } if (isdup) { dup++; if (!(a->type & DUPLICATE)) { a->type |= DUPLICATE; DPRINT(Debug,14, (&Debug, "rebuild_aliasview: Marking [%d/%d] \"%s\" as duplicate (not added as %d)\n", i,y, a->name,x)); } } else { if (a->type & DUPLICATE) { DPRINT(Debug,14, (&Debug, "rebuild_aliasview: Clearing [%d/%d] duplicate mark\n", i,y)); a->type &= ~DUPLICATE; } x++; } } } } DPRINT(Debug,4, (&Debug, "rebuild_aliasview: %d normal aliases\n",x)); aview->normal_alias_len = x; if (dup) { /* Add duplicates */ for (i = 0; i < aview->aliasclasscount && x < len; i++) { int y; int count = aview->aliasclass[i].atype-> at_get_count_it(& (aview->aliasclass[i])); for (y = 0; y < count && x < len; y++) { struct alias_rec *a = aview->aliasclass[i].atype-> at_it_give_alias( & (aview->aliasclass[i] ), y); if (a) { if (a->type & DUPLICATE) { aview->view[x].classnum = i; aview->view[x].index = y; x++; } } } } } aview->view_len = x; DPRINT(Debug,4, (&Debug, "rebuild_aliasview: len=%d duplicates=%d\n", x,dup)); } /* Return 1 if changes */ int update_aview(aview) struct AliasView *aview; { int r = 0; if (aview->magic != ALIASVIEW_magic) panic("ALIAS VIEW PANIC",__FILE__,__LINE__,"update_aview", "bad aliasview magic",0); if (aview->aliasclass) { int i; for (i = 0; i < aview->aliasclasscount; i++) { if (aview->aliasclass[i].atype->magic != ALIASTYPE_magic) panic("ALIAS VIEW PANIC",__FILE__,__LINE__,"update_aview", "bad aliastype magic",0); if (aview->aliasclass[i].atype-> at_update_it(& (aview->aliasclass[i]))) { int j,z; r = 1; } } if (r) rebuild_aliasview(aview); } DPRINT(Debug,4, (&Debug, "update_aview=%d\n",r)); return r; } struct sort_data2 { struct aliasclass *c; struct alias_view w; }; struct alias_rec * give_alias_s(s) struct sort_data2 *s; { if (s->c->atype->magic != ALIASTYPE_magic) panic("ALIAS VIEW PANIC",__FILE__,__LINE__,"give_alias_s", "bad aliastype magic",0); return s->c->atype->at_it_give_alias(s->c, s->w.index); } void sort_aview (aview,func) struct AliasView *aview; alias_compare_func *func; { int i; struct sort_data2 * array; /* Little dirty ... */ typedef int (*compar) P_((const void *, const void *)); compar X = (compar) func; int len = aview->view_len; if (aview->magic != ALIASVIEW_magic) panic("ALIAS VIEW PANIC",__FILE__,__LINE__,"sort_aview", "bad aliasview magic",0); if (len < 2) return; array = safe_malloc(len * sizeof (array[0])); for (i = 0; i < len; i++) { int cx = aview->view[i].classnum; int cindex = aview->view[i].index; if (cx < 0 || cx >= aview->aliasclasscount) panic("ALIAS VIEW PANIC",__FILE__,__LINE__,"sort_aview", "bad class number",0); array[i].c = & (aview->aliasclass[cx] ); array[i].w = aview->view[i]; } qsort(array,len,sizeof (array[0]), X); for (i = 0; i < len; i++) { aview->view[i] = array[i].w; } free(array); } /* * Local Variables: * mode:c * c-basic-offset:4 * buffer-file-coding-system: iso-8859-1 * End: */