/* * $Id: memory.c,v 0.48 2003/08/23 16:38:15 ceder Exp $ * Copyright (C) 1991-1994, 1996-1999, 2001-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * Memory allocators/deallocators/initializers. * * These functions should be used instead of smalloc/srealloc. */ #if HAVE_CONFIG_H # include #endif #include #ifdef HAVE_STRING_H # include #endif #include #include "timewrap.h" #include "s-string.h" #include "kom-types.h" #include "kom-memory.h" #include "server/smalloc.h" #include "log.h" #include "lyskomd.h" #include "ram-io.h" #include "local-to-global.h" static int person_cnt = 0; static int conference_cnt = 0; static int text_stat_cnt = 0; /* Forward declarations */ static void clear_mark_list (Mark_list *mark_list); static Mark_list copy_mark_list (Mark_list ml); static void clear_member_list (Member_list *m); static Member_list copy_member_list (Member_list ml); static void clear_membership (Membership *mship); static Membership copy_membership (Membership m); static void clear_membership_list (Membership_list *mlist); static Membership_list copy_membership_list (Membership_list ml); static void copy_aux_item_list(Aux_item_list *dest, const Aux_item_list *src); /* Conf_type */ void init_conf_type(Conf_type *ct) { ct->rd_prot = 0; ct->original = 0; ct->secret = 0; ct->letter_box = 0; ct->allow_anon = 1; ct->forbid_secret = 0; ct->reserved2 = 0; ct->reserved3 = 0; } /* Conference */ Conference * alloc_conference(void) { Conference *c; conference_cnt++; c = smalloc(sizeof(Conference)); init_conference(c); return c; } void free_conference(Conference *confp) { if ( confp == NULL ) return; conference_cnt--; clear_conference(confp); l2g_destruct(&confp->texts); sfree(confp); } void clear_conference(Conference *confp) { s_clear(&confp->name); clear_member_list(&confp->members); l2g_clear(&confp->texts); free_aux_item_list(&confp->aux_item_list); init_conference(confp); } Conference * copy_conference (const Conference *o) { Conference *c; c = alloc_conference(); c->type = o->type; c->creator = o->creator; c->supervisor = o->supervisor; c->permitted_submitters = o->permitted_submitters; c->super_conf = o->super_conf; c->creation_time = o->creation_time; c->presentation = o->presentation; c->last_written = o->last_written; c->msg_of_day = o->msg_of_day; c->nice = o->nice; c->keep_commented = o->keep_commented; c->expire = o->expire; s_strcpy(&c->name, o->name); c->highest_aux = o->highest_aux; copy_aux_item_list(&c->aux_item_list, &o->aux_item_list); c->members = copy_member_list(o->members); l2g_copy(&c->texts, &o->texts); return c; } void init_conference (Conference *c) { init_conf_type(&c->type); c->creator = 0; c->supervisor = 0; c->permitted_submitters = 0; c->super_conf = 0; c->creation_time = NO_TIME; c->presentation = 0; c->last_written = NO_TIME; c->msg_of_day = 0; c->nice = 0; c->keep_commented = 0; c->highest_aux = 0; c->expire = 0; c->name = EMPTY_STRING; init_member_list(&c->members); l2g_init(&c->texts); init_aux_item_list(&c->aux_item_list); } /* Dynamic_session_info */ void init_dynamic_session_info (Dynamic_session_info *d) { d->session = 0; d->person = 0; d->working_conference = 0; d->idle_time = 0; d->flags.invisible = FALSE; d->flags.user_active_used = FALSE; d->flags.user_absent = FALSE; d->flags.reserved3 = FALSE; d->flags.reserved4 = FALSE; d->flags.reserved5 = FALSE; d->flags.reserved6 = FALSE; d->flags.reserved7 = FALSE; d->what_am_i_doing = EMPTY_STRING; } /* Mark_list */ static void clear_mark_list(Mark_list *mark_list) { if ( mark_list == NULL ) { kom_log("clear_mark_list(): mark_list == NULL.\n"); return; } sfree(mark_list->marks); init_mark_list(mark_list); } static Mark_list copy_mark_list(Mark_list ml) { Mark_list r; r.no_of_marks = ml.no_of_marks; r.marks = smalloc(r.no_of_marks * sizeof(Mark)); memcpy(r.marks, ml.marks, r.no_of_marks * sizeof(Mark)); return r; } void init_mark_list (Mark_list *ml) { ml->no_of_marks = 0; ml->marks = NULL; } /* Member_list */ static void clear_member_list(Member_list *m) { if ( m == NULL ) return; sfree(m->members); init_member_list(m); } static Member_list copy_member_list(Member_list ml) { Member_list res; res.no_of_members = ml.no_of_members; res.members = smalloc(res.no_of_members * sizeof ( Member )); memcpy(res.members, ml.members, res.no_of_members * sizeof ( Member )); return res; } void init_member_list (Member_list *ml) { ml->no_of_members = 0; ml->members = NULL; } /* Member */ void init_member(Member *mem) { if (mem == NULL) { kom_log("init_member(): mem == NULL.\n"); return; } mem->member = 0; mem->added_by = 0; mem->added_at = NO_TIME; init_membership_type(&mem->type); } /* Membership */ static void clear_membership(Membership *mship) { if ( mship == NULL ) { kom_log("clear_membership(): mship == NULL.\n"); return; } sfree(mship->read_ranges); init_membership(mship); } static Membership copy_membership(Membership m) { Membership res; res = m; if (m.no_of_read_ranges != 0) { res.read_ranges = smalloc(m.no_of_read_ranges * sizeof(res.read_ranges[0])); memcpy(res.read_ranges, m.read_ranges, m.no_of_read_ranges * sizeof(res.read_ranges[0])); } else if (m.read_ranges != NULL) { kom_log("copy_membership(): " "read_ranges != NULL but no_of_read_ranges == 0\n"); res.read_ranges = NULL; } return res; } void init_membership_type(Membership_type *m) { m->invitation = 0; m->passive = 0; m->secret = 0; m->passive_message_invert = 0; m->reserved2 = 0; m->reserved3 = 0; m->reserved4 = 0; m->reserved5 = 0; } void init_membership(Membership *m) { m->conf_no = 0; m->priority = 0; m->no_of_read_ranges = 0; m->read_ranges = NULL; m->last_time_read = NO_TIME; m->added_by = 0; m->position = 0; m->added_at = NO_TIME; init_membership_type(&m->type); m->skip_read_texts = FALSE; } /* Membership_list */ static void clear_membership_list(Membership_list *mlist) { int i; if ( mlist == NULL ) { kom_log("clear_membership_list(): membership_list == NULL.\n"); return; } for ( i = 0; i < mlist->no_of_confs; i++ ) { clear_membership(&mlist->confs[i]); } sfree(mlist->confs); init_membership_list(mlist); } static Membership_list copy_membership_list(Membership_list ml) { Membership_list r; int i; r.no_of_confs = ml.no_of_confs; r.confs = smalloc(ml.no_of_confs * sizeof(Membership)); for ( i = 0; i < r.no_of_confs; i++ ) { r.confs[i] = copy_membership(ml.confs[i]); } return r; } void init_membership_list (Membership_list *m) { m->no_of_confs = 0; m->confs = NULL; } /* Static_session_info */ void init_static_session_info (Static_session_info *d) { d->username = EMPTY_STRING; d->hostname = EMPTY_STRING; d->ident_user = EMPTY_STRING; d->connection_time = NO_TIME; } /* Person */ Person * alloc_person(void) { Person *p; person_cnt++; p = smalloc(sizeof(Person)); init_person(p); return p; } void free_person(Person *person) { if ( person == NULL ) return; person_cnt--; clear_person(person); l2g_destruct(&person->created_texts); sfree(person); } void clear_person(Person *person) { s_clear(&person->username); l2g_clear(&person->created_texts); clear_mark_list(&person->marks); clear_membership_list(&person->conferences); init_person(person); } Person * copy_person(const Person *p) { Person *c; c = alloc_person(); c->user_area = p->user_area; c->privileges = p->privileges; c->flags = p->flags; c->last_login = p->last_login; c->total_time_present = p->total_time_present; c->sessions = p->sessions; c->created_lines = p->created_lines; c->created_bytes = p->created_bytes; c->read_texts = p->read_texts; c->no_of_text_fetches = p->no_of_text_fetches; c->created_persons = p->created_persons; c->created_confs = p->created_confs; s_strcpy(&c->username, p->username); l2g_copy(&c->created_texts, &p->created_texts); c->marks = copy_mark_list(p->marks); c->conferences = copy_membership_list(p->conferences); memcpy(&c->pwd, &p->pwd, sizeof(Password)); return c; } void init_person (Person *p) { p->user_area = 0; p->total_time_present = 0; p->sessions = 0; p->created_lines = 0; p->created_bytes = 0; p->read_texts = 0; p->no_of_text_fetches = 0; p->created_persons = 0; p->created_confs = 0; p->username = EMPTY_STRING; p->last_login = NO_TIME; init_priv_bits(&p->privileges); init_personal_flags(&p->flags); l2g_init(&p->created_texts); init_mark_list(&p->marks); init_membership_list(&p->conferences); /* No initialization of pwd is really needed, but this shuts up valgrind. */ memset(p->pwd, 0, PASSWD_LEN); } /* Personal_flags */ void init_personal_flags (Personal_flags *p) { p->unread_is_secret = 0; p->flg2 = 0; p->flg3 = 0; p->flg4 = 0; p->flg5 = 0; p->flg6 = 0; p->flg7 = 0; p->flg8 = 0; } /* Priv_bits */ void init_priv_bits (Priv_bits *pb) { pb->wheel = 0; pb->admin = 0; pb->statistic = 0; pb->create_pers = 0; pb->create_conf = 0; pb->change_name = 0; pb->flg7 = 0; pb->flg8 = 0; pb->flg9 = 0; pb->flg10 = 0; pb->flg11 = 0; pb->flg12 = 0; pb->flg13 = 0; pb->flg14 = 0; pb->flg15 = 0; pb->flg16 = 0; } /* Session_info */ void init_session_info (Session_info *s) { s->person = 0; s->what_am_i_doing = EMPTY_STRING; s->username = EMPTY_STRING; s->working_conference = 0; s->session = 0; s->connection_time = NO_TIME; s->idle_time = 0; } /* Session_info_ident */ void init_session_info_ident (Session_info_ident *s) { s->person = 0; s->what_am_i_doing = EMPTY_STRING; s->username = EMPTY_STRING; s->ident_user = EMPTY_STRING; s->hostname = EMPTY_STRING; s->working_conference = 0; s->session = 0; s->connection_time = NO_TIME; s->idle_time = 0; } /* Text_stat */ Text_stat * alloc_text_stat(void) { Text_stat *t; text_stat_cnt++; t = smalloc(sizeof(Text_stat)); init_text_stat(t); return t; } void free_text_stat(Text_stat *t) { if ( t == NULL ) return; text_stat_cnt--; clear_text_stat(t); sfree(t); } void clear_text_stat(Text_stat *t) { int i; for ( i = 0; i < t->no_of_misc; i++ ) { switch ( t->misc_items[ i ].type ) { case recpt: case cc_recpt: case bcc_recpt: case comm_to: case comm_in: case footn_to: case footn_in: case loc_no: case rec_time: case sent_by: case sent_at: /* No need to free anything for these. */ break; default: restart_kom("clear_text_stat(): unknown enum info_type %d.", t->misc_items[ i ].type); } } sfree(t->misc_items); free_aux_item_list(&t->aux_item_list); init_text_stat(t); } Text_stat * copy_text_stat(const Text_stat *t) { Text_stat *c; c = alloc_text_stat(); c->creation_time = t->creation_time; c->generation = t->generation; c->file_pos = t->file_pos; c->author = t->author; c->no_of_lines = t->no_of_lines; c->no_of_chars = t->no_of_chars; c->no_of_marks = t->no_of_marks; c->no_of_misc = t->no_of_misc; c->highest_aux = t->highest_aux; c->misc_items = smalloc(c->no_of_misc * sizeof(Misc_info)); memcpy(c->misc_items, t->misc_items, c->no_of_misc * sizeof(Misc_info)); copy_aux_item_list(&c->aux_item_list, &t->aux_item_list); return c; } void init_text_stat (Text_stat *t) { t->creation_time = NO_TIME; t->generation = 0; t->file_pos = 0; t->author = 0; t->no_of_lines = 0; t->no_of_chars = 0; t->no_of_marks = 0; t->no_of_misc = 0; t->highest_aux = 0; t->misc_items = NULL; init_aux_item_list(&t->aux_item_list); } /* struct tm */ void init_struct_tm (struct tm *t) { t->tm_sec = 0; t->tm_min = 0; t->tm_hour = 0; t->tm_mday = 0; t->tm_mon = 0; t->tm_year = 0; t->tm_wday = 0; t->tm_yday = 0; t->tm_isdst = 0; } /* Who_info */ void init_who_info (Who_info *w) { w->person = 0; w->what_am_i_doing = EMPTY_STRING; w->username = EMPTY_STRING; w->working_conference = 0; w->session_no = 0; } /* Who_info_ident */ void init_who_info_ident (Who_info_ident *w) { w->person = 0; w->what_am_i_doing = EMPTY_STRING; w->username = EMPTY_STRING; w->ident_user = EMPTY_STRING; w->hostname = EMPTY_STRING; w->working_conference = 0; w->session_no = 0; } /* Who_info_old */ void init_who_info_old (Who_info_old *w) { w->person = 0; w->what_am_i_doing = EMPTY_STRING; w->working_conference = 0; } /* Kom_info */ void clear_info(Info *i) { free_aux_item_list(&i->aux_item_list); } /* Aux_item_list */ void free_aux_item_list(Aux_item_list *list) { unsigned long i; if (list->items != NULL) { for (i = 0; i < list->length; i++) clear_aux_item(&list->items[i]); } list->length = 0; sfree(list->items); list->items = NULL; } static void copy_aux_item_list(Aux_item_list *dest, const Aux_item_list *src) { unsigned long i; dest->length = src->length; dest->items = smalloc(sizeof(Aux_item) * src->length); for (i = 0; i < src->length; i++) { copy_aux_item(&dest->items[i], &src->items[i]); } } void init_aux_item_list(Aux_item_list *list) { list->length = 0; list->items = NULL; } void init_aux_item_link(Aux_item_link *dest) { dest->target_type = NO_OBJECT_TYPE; dest->target_item = 0; dest->target_object.conf = 0; dest->target_object.text = 0; } void init_aux_item_flags(Aux_item_flags *dest) { dest->deleted = 0; dest->inherit = 0; dest->secret = 0; dest->hide_creator = 0; dest->dont_garb = 0; dest->reserved3 = 0; dest->reserved4 = 0; dest->reserved5 = 0; } void init_aux_item(Aux_item *dest) { dest->aux_no = 0; dest->creator = 0; dest->sent_at = 0; dest->inherit_limit = 0; dest->tag = 0; dest->data = EMPTY_STRING; init_aux_item_flags(&dest->flags); init_aux_item_link(&dest->linked_item); } void clear_aux_item(Aux_item *item) { s_clear(&item->data); init_aux_item(item); } void copy_aux_item(Aux_item *dest, const Aux_item *src) { dest->aux_no = src->aux_no; dest->creator = src->creator; dest->sent_at = src->sent_at; dest->flags = src->flags; dest->inherit_limit = src->inherit_limit; dest->tag = src->tag; dest->data = EMPTY_STRING; s_strcpy(&dest->data, src->data); dest->linked_item = src->linked_item; } /* * Other kind of functions */ void dump_alloc_counts(FILE *fp) { fprintf(fp, "---memory.c:\n\tperson: %d\n\tconference: %d\n", person_cnt, conference_cnt); fprintf(fp, "\ttext_stat: %d\n", text_stat_cnt); }