Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Problem with MAIL files...

5 views
Skip to first unread message

Jerry Leichter

unread,
May 17, 1995, 3:00:00 AM5/17/95
to
We have a user who we think was over disk quota while lots of mail was
being delivered.

The result was that the user ended up with about 260 messages in their
MAIL folder and 60 messages in NEWMAIL (there are no other folders!).
Unfortunately their [.MAIL] subdirectory contains around 1300
MAIL$*MAI;1 files. So we got the user to issue a SET MAIL [.MAIL2]
command from mail expecting to end up with about 320 files (approx) in
[.MAIL2], and about 980 in [.MAIL] which we could delete.
Unfortunately ALL 1300 files got moved into [.MAIL2].

It seems like whatever algorithm MAIL uses to relocate its
MAIL$....MAI files is only approximate - possibly involving a
wildcard.

MAIL simply moves *all* files that have the right form.

Does anyone have a procedure for getting rid of spurious
MAIL$....MAI files?

I have two, one which I've used successfully, written in C; and one I've
never tried (though knowing the author, it probably works) which is a command
file. I've attached both below.

-- Jerry
----------------MAIL-SCAN.COM----------------
$!
$! From a message posted to INFO-VAX.
$!
$! Subject: Re: Yet ANOTHER Mail Problem ...
$! From: vanden...@eps.enet.dec.com (Hein RMS van den Heuvel)
$! Date: 24 OCT 94 09:35:27
$!
$! ...
$! So now lets move to the secondary problem you managed to get into.
$! There are a number of mail 'orphan' detectors on the net that should be
$! able to deal with this gracefully.
$!
$! It so happens (ha!) that I've written a special purpose on not too long
$! ago, that I'll repost. It is not too clean and you'll need to wrap it in a
$! 'loop though all users' too, and for now it only reports. You may want to
$! change it to generate a massive command file to delete or move all orphans
$! found. No smarts about current directory or mail file names, but it works
$! for me! Yes, a 'real' program with more RMS buffers would work faster and
$! without exceptions for 'funny' key values, but this thingie should get you
$! going. You can speed it up by giving it 98 as argument which cause it to
$! bother only with files after 15-Jun this year.
$start:
$i = 0
$key = "12345678"
$start_date = P1 ! 96="2-Sep-1992", 97="24-Jul-1993", 98="15-Jun-1994"
$OPEN/READ/SHARE=WRITE/ERROR=Oooops file MAIL.MAI
$loop:
$ i = i + 1
$ IF i.EQ.(i/100)*100 THEN WRITE sys$output i, " files. Last file ", file_name
$ file_name = f$search ( "MAIL$*.MAI" )
$ IF file_name .eqs. "" THEN GOTO done
$ id = F$PARSE(file_name,,,"NAME","SYNTAX_ONLY") - "MAIL$"
$ IF start_date .GTS. F$EXTRACT(14,2,id) THEN GOTO loop
$key[48,16]=%x'f$extract(12,4,id)
$key[16,32]=%x0005'f$extract(0,8,id)
$key[0,16]=0
$q = F$LOC("""",key) ! help read/key with quotes in key string a little
$if q.ne.8 then key = F$EXT(0,q,key) + "!" + F$EXT(q+1,8,key)
$READ/MATCH=GE/KEY=&key file rec
$bin_date = F$EXTRACT(0,8,rec)
$asc_date = F$FAO("!%D",f$cvui(32,32,f$fao("!AD",8,bin_date)))
$k1 = F$FAO("!XL", F$CVSI(16,32,rec))
$k2 = F$FAO("!XL", F$CVSI(48,16,rec))
$folder = F$EXTRACT(9,F$CVSI(0,8,F$EXTRACT(8,1,rec)),rec)
$IF F$EXTRACT(0,8,id).EQS.k1 THEN GOTO loop ! Close enough
$WRITE SYS$OUTPUT asc_date, " ", id, " ", k1, " ", k2, " ", folder
$GOTO loop
$
$Done:
$WRITE sys$output i, " files processed in total."
$CLOSE file
$EXIT
$
$Oooops:
$WRITE SYS$OUTPUT "Failed to open MAIL.MAI"
$EXIT
$!
$! Hope this helps, +--------------------------------------+
$! | All opinions expressed are mine, and |
$! Hein van den Heuvel, Digital | may not reflect those of my employer |
$! vanden...@eps.enet.dec.com +--------------------------------------+
----------------MAILCOUNT.C----------------
/* MAILCOUNT.C

Description: This program determines the location of a user's mail directory,
tabulates all MAIL$nnnnnnnnnnnnnnnn.MAI files found and correlates this
information with the files expected in MAIL.MAI. A summary report is output
at the end indicating if any extra files exist, or if any are missing. It
does a lot of work, so it can take a while to execute...

Environment: Works in the mail environment for the current username only.

Privileges required: none

Written: H. Brydon, December 1991

Disclaimer: Be kind to me - I'm a new C programmer. I know it looks like
Fortran.

Modifications:

*/
#include descrip
#include ctype
#include maildef
#include fscndef
#include <stdio.h>

long stat;
#define ckstat(x) if(((stat = x) & 7) != 1) SYS$EXIT(stat)
#define min(a,b) ((a) < (b) ? (a) : (b))
#define TRUE (1)
#define FALSE (0)
#define maxmsgs 5000 /***/

typedef struct _ItemList
{
short buffer_length;
short item_code;
void *buffer_address;
long *return_length_address;
} ItemList;

typedef struct _minfo /* Structure to hold message info */
{ char name[26]; /* Name of external message */
unsigned ptrfound : 1; /* Ptr to message identified */
unsigned msgfound : 1; /* Actual message file has been located */
} Minfo;

Minfo msgs[maxmsgs];
int msgctr = -1;
char mfds[255];
int mfdslen;

/*
add_msgid scans the Minfo data and adds a given message name if
not already there, or updates the information if previously entered
*/
unsigned add_msgid(char *msgid, unsigned pf, unsigned mf)
{
int i;
char *p;
if(msgid[0] == 0)
{
fprintf(stderr,
"\nMAILCOUNT-W: Attempt to enter null string\n");
}
if (++msgctr >= maxmsgs)
{
fprintf(stderr,
"\nMAILCOUNT-F: Number of messages exceeds maxmsgs(%d) - recompile required\n",
maxmsgs);
exit(2);
}
if(strlen(msgid) > sizeof msgs[msgctr].name)
{
fprintf(stderr,
"\nMAILCOUNT-W: Size of message name exceeds data field size\n");
fprintf(stderr, "Message file name: >%s<", msgid);
}

/* Strip the ".MAI" extension and anything after it... */
for(p=msgid; p<=msgid + sizeof msgs[msgctr].name; p++)
if(*p == ".") *p = 0;

strcpy(msgs[msgctr].name, msgid);
for(i=0; i<= msgctr; i++)
if(!strcmp(msgs[i].name, msgid))
{
msgs[i].ptrfound |= pf;
msgs[i].msgfound |= mf;
if (i == msgctr)
{
return 1;
}
else
{
msgctr--;
return 0;
}
}
}

int folder_routine(int *pfctx, struct dsc$descriptor *name)
{
static int folders = 0;
short rectype;
char subject[510], extid[255];
int subjlen, extid_len;
int mcontext =0;
ItemList
null_list[] = {{0,0,0,0}},
mslist[] = {
{0, MAIL$_MESSAGE_FOLDER, 0, 0},
{0, MAIL$_NOSIGNAL, 0, 0},
{0,0,0,0}},
mblist[] = {{4,MAIL$_MESSAGE_FILE_CTX,pfctx,0},
{0,0,0,0}},
milist[] = {{0,MAIL$_MESSAGE_NEXT,0,0},
{0,MAIL$_NOSIGNAL,0,0},
{0,0,0,0}},
molist[] = {{sizeof subject, MAIL$_MESSAGE_SUBJECT, subject, &subjlen},
{sizeof extid, MAIL$_MESSAGE_EXTID, extid, &extid_len},
{0,0,0,0}};

if (name->dsc$w_length)
{
ckstat(mail$message_begin(&mcontext, mblist, null_list));

mslist[0].buffer_length = name->dsc$w_length;
mslist[0].buffer_address = name->dsc$a_pointer;
if (mail$message_select(&mcontext, mslist, null_list) & 1)
{
printf("\nScanning folder %.*s...",
name->dsc$w_length, name->dsc$a_pointer);
++folders;

while (mail$message_info(&mcontext, milist, molist) & 1)
{
subject[subjlen] = 0;
extid[extid_len] = 0;
if(extid_len)
{
/* printf("\n Message %.*s found, subj=%.*s", /**/
/* extid_len, extid, min(subjlen, 50), subject); /**/
add_msgid(extid, TRUE, FALSE);
}
}
ckstat(mail$message_end(&mcontext, null_list, null_list));
}
}
else
{ /* no more folders, print out the total! */
printf("\n\n Total of %d folder%s processed\n",
folders,(folders == 1)?"":"s");
}
return 1;
}

/*
get_names_from_mail_mai collects the names of all valid external
MAIL$nnnnnnnnnnnnnnnn.MAI files from the user's mail.mai file.
*/
unsigned get_names_from_mail_mai()
{
int sts;
int mcontext=0;
int fcontext=0;
ItemList
null_list[] = {{0,0,0,0}},
mblist[] = {{4,MAIL$_MESSAGE_FILE_CTX,&fcontext,0}, {0,0,0,0}},
mflist[] = {{4,MAIL$_MAILFILE_FOLDER_ROUTINE,folder_routine,0},
{4,MAIL$_MAILFILE_USER_DATA,&fcontext,0},
{0,0,0,0}};

if (mail$mailfile_begin(&fcontext, null_list, null_list) & 1)
{
if (mail$mailfile_open(&fcontext, null_list, null_list) & 1)
{
ckstat(mail$mailfile_info_file(&fcontext, mflist, null_list));
mail$mailfile_close(&fcontext, null_list, null_list);
}
mail$mailfile_end(&fcontext, null_list, null_list);
}
printf(
"\n Total of %d message%s found following processing of MAIL.MAI file",
msgctr+1,(msgctr==0)?"":"s");
}


/*
get_names_from_dir collects the names of all existing external
MAIL$nnnnnnnnnnnnnnnn.MAI files from the user's mail [sub]directory.
*/
unsigned get_names_from_dir()
{
int i;
int ffcontext;
char *filext;
char rfs[200];
struct dsc$descriptor rfs_desc =
{sizeof rfs, DSC$K_DTYPE_T, DSC$K_CLASS_S, rfs};
struct dsc$descriptor dfs_desc =
{strlen(mfds), DSC$K_DTYPE_T, DSC$K_CLASS_S, mfds};
$DESCRIPTOR(filespec_desc, "*.MAI");

ffcontext = 0;
while(lib$find_file(&filespec_desc, &rfs_desc, &ffcontext, &dfs_desc, 0,
0, 0) & 1)
{
/*
rfs now has device, directory, name, extension and version info in it. We
need to locate the name.ext info only and pass to add_msgid.
*/
filext = &rfs[sizeof rfs];
for(i = 0; i <= sizeof rfs; i++)
if(rfs[i] == ';')
{
rfs[i] = 0;
filext = &rfs[i];
break;
}
while(filext > &rfs)
if( *--filext == ']')
{
filext++;
break;
}
add_msgid(filext, FALSE, TRUE);
}
printf(
"\n Total of %d message%s found following processing of mail directory",
msgctr+1,(msgctr==0)?"":"s");
}


/*
make_report outputs the list of all MAIL$nnnnnnnnnnnnnnnn.MAI files that
either exist but have no pointer referencing them or do not exist but a
dangling pointer assumes they are present.
*/
unsigned make_report()
{
int i;

for(i=0; i<= msgctr; i++)
{
if ((!msgs[i].ptrfound) && msgs[i].msgfound)
{
printf("\nNo mail file pointer exists for external file %s",
msgs[i].name);
}
else if ((msgs[i].ptrfound) && (!msgs[i].msgfound))
{
printf("\nPointer exists but no external file %s found",
msgs[i].name);
}
}
}


main (int argc, char *argv[])
{
int ucontext;
ItemList
null_list[] = {{0,0,0,0}},
info_list[] = {
{sizeof mfds, MAIL$_USER_FULL_DIRECTORY, &mfds, &mfdslen},
{0,0,0,0}};

ucontext = 0;
ckstat(mail$user_begin(&ucontext, null_list, info_list));
mfds[mfdslen] = 0;
printf("\n Mail files are in directory %.*s\n", mfdslen, mfds);

get_names_from_mail_mai();
get_names_from_dir();
make_report();
}

0 new messages