home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Meeting Pearls 3
/
Meeting_Pearls_III.iso
/
Pearls
/
comm
/
Mail+News
/
UMS11
/
Tools
/
SUMSTools
/
Source
/
sumsprint.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-08-03
|
13KB
|
562 lines
#include <utility/hooks.h>
#include "sumstl.h"
#include <proto/locale.h>
#include <stdio.h>
#include <ctype.h>
#ifdef __SASC
#include <dos.h>
#endif
#include "umsfilter.h"
#include "date.h"
/* SMAKE */
struct MyHook {
struct MinNode h_MinNode;
ULONG (*h_Entry)(); /* assembler entry point */
ULONG (*h_SubEntry)();/* often HLL entry point */
char *h_Data; /* owner specific */
};
// Version String
// --------------
static char VersionString[] = "$VER: sumsprint "VERSION;
static char UsageString[] = "\
U=User : user name.\n\
P=Password : user's password.\n\
FI=Filter : filter specification.\n\
FO=Format : format string (see documentation for details).\n\
FILE=Formatfile : file that contains a format string.\n\
O=SetOldFlag : if existing, read messages become old.\n\
B=Backwards : if existing, messages are scanned backwards.\n\
S=Server : server name.\n\n\
";
// Template
// --------
static char *TemplateString = "U=User=Name/A,P=Password/A,FI=Filter/A,FO=Format,FILE=Formatfile/K,O=SetOldFlag/S,B=Backwards/S,S=Server/K";
enum opts {
OPT_USER, OPT_PASSWORD, OPT_FILTER, OPT_FORMAT, OPT_FORMATFILE, OPT_SETOLDFLAG, OPT_BACKWARDS, OPT_SERVER,
OPT_COUNT};
static LONG opts[OPT_COUNT];
// Globals
// -------
extern struct DosLibrary *DOSBase;
struct Library *UMSBase = NULL;
struct Library *LocaleBase = NULL;
struct Locale *Locale = NULL;
UMSAccount acc = NULL;
char *TextFields[UMSNUMFIELDS];
struct MyMessageInfo
{
LONG msgi_HeaderLength; // 0 (offsets for keyword table)
LONG msgi_TextLength; // 1
LONG msgi_Date; // 2
UMSMsgNum msgi_ChainUp; // 3
UMSMsgNum msgi_ChainDn; // 4
UMSMsgNum msgi_ChainLt; // 5
UMSMsgNum msgi_ChainRt; // 6
UMSSet msgi_GlobalStatus; // 7
UMSSet msgi_UserStatus; // 8
UMSSet msgi_LoginStatus; // 9
UMSMsgNum msgi_HardLink; // 10
UMSMsgNum msgi_SoftLink; // 11
LONG msgi_MsgNum; // 12
} MessageInfo;
#define KW_STRING 0
#define KW_NUMBER 1
#define KW_DATE 2
#define KW_QTEXT 3
#define KW_FLAG 4
struct Keyword
{
char *name;
char *format;
LONG type;
LONG code;
} Keywords[] =
{
{ "MsgText" ,"%s",KW_STRING,UMSCODE_MsgText },
{ "FromName" ,"%s",KW_STRING,UMSCODE_FromName },
{ "FromAddr" ,"%s",KW_STRING,UMSCODE_FromAddr },
{ "ToName" ,"%s",KW_STRING,UMSCODE_ToName },
{ "ToAddr" ,"%s",KW_STRING,UMSCODE_ToAddr },
{ "MsgID" ,"%s",KW_STRING,UMSCODE_MsgID },
{ "CreationDate" ,"%s",KW_STRING,UMSCODE_CreationDate },
{ "ReceiveDate" ,"%s",KW_STRING,UMSCODE_ReceiveDate },
{ "ReferID" ,"%s",KW_STRING,UMSCODE_ReferID },
{ "Group" ,"%s",KW_STRING,UMSCODE_Group },
{ "Subject" ,"%s",KW_STRING,UMSCODE_Subject },
{ "Attributes" ,"%s",KW_STRING,UMSCODE_Attributes },
{ "Comments" ,"%s",KW_STRING,UMSCODE_Comments },
{ "Organization" ,"%s",KW_STRING,UMSCODE_Organization },
{ "Distribution" ,"%s",KW_STRING,UMSCODE_Distribution },
{ "Folder" ,"%s",KW_STRING,UMSCODE_Folder },
{ "FidoID" ,"%s",KW_STRING,UMSCODE_FidoID },
{ "MausID" ,"%s",KW_STRING,UMSCODE_MausID },
{ "ReplyGroup" ,"%s",KW_STRING,UMSCODE_ReplyGroup },
{ "ReplyName" ,"%s",KW_STRING,UMSCODE_ReplyName },
{ "ReplyAddr" ,"%s",KW_STRING,UMSCODE_ReplyAddr },
{ "LogicalToName","%s",KW_STRING,UMSCODE_LogicalToName},
{ "LogicalToAddr","%s",KW_STRING,UMSCODE_LogicalToAddr},
{ "RFCMsgNum" ,"%s",KW_STRING,UMSCODE_RFCMsgNum },
{ "FidoText" ,"%s",KW_STRING,UMSCODE_FidoText },
{ "ErrorText" ,"%s",KW_STRING,UMSCODE_ErrorText },
{ "Newsreader" ,"%s",KW_STRING,UMSCODE_Newsreader },
{ "RFCAttr" ,"%s",KW_STRING,UMSCODE_RfcAttr },
{ "FTNAttr" ,"%s",KW_STRING,UMSCODE_FtnAttr },
{ "ZerAttr" ,"%s",KW_STRING,UMSCODE_ZerAttr },
{ "MausAttr" ,"%s",KW_STRING,UMSCODE_MausAttr },
{ "CDate","%d-%b-%y %X",KW_DATE,UMSCODE_CreationDate },
{ "IDate","%d-%b-%y %X",KW_DATE,UMSCODE_ReceiveDate },
{ "MsgNum" ,"%ld" ,KW_NUMBER,12 },
{ "ChainUp" ,"%ld" ,KW_NUMBER, 3 },
{ "ChainDown" ,"%ld" ,KW_NUMBER, 4 },
{ "ChainLeft" ,"%ld" ,KW_NUMBER, 5 },
{ "ChainRight" ,"%ld" ,KW_NUMBER, 6 },
{ "HardLink" ,"%ld" ,KW_NUMBER,10 },
{ "SoftLink" ,"%ld" ,KW_NUMBER,11 },
{ "GlobalStatus","%08lx",KW_FLAG, 7 },
{ "UserStatus" ,"%08lx",KW_FLAG, 8 },
{ "LoginStatus" ,"%08lx",KW_FLAG, 9 },
{ "QuoteText","> ",KW_QTEXT,UMSCODE_MsgText },
{ NULL,0,0 }
};
char *DefaultFormat = "\
Group..: <Group>\n\
From...: <FromName> (<FromAddr>)\n\
To.....: <ToName> (<ToAddr>)\n\
Subject: <Subject>\n\
\n\
<MsgText>\n\
";
static char filteradd[] = " AND readaccess=1 AND viewaccess=1";
#define FILTERADDSTR filteradd
#define NULLFILTERSTR (&filteradd[5])
#define FILTERADDLEN 35
// Functions
// ---------
LONG PrintMessage(char *format);
// CTRL-C Stuff
// ------------
int brk(void)
{
return(0);
}
#define ABORTED (SetSignal(0,0) & SIGBREAKF_CTRL_C)
// Main Function
// -------------
int main(int argc,char *argv[])
{
char *filter;
char *format = DefaultFormat;
char *language=NULL;
int erg = RETURN_ERROR, umserr;
int nr=0;
int oldtag = UMSTAG_RNoUpdate;
int direction = 1;
int fi;
struct RDArgs *args_ptr;
onbreak(brk);
if (argc<2 || *argv[1] == '?')
{
fprintf(stderr,"\33[1m%s\33[0m, written by Stefan Stuntz, Public Domain.\n\nTemplate: %s\n%s",&VersionString[6],TemplateString,UsageString);
}
{
int i;
for (i=0; i<OPT_COUNT; i++)
opts[i]=NULL;
}
if (args_ptr = ReadArgs(TemplateString, opts, NULL))
{
if (opts[OPT_FORMATFILE])
{
FILE *f;
int len;
if (f=fopen((char *)opts[OPT_FORMATFILE],"rb"))
{
fseek(f,0,2);
len=ftell(f);
fseek(f,0,0);
if (!(len>0 && (format=calloc(1,len+1)) && fread(format,1,len,f)==len))
format = DefaultFormat;
fclose(f);
}
else
{
fprintf(stderr,"\7Format file \"%s\" not found.\n",opts[OPT_FORMATFILE]);
FreeArgs(args_ptr);
return(20);
}
}
else
if (opts[OPT_FORMAT])
format = (char *)opts[OPT_FORMAT];
if (opts[OPT_SETOLDFLAG])
oldtag = TAG_IGNORE;
if (opts[OPT_BACKWARDS])
direction = -1;
if (!strnicmp(format,"LANGUAGE: ",10))
{
language = format+10;
if (!(format=strchr(language,'\n')))
{
fprintf(stderr,"\7Invalid language spec in format file.");
FreeArgs(args_ptr);
return(20);
}
*format++=0;
}
if (!(filter = malloc(strlen((char *)(opts[OPT_FILTER]))+FILTERADDLEN)))
{
fprintf(stderr,"\7Out of memory.\n");
FreeArgs(args_ptr);
return(20);
}
if (opts[OPT_FILTER] && *(char *)opts[OPT_FILTER])
{
strcpy(filter,(char *)opts[OPT_FILTER]);
strcat(filter,FILTERADDSTR);
}
else
{
strcpy(filter,NULLFILTERSTR);
}
if (LocaleBase = OpenLibrary("locale.library",38))
Locale = OpenLocale(language);
if (UMSBase = OpenLibrary(UMSNAME,UMSVERSION))
{
if (acc = UMSRLogin((char *)opts[OPT_SERVER],(char *)opts[OPT_USER],(char *)opts[OPT_PASSWORD]))
{
if (!(fi = UmsFilterExpression(filter,acc,0,0,1)))
{
erg = RETURN_OK;
while (nr = UMSSearchTags(acc,
UMSTAG_SearchLast ,nr,
UMSTAG_SearchLocal ,TRUE,
UMSTAG_SearchMask ,1,
UMSTAG_SearchMatch ,1,
UMSTAG_SearchDirection,direction,
TAG_DONE))
{
if (ABORTED)
{
fprintf(stderr,"\7*** User break.\n");
erg = RETURN_WARN;
break;
}
if (umserr=UMSReadMsgTags(acc,
UMSTAG_RMsgNum ,nr,
UMSTAG_RMsgInfo ,&MessageInfo,
UMSTAG_RTextFields,TextFields,
UMSTAG_RReadAll ,TRUE,
oldtag ,TRUE,
TAG_DONE))
{
if (!TextFields[UMSCODE_Group] || !*TextFields[UMSCODE_Group])
TextFields[UMSCODE_Group]="Netmail";
MessageInfo.msgi_MsgNum = nr;
if ( PrintMessage(format) ) {
erg = RETURN_WARN;
UMSFreeMsg(acc,nr);
break;
}
UMSFreeMsg(acc,nr);
}
else
{
fprintf(stderr,"UMS-Error %d: %s\n",UMSErrNum(acc),UMSErrTxt(acc));
erg = RETURN_WARN;
/* kludge for bad behavior of UMSSearchTags() */
if ( umserr==UMSERR_ServerTerminated ) {
erg = RETURN_ERROR;
break;
}
}
}
}
else printf("\7Expression Error %ld\n",fi);
UMSLogout(acc);
}
else fprintf(stderr,"\7UMS-Login failed.\n");
CloseLibrary(UMSBase);
}
else fprintf(stderr,"\7Could not open ums.library V10.\n");
if (LocaleBase)
{
if (Locale) CloseLocale(Locale);
CloseLibrary(LocaleBase);
}
FreeArgs(args_ptr);
}
else
{
PrintFault(IoErr(), NULL);
return(RETURN_ERROR);
}
return(erg);
}
struct Keyword *FindKeyword(char *name)
{
struct Keyword *k;
for (k=Keywords;k->name;k++)
{
if (!stricmp(name,k->name)) return(k);
}
return(NULL);
}
#ifdef _DCC
VOID DatePutCharFunc(__A0 struct MyHook *h, __A1 UBYTE c, __A2 struct Locale *loc)
{
*h->h_Data++=c;
}
#else
VOID __asm DatePutCharFunc(register __a0 struct MyHook *h,register __a1 UBYTE c,register __a2 struct Locale *loc)
{
*h->h_Data++ = c;
}
#endif
LONG PrintMessage(char *format)
{
static char buf[50];
char *c = format;
char *ob,*cb,*fmt;
int len;
struct Keyword *k;
while (*c)
{
if (*c=='<')
{
ob=c;
if (!(cb=strchr(ob+1,'>'))) break;
c=cb+1;
if ((len=cb-ob-1)>49) break;
strncpy(buf,ob+1,len); buf[len]=0;
if (fmt=strchr(buf,',')) *fmt++=0;
if (k=FindKeyword(buf))
{
if (!fmt) fmt=k->format;
if (k->type==KW_STRING)
{
printf(fmt,TextFields[k->code] ? TextFields[k->code] : "");
}
else if (k->type==KW_NUMBER)
{
printf(fmt,((LONG *)&MessageInfo)[k->code]);
}
else if (k->type==KW_FLAG)
{
if ( *fmt!='%' )
{
char *scan,*cfstart=fmt,output[34],*pptr;
ULONG p,flags=((LONG *)&MessageInfo)[k->code];
if ( pptr=strchr(fmt,'%') )
{
scan=pptr-1;
fmt=pptr;
}
else
{
scan=fmt+strlen(fmt)-1;
fmt="%s";
}
pptr=output;
p=1;
while ( scan>=cfstart )
{
if ( *scan!='-' )
{
if ( flags&p )
{
*pptr++=toupper(*scan);
}
else
{
if ( isupper(*scan) )
*pptr++='-';
}
}
scan--;
p<<=1;
}
*pptr='\0';
printf(fmt,output);
}
else
{
printf(fmt,((LONG *)&MessageInfo)[k->code]);
}
}
else if (k->type==KW_DATE && Locale)
{
LONG secs;
char *dstr = TextFields[UMSCODE_CreationDate] ? TextFields[UMSCODE_CreationDate] : "";
if (k->code == UMSCODE_CreationDate)
{
secs = DateToSeconds(dstr);
}
else
{
if (!(secs = MessageInfo.msgi_Date)) secs=1;
}
if (secs)
{
struct DateStamp ds;
static char buf[256];
struct MyHook hook = {{0,0},(APTR)DatePutCharFunc,NULL,buf };
ds.ds_Days = secs/(24*60*60);
ds.ds_Minute = (secs%(24*60*60))/60;
ds.ds_Tick = (secs%60)*50;
FormatDate(Locale,fmt,&ds,&hook);
printf("%s",buf);
}
else
printf("%s",dstr);
}
else if (k->type==KW_QTEXT)
{
char *str = TextFields[k->code] ? TextFields[k->code] : "";
int pos=0,npos;
while (*str)
{
if (pos==0) printf("%s",fmt);
switch (*str)
{
case '\r': putchar('\n');
pos=0;
if (*++str=='\n') str++;
break;
case '\n': putchar('\n');
pos=0;
if (*++str=='\r') str++;
break;
case '\t': npos = pos + 8 - (pos%8);
while (pos!=npos) { putchar(' '); pos++; }
str++;
if (++pos>79) { putchar('\n'); pos=0; }
break;
default: putchar(*str);
str++;
if (++pos>79) { putchar('\n'); pos=0; }
break;
}
}
}
}
else
fprintf(stderr,"\7Unknown Keyword: %s\n",buf);
}
else if (*c=='\\')
{
if (!(*++c)) break;
switch (*c)
{
case '\^': putchar('^'); break;
case '\\': putchar('\\'); break;
case 'n' : putchar('\n'); break;
case 'r' : putchar('\r'); break;
case 't' : putchar('\t'); break;
case 'f' : putchar('\f'); break;
case '<' : putchar('<'); break;
case '>' : putchar('>'); break;
case 'e' : putchar(27); break;
default : putchar(*c); break;
}
c++;
}
else if (*c=='^')
{
if (!(*++c)) break;
putchar(*c & (~64));
c++;
}
else
{
putchar(*c);
c++;
}
if ( ABORTED ) {
puts("\n*** User break");
return 5;
}
}
return 0;
}