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 <hurtta+elm@posti.FMI.FI> (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:
*/
syntax highlighted by Code2HTML, v. 0.9.1