/**
* \file malias.c
*
* \brief Global mail aliases/lists
*
* \verbatim
*
* This code implements an extension to extended @mail which allows
* admin (and others who are so em@powered) to create mail aliases
* for the MUSH. Optionally, any player can be allowed to.
*
* Aliases are used by @mail'ing to !<alias name>
* Aliases have a name, a description, a list of members (dbrefs), an owner
* a size (how many members), and two kinds of flags.
* nflags control who can use/see an alias name, and mflags
* control who can see the alias members. The choices
* are everyone, alias members, owner, admin
*
* Interface:
* @malias[/list]
* @malias/members !name
* @malias[/create] !name=list-of-members
* @malias/destroy !name
* @malias/add !name=list-of-members
* @malias/remove !name=list-of-members
* @malias/desc !name=description
* @malias/nameprivs !name=flags
* @malias/listprivs !name=flags
* @malias/stat
* @malias/chown !name=owner (Admin only)
* @malias/nuke (Admin only)
*
* \endverbatim
*/
#define MA_INC 3 /**< How many maliases we malloc at a time */
#include "config.h"
#include "copyrite.h"
#ifdef I_SYS_TIME
#include <sys/time.h>
#else
#include <time.h>
#endif
#include <ctype.h>
#ifdef I_SYS_TYPES
#include <sys/types.h>
#endif
#include <string.h>
#include "conf.h"
#include "externs.h"
#include "mushdb.h"
#include "dbdefs.h"
#include "match.h"
#include "parse.h"
#include "malias.h"
#include "privtab.h"
#include "mymalloc.h"
#include "flags.h"
#include "pueblo.h"
#include "log.h"
#include "dbio.h"
#include "confmagic.h"
int ma_size = 0; /**< Number of maliases */
int ma_top = 0; /**< Top of alias array */
struct mail_alias *malias; /**< Pointer to linked list of aliases */
/** Privilege table for maliases. */
static PRIV malias_priv_table[] = {
{"Admin", 'A', ALIAS_ADMIN, ALIAS_ADMIN},
{"Members", 'M', ALIAS_MEMBERS, ALIAS_MEMBERS},
{"Owner", 'O', ALIAS_OWNER, ALIAS_OWNER},
{NULL, '\0', 0, 0}
};
static const char *get_shortprivs(struct mail_alias *m);
/***********************************************************
***** User-commands *****
***********************************************************/
/** List or create a malias.
* \verbatim
* This implements the @malias command (with no switches).
* \endverbatim
* \param player the enactor.
* \param arg1 name of malias to create or list, or NULL to list all.
* \param arg2 parameters for creation, or NULL to list.
*/
void
do_malias(dbref player, char *arg1, char *arg2)
{
if (!arg1 || !*arg1) {
if (arg2 && *arg2) {
notify(player, T("MAIL: Invalid malias command."));
return;
}
/* just the "@malias" command */
do_malias_list(player);
return;
}
if (arg2 && *arg2) {
/* Creating malias */
do_malias_create(player, arg1, arg2);
} else {
/* List specific alias - no arg2 */
do_malias_members(player, arg1);
}
}
/** Create a malias.
* \verbatim
* This implements the @malias/create command.
* \endverbatim
* \param player the enactor.
* \param alias name of malias to create.
* \param tolist parameters for creation.
*/
void
do_malias_create(dbref player, char *alias, char *tolist)
{
char *head, *tail, spot;
struct mail_alias *m;
char *na;
const char *buff, *good, *scan;
int i = 0;
dbref target;
dbref alist[100];
if (!IsPlayer(player)) {
notify(player, T("MAIL: Only players may create mail aliases."));
return;
}
if (!alias || !*alias || !tolist || !*tolist) {
notify(player, T("MAIL: What alias do you want to create?."));
return;
}
if (*alias != MALIAS_TOKEN) {
notify_format(player,
T("MAIL: All Mail aliases must begin with '%c'."),
MALIAS_TOKEN);
return;
}
good = "`$_-.'";
/* Make sure that the name contains legal characters only */
for (scan = alias + 1; scan && *scan; scan++) {
if (isalpha((unsigned char) *scan) || isdigit((unsigned char) *scan))
continue;
if (!strchr(good, *scan)) {
notify(player, T("MAIL: Invalid character in mail alias."));
return;
}
}
m = get_malias(GOD, alias); /* GOD can see all aliases */
if (m) { /* Ensures no duplicates! */
notify_format(player, T("MAIL: Mail Alias '%s' already exists."), alias);
return;
}
if (!ma_size) {
ma_size = MA_INC;
malias =
(struct mail_alias *) mush_malloc(sizeof(struct mail_alias) *
ma_size, "malias_list");
} else if (ma_top >= ma_size) {
ma_size += MA_INC;
m =
(struct mail_alias *) mush_malloc(sizeof(struct mail_alias) *
(ma_size), "malias_list");
memcpy(m, malias, sizeof(struct mail_alias) * ma_top);
mush_free((Malloc_t) malias, "malias_list");
malias = m;
}
i = 0;
/*
* Parse the player list
*/
head = (char *) tolist;
while (head && *head) {
while (*head == ' ')
head++;
tail = head;
while (*tail && (*tail != ' ')) {
if (*tail == '"') {
head++;
tail++;
while (*tail && (*tail != '"'))
tail++;
}
if (*tail)
tail++;
}
tail--;
if (*tail != '"')
tail++;
spot = *tail;
*tail = '\0';
/*
* Now locate a target
*/
if (!strcasecmp(head, "me"))
target = player;
else if (*head == '#') {
target = atoi(head + 1);
} else
target = lookup_player(head);
if (!(GoodObject(target)) || (!IsPlayer(target))) {
notify_format(player, T("MAIL: No such player '%s'."), head);
} else {
buff = unparse_object(player, target);
notify_format(player, T("MAIL: %s added to alias %s"), buff, alias);
alist[i] = target;
i++;
}
/*
* Get the next recip
*/
*tail = spot;
head = tail;
if (*head == '"')
head++;
if (i == 100)
break;
}
if (head && *head) {
notify(player, T("MAIL: Alias list is restricted to maximal 100 entries!"));
}
if (!i) {
notify(player, T("MAIL: No valid recipients for alias-list!"));
return;
}
m = &malias[ma_top];
m->members = (dbref *) mush_malloc(sizeof(dbref) * i, "malias_members");
memcpy(m->members, alist, sizeof(dbref) * i);
na = alias + 1;
m->size = i;
m->owner = player;
m->name = mush_strdup(na, "malias_name");
m->desc = compress(na);
add_check("malias_desc");
m->nflags = ALIAS_OWNER | ALIAS_MEMBERS;
m->mflags = ALIAS_OWNER;
ma_top++;
notify_format(player, T("MAIL: Alias set '%s' defined."), alias);
}
/** List maliases.
* \verbatim
* This function implements @malias/list.
* \endverbatim
* \param player the enactor.
*/
void
do_malias_list(dbref player)
{
struct mail_alias *m;
int i = 0;
int notified = 0;
for (i = 0; i < ma_top; i++) {
m = &malias[i];
if ((m->owner == player) || (m->nflags == 0) ||
((m->nflags & ALIAS_ADMIN) && Hasprivs(player)) ||
((m->nflags & ALIAS_MEMBERS) && ismember(m, player))) {
if (!notified) {
notify_format(player, "%-13s %-35s %s %-15s",
T("Name"), T("Alias Description"), T("Use See"),
T("Owner"));
notified++;
}
notify_format(player,
"%c%-12.12s %-35.35s %s %-15.15s", MALIAS_TOKEN, m->name,
uncompress((unsigned char *) (m->desc)), get_shortprivs(m),
Name(m->owner));
}
}
notify(player, T("***** End of Mail Aliases *****"));
}
/** List malias members.
* \verbatim
* This function implements @malias/members.
* \endverbatim
* \param player the enactor.
* \param alias name of the alias to list members of.
*/
void
do_malias_members(dbref player, char *alias)
{
struct mail_alias *m;
int i = 0;
char buff[BUFFER_LEN];
char *bp;
m = get_malias(player, alias);
if (!m) {
notify_format(player, T("MAIL: Alias '%s' not found."), alias);
return;
}
if ((m->owner == player) || (m->mflags == 0) ||
(Hasprivs(player)) ||
((m->mflags & ALIAS_MEMBERS) && ismember(m, player))) {
/* Dummy to avoid having to invert the "if" above ;-) */
} else {
notify(player, T("MAIL: Permission denied."));
return;
}
bp = buff;
safe_format(buff, &bp, T("MAIL: Alias %c%s: "), MALIAS_TOKEN, m->name);
for (i = 0; i < m->size; i++) {
safe_str(Name(m->members[i]), buff, &bp);
safe_chr(' ', buff, &bp);
/* Attention if player names may contain spaces!! */
}
*bp = '\0';
notify(player, buff);
}
FUNCTION(fun_malias)
{
/* With no arguments, list all alias names
* With one argument, it's either a delimiter or list all member dbrefs
* With two arguments, it's a malias name and a delimiter, and we
* list dbrefs, delimited
*/
int i;
int count = 0;
char sep = ' ';
struct mail_alias *m;
if (nargs >= 1) {
m = get_malias(executor, args[0]);
if (m) {
if (!delim_check(buff, bp, nargs, args, 2, &sep))
return;
if ((m->owner == executor) || (m->mflags == 0) ||
(Hasprivs(executor)) ||
((m->mflags & ALIAS_MEMBERS) && ismember(m, executor))) {
for (i = 0; i < m->size; i++) {
if (count++)
safe_chr(sep, buff, bp);
safe_dbref(m->members[i], buff, bp);
}
} else {
safe_str(T(e_perm), buff, bp);
}
return;
} else {
/* Perhaps it's a delimiter? */
if (arglens[0] > 1) {
/* Oops, not if it's longer than one character */
safe_str(T(e_match), buff, bp);
return;
}
if (!delim_check(buff, bp, nargs, args, 1, &sep))
return;
}
}
/* List maliases, possibly with a delimiter */
for (i = 0; i < ma_top; i++) {
m = &malias[i];
if ((m->owner == executor) || (m->nflags == 0) ||
((m->nflags & ALIAS_ADMIN) && Hasprivs(executor)) ||
((m->nflags & ALIAS_MEMBERS) && ismember(m, executor))) {
if (count++)
safe_chr(sep, buff, bp);
safe_chr(MALIAS_TOKEN, buff, bp);
safe_str(m->name, buff, bp);
}
}
}
/** Describe a malias.
* \verbatim
* This implements the @malias/desc command.
* \endverbatim
* \param player the enactor.
* \param alias name of the malias to describe.
* \param desc description to set.
*/
void
do_malias_desc(dbref player, char *alias, char *desc)
{
struct mail_alias *m;
if (!(m = get_malias(player, alias))) {
notify_format(player, T("MAIL: Alias %s not found."), alias);
return;
} else if (Wizard(player) || (player == m->owner)) {
if (m->desc)
free(m->desc); /* No need to update MEM_CHECK records here */
m->desc = compress(desc);
notify(player, T("MAIL: Description changed."));
} else
notify(player, T("MAIL: Permission denied."));
return;
}
/** Change ownership of a malias.
* \verbatim
* This implements the @malias/chown command.
* \endverbatim
* \param player the enactor.
* \param alias name of the malias to chown.
* \param owner name of the new owner.
*/
void
do_malias_chown(dbref player, char *alias, char *owner)
{
struct mail_alias *m;
dbref no = NOTHING;
if (!(m = get_malias(player, alias))) {
notify_format(player, T("MAIL: Alias %s not found."), alias);
return;
} else {
if (!Wizard(player)) {
notify(player, T("MAIL: You cannot do that!"));
return;
} else {
if ((no = lookup_player(owner)) == NOTHING) {
notify(player, T("MAIL: I cannot find that player."));
return;
}
m->owner = no;
notify(player, T("MAIL: Owner changed for alias."));
}
}
}
/** Change name of a malias.
* \verbatim
* This implements the @malias/rename command.
* \endverbatim
* \param player the enactor.
* \param alias name of the malias to rename.
* \param newname new name for the malias.
*/
void
do_malias_rename(dbref player, char *alias, char *newname)
{
struct mail_alias *m;
if ((m = get_malias(player, alias)) == NULL) {
notify(player, T("MAIL: I cannot find that alias!"));
return;
}
if (*newname != MALIAS_TOKEN) {
notify_format(player,
T("MAIL: Bad alias. Aliases must start with '%c'."),
MALIAS_TOKEN);
return;
}
if (get_malias(GOD, newname) != NULL) {
notify(player, T("MAIL: That name already exists!"));
return;
}
if (!Wizard(player) && !(m->owner == player)) {
notify(player, T("MAIL: Permission denied."));
return;
}
free(m->name); /* No need to update MEM_CHECK records here. */
m->name = strdup(newname + 1);
notify(player, T("MAIL: Mail Alias renamed."));
}
/** Delete a malias.
* \verbatim
* This implements the @malias/destroy command.
* \endverbatim
* \param player the enactor.
* \param alias name of the malias to destroy.
*/
void
do_malias_destroy(dbref player, char *alias)
{
struct mail_alias *m;
m = get_malias(player, alias);
if (!m) {
notify(player,
T
("MAIL: Not a valid alias. Remember to prefix the alias name with *."));
return;
}
if (Wizard(player) || (m->owner == player)) {
notify(player, T("MAIL: Alias Destroyed."));
if (m->members)
mush_free((Malloc_t) m->members, "malias_members");
if (m->name)
mush_free(m->name, "malias_name");
if (m->desc)
mush_free(m->desc, "malias_desc");
*m = malias[--ma_top];
} else {
notify(player, T("MAIL: Permission denied!"));
}
}
/** Set the membership list for a malias.
* \verbatim
* This implements the @malias/set command.
* \endverbatim
* \param player the enactor.
* \param alias name of the malias to set members for.
* \param tolist space-separated list of players to set as members.
*/
void
do_malias_set(dbref player, char *alias, char *tolist)
{
struct mail_alias *m;
int i = 0;
char *head, *tail, spot;
const char *buff;
dbref alist[100];
dbref target;
m = get_malias(player, alias);
if (!m) {
notify_format(player,
T
("MAIL: Not a valid alias. Remember to prefix the alias name with %c."),
MALIAS_TOKEN);
return;
}
if (!tolist || !*tolist) {
notify(player, T("MAIL: You must set the alias to a non-empty list."));
return;
}
if (!(Wizard(player) || (m->owner == player))) {
notify(player, T("MAIL: Permission denied!"));
return;
}
/*
* Parse the player list
*/
head = (char *) tolist;
while (head && *head) {
while (*head == ' ')
head++;
tail = head;
while (*tail && (*tail != ' ')) {
if (*tail == '"') {
head++;
tail++;
while (*tail && (*tail != '"'))
tail++;
}
if (*tail)
tail++;
}
tail--;
if (*tail != '"')
tail++;
spot = *tail;
*tail = '\0';
/*
* Now locate a target
*/
if (!strcasecmp(head, "me"))
target = player;
else if (*head == '#') {
target = atoi(head + 1);
} else
target = lookup_player(head);
if (!(GoodObject(target)) || (!IsPlayer(target))) {
notify_format(player, T("MAIL: No such player '%s'."), head);
} else {
buff = unparse_object(player, target);
notify_format(player, T("MAIL: %s added to alias %s"), buff, alias);
alist[i] = target;
i++;
}
/*
* Get the next recip
*/
*tail = spot;
head = tail;
if (*head == '"')
head++;
if (i == 100)
break;
}
if (head && *head) {
notify(player, T("MAIL: Alias list is restricted to maximal 100 entries!"));
}
if (!i) {
notify(player, T("MAIL: No valid recipients for alias-list!"));
return;
}
if (m->members)
mush_free((Malloc_t) m->members, "malias_members");
m->members = (dbref *) mush_malloc(sizeof(dbref) * i, "malias_members");
memcpy(m->members, alist, sizeof(dbref) * i);
m->size = i;
notify(player, T("MAIL: Alias list set."));
}
/** List all maliases.
* \verbatim
* This implements the @malias/list command.
* \endverbatim
* \param player the enactor.
*/
void
do_malias_all(dbref player)
{
struct mail_alias *m;
int i;
if (!Hasprivs(player)) {
do_malias_list(player);
return;
}
notify(player,
"Num Name Description Owner Count");
for (i = 0; i < ma_top; i++) {
m = &malias[i];
notify_format(player, "#%-4d %c%-10.10s %-40.40s %-11.11s (%3d)",
i, MALIAS_TOKEN, m->name,
uncompress((unsigned char *) m->desc),
Name(m->owner), m->size);
}
notify(player, T("***** End of Mail Aliases *****"));
}
/** Statistics on maliases.
* \verbatim
* This implements the @malias/stat command.
* \endverbatim
* \param player the enactor.
*/
void
do_malias_stats(dbref player)
{
if (!Hasprivs(player))
notify(player, T("MAIL: Permission denied."));
else {
notify_format(player,
T("MAIL: Number of mail aliases defined: %d"), ma_top);
notify_format(player, T("MAIL: Allocated slots %d"), ma_size);
}
}
/** Remove all maliases.
* \verbatim
* This implements the @malias/nuke command.
* \endverbatim
* \param player the enactor.
*/
void
do_malias_nuke(dbref player)
{
struct mail_alias *m;
int i;
if (!God(player)) {
notify(player, T("MAIL: Only god can do that!"));
return;
}
if (ma_size) { /* aliases defined ? */
for (i = 0; i < ma_top; i++) {
m = &malias[i];
if (m->name)
mush_free(m->name, "malias_name");
if (m->desc)
mush_free(m->desc, "malias_desc");
if (m->members)
mush_free((Malloc_t) m->members, "malias_members");
}
mush_free((Malloc_t) malias, "malias_list");
}
ma_size = ma_top = 0;
notify(player, T("MAIL: All mail aliases destroyed!"));
}
/** Set permisions on maliases.
* \verbatim
* This implements @malias/use and @malias/see
* \endverbatim
* \param player the enactor.
* \param alias name of the malias.
* \param privs string of privs to set.
* \param type if 1, setting nprivs, if 0, mprivs.
*/
void
do_malias_privs(dbref player, char *alias, char *privs, int type)
{
struct mail_alias *m;
int *p;
if (!(m = get_malias(player, alias))) {
notify(player, T("MAIL: I cannot find that alias!"));
return;
}
if (!Wizard(player) && (m->owner != player)) {
notify(player, T("MAIL: Permission denied."));
return;
}
p = type ? &m->mflags : &m->nflags;
*p = string_to_privs(malias_priv_table, privs, 0);
notify_format(player,
T("MAIL: Permission to see/use alias '%s' changed to %s"),
alias, privs_to_string(malias_priv_table, *p));
}
/** Add players to a malias.
* \param player dbref of enactor.
* \param alias name of malias.
* \param tolist string with list of players to add.
*/
void
do_malias_add(dbref player, char *alias, char *tolist)
{
char *head, *tail, spot;
struct mail_alias *m;
const char *buff;
int i = 0;
dbref target;
dbref alist[100];
dbref *members;
m = get_malias(player, alias);
if (!m) {
notify_format(player, T("MAIL: Mail Alias '%s' not found."), alias);
return;
}
if (!Wizard(player) && (m->owner != player)) {
notify(player, T("Permission denied."));
return;
}
i = 0;
/*
* Parse the player list
*/
head = (char *) tolist;
while (head && *head) {
while (*head == ' ')
head++;
tail = head;
while (*tail && (*tail != ' ')) {
if (*tail == '"') {
head++;
tail++;
while (*tail && (*tail != '"'))
tail++;
}
if (*tail)
tail++;
}
tail--;
if (*tail != '"')
tail++;
spot = *tail;
*tail = '\0';
/*
* Now locate a target
*/
if (!strcasecmp(head, "me"))
target = player;
else if (*head == '#') {
target = atoi(head + 1);
} else
target = lookup_player(head);
if (!(GoodObject(target)) || (!IsPlayer(target))) {
notify_format(player, T("MAIL: No such player '%s'."), head);
} else {
if (ismember(m, target)) {
notify_format(player,
T("MAIL: player '%s' exists already in alias %s."),
head, alias);
} else {
buff = unparse_object(player, target);
notify_format(player, T("MAIL: %s added to alias %s"), buff, alias);
alist[i] = target;
i++;
}
}
/*
* Get the next recip
*/
*tail = spot;
head = tail;
if (*head == '"')
head++;
if (i == 100)
break;
}
if (head && *head) {
notify(player, T("MAIL: Alias list is restricted to maximal 100 entries!"));
}
if (!i) {
notify(player, T("MAIL: No valid recipients for alias-list!"));
return;
}
members =
(dbref *) mush_malloc(sizeof(dbref) * (i + m->size), "malias_members");
memcpy(members, m->members, sizeof(dbref) * m->size);
memcpy(&members[m->size], alist, sizeof(dbref) * i);
mush_free((Malloc_t) m->members, "malias_members");
m->members = members;
m->size += i;
notify_format(player, T("MAIL: Alias set '%s' redefined."), alias);
}
/** Remove players from a malias.
* \param player dbref of enactor.
* \param alias name of malias.
* \param tolist string with list of players to remove.
*/
void
do_malias_remove(dbref player, char *alias, char *tolist)
{
char *head, *tail, spot;
struct mail_alias *m;
const char *buff;
int i = 0;
dbref target;
m = get_malias(player, alias);
if (!m) {
notify_format(player, T("MAIL: Mail Alias '%s' not found."), alias);
return;
}
if (!Wizard(player) && (m->owner != player)) {
notify(player, T("Permission denied."));
return;
}
i = 0;
/*
* Parse the player list
*/
head = (char *) tolist;
while (head && *head) {
while (*head == ' ')
head++;
tail = head;
while (*tail && (*tail != ' ')) {
if (*tail == '"') {
head++;
tail++;
while (*tail && (*tail != '"'))
tail++;
}
if (*tail)
tail++;
}
tail--;
if (*tail != '"')
tail++;
spot = *tail;
*tail = '\0';
/*
* Now locate a target
*/
if (!strcasecmp(head, "me"))
target = player;
else if (*head == '#') {
target = atoi(head + 1);
} else
target = lookup_player(head);
if (!(GoodObject(target)) || (!IsPlayer(target))) {
notify_format(player, T("MAIL: No such player '%s'."), head);
} else {
if (!(i = ismember(m, target))) {
notify_format(player, T("MAIL: player '%s' is not in alias %s."),
head, alias);
} else {
buff = unparse_object(player, target);
m->members[i - 1] = m->members[--m->size];
notify_format(player, T("MAIL: %s removed from alias %s"), buff, alias);
}
}
/*
* Get the next recip
*/
*tail = spot;
head = tail;
if (*head == '"')
head++;
}
notify_format(player, T("MAIL: Alias set '%s' redefined."), alias);
}
/***********************************************************
***** "Utility" functions *****
***********************************************************/
static const char *
get_shortprivs(struct mail_alias *m)
{
static char privs[10];
strcpy(privs, "-- -- ");
if (!m->nflags)
privs[0] = 'E';
else {
if (m->nflags & ALIAS_MEMBERS)
privs[0] = 'M';
if (m->nflags & ALIAS_ADMIN)
privs[1] = 'A';
if (!strncmp(privs, "--", 2))
privs[1] = 'O';
}
if (!m->mflags)
privs[4] = 'E';
else {
if (m->mflags & ALIAS_MEMBERS)
privs[4] = 'M';
if (m->mflags & ALIAS_ADMIN)
privs[5] = 'A';
if (!strncmp(privs + 4, "--", 2))
privs[5] = 'O';
}
return privs;
}
/** Is a player a member of a malias?
* \param m pointer to malias.
* \param player dbref of player.
* \retval 1 player is a member of the malias.
* \retval 0 player is not a member of the malias.
*/
int
ismember(struct mail_alias *m, dbref player)
{
int i;
for (i = 0; i < m->size; i++) {
if (player == m->members[i])
return (i + 1); /* To avoid entry "0" */
}
return 0;
}
/** Remove a destroyed player from all maliases.
* \param player player to remove from maliases.
*/
void
malias_cleanup(dbref player)
{
struct mail_alias *m;
int n, i = 0;
for (n = 0; n < ma_top; n++) {
m = &malias[n];
if ((i = ismember(m, player)) != 0) {
do_rawlog(LT_ERR, "Removing #%d from malias %s", player, m->name);
m->members[i - 1] = m->members[--m->size];
}
}
}
/** Get a malias pointer with permission checking.
* \param player player dbref, for permission check.
* \param alias name of malias to retrieve.
* \return pointer to malias structure, or NULL if player can't see it.
*/
struct mail_alias *
get_malias(dbref player, char *alias)
{
const char *mal;
struct mail_alias *m;
int i = 0;
if (*alias != MALIAS_TOKEN)
return NULL;
mal = alias + 1;
for (i = 0; i < ma_top; i++) {
m = &malias[i];
if ((m->owner == player) || (m->nflags == 0) ||
/* ((m->nflags & ALIAS_ADMIN) && Hasprivs(player)) || */
Hasprivs(player) ||
((m->nflags & ALIAS_MEMBERS) && ismember(m, player))) {
if (!strcasecmp(mal, m->name))
return m;
}
}
return NULL;
}
/***********************************************************
***** Loading and saving of mail-aliases *****
***********************************************************/
/** Load maliases from the mail db.
* \param fp file pointer to read from.
*/
void
load_malias(FILE * fp)
{
int i, j;
char buffer[BUFFER_LEN];
struct mail_alias *m;
char *s;
ma_top = getref(fp);
ma_size = ma_top;
if (ma_top > 0)
malias =
(struct mail_alias *) mush_malloc(sizeof(struct mail_alias) *
ma_size, "malias_list");
else
malias = NULL;
for (i = 0; i < ma_top; i++) {
m = &malias[i];
m->owner = getref(fp);
m->name = mush_strdup(getstring_noalloc(fp), "malias_name");
m->desc = compress(getstring_noalloc(fp));
add_check("malias_desc");
m->nflags = getref(fp);
m->mflags = getref(fp);
m->size = getref(fp);
if (m->size > 0) {
m->members =
(dbref *) mush_malloc(m->size * sizeof(dbref), "malias_members");
for (j = 0; j < m->size; j++) {
m->members[j] = getref(fp);
}
} else {
m->members = NULL;
}
}
s = fgets(buffer, sizeof(buffer), fp);
if (!s || strcmp(buffer, "\"*** End of MALIAS ***\"\n") != 0) {
do_rawlog(LT_ERR, T("MAIL: Error reading MALIAS list"));
}
}
/** Write maliases to the maildb
* \param fp file pointer to write to.
*/
void
save_malias(FILE * fp)
{
int i, j;
struct mail_alias *m;
putref(fp, ma_top);
for (i = 0; i < ma_top; i++) {
m = &malias[i];
putref(fp, m->owner);
putstring(fp, (char *) (m->name));
putstring(fp, uncompress(m->desc));
putref(fp, m->nflags);
putref(fp, m->mflags);
putref(fp, m->size);
for (j = 0; j < m->size; j++)
putref(fp, m->members[j]);
}
putstring(fp, "*** End of MALIAS ***");
}