home *** CD-ROM | disk | FTP | other *** search
/ Aminet 18 / aminetcdnumber181997.iso / Aminet / comm / ums / SUMSTools.lha / UMS / Tools / SUMSTools / Source / sumsprint.c < prev    next >
C/C++ Source or Header  |  1997-01-09  |  23KB  |  565 lines

  1.  
  2. #include <utility/hooks.h>
  3.  
  4. #include "sumstl.h"
  5.  
  6. #include <proto/locale.h>
  7.  
  8. #include <stdio.h>
  9. #include <ctype.h>
  10.  
  11. #ifdef __SASC
  12. #include <dos.h>
  13. #endif
  14.  
  15. #include "umsfilter.h"
  16. #include "date.h"
  17.  
  18. /* SMAKE */
  19.  
  20.  
  21. struct MyHook   {
  22.     struct MinNode      h_MinNode;
  23.     ULONG               (*h_Entry)();   /* assembler entry point        */
  24.     ULONG               (*h_SubEntry)();/* often HLL entry point        */
  25.     char        *h_Data;        /* owner specific               */
  26. };
  27.  
  28.  
  29. // Version String
  30. // --------------
  31.  
  32. static char VersionString[] = "$VER: sumsprint "VERSION;
  33.  
  34. static char UsageString[] = "\
  35.      U=User       : user name.\n\
  36.      P=Password   : user's password.\n\
  37.     FI=Filter     : filter specification.\n\
  38.     FO=Format     : format string (see documentation for details).\n\
  39.   FILE=Formatfile : file that contains a format string.\n\
  40.      O=SetOldFlag : if existing, read messages become old.\n\
  41.      B=Backwards  : if existing, messages are scanned backwards.\n\
  42.      S=Server     : server name.\n\n\
  43. ";
  44.  
  45.  
  46. // Template
  47. // --------
  48.  
  49. 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";
  50. enum opts {
  51.         OPT_USER, OPT_PASSWORD, OPT_FILTER, OPT_FORMAT, OPT_FORMATFILE, OPT_SETOLDFLAG, OPT_BACKWARDS, OPT_SERVER,
  52.         OPT_COUNT};
  53. static LONG opts[OPT_COUNT];
  54.  
  55.  
  56. // Globals
  57. // -------
  58.  
  59. extern struct DosLibrary *DOSBase;
  60.  
  61. struct Library *UMSBase = NULL;
  62. struct Library *LocaleBase = NULL;
  63. struct Locale *Locale = NULL;
  64. UMSAccount acc = NULL;
  65. char *TextFields[UMSNUMFIELDS];
  66. struct MyMessageInfo
  67. {
  68.         LONG      msgi_HeaderLength; // 0  (offsets for keyword table)
  69.         LONG      msgi_TextLength;   // 1
  70.         LONG      msgi_Date;         // 2
  71.         UMSMsgNum msgi_ChainUp;      // 3
  72.         UMSMsgNum msgi_ChainDn;      // 4
  73.         UMSMsgNum msgi_ChainLt;      // 5
  74.         UMSMsgNum msgi_ChainRt;      // 6
  75.         UMSSet    msgi_GlobalStatus; // 7
  76.         UMSSet    msgi_UserStatus;   // 8
  77.         UMSSet    msgi_LoginStatus;  // 9
  78.         UMSMsgNum msgi_HardLink;     // 10
  79.         UMSMsgNum msgi_SoftLink;     // 11
  80.         LONG      msgi_MsgNum;       // 12
  81. } MessageInfo;
  82.  
  83.  
  84. #define KW_STRING 0
  85. #define KW_NUMBER 1
  86. #define KW_DATE   2
  87. #define KW_QTEXT  3
  88. #define KW_FLAG   4
  89.  
  90. struct Keyword
  91. {
  92.         char *name;
  93.         char *format;
  94.         LONG type;
  95.         LONG code;
  96. } Keywords[] =
  97. {
  98.         { "MsgText"      ,"%s",KW_STRING,UMSCODE_MsgText      },
  99.  
  100.         { "FromName"     ,"%s",KW_STRING,UMSCODE_FromName     },
  101.         { "FromAddr"     ,"%s",KW_STRING,UMSCODE_FromAddr     },
  102.         { "ToName"       ,"%s",KW_STRING,UMSCODE_ToName       },
  103.         { "ToAddr"       ,"%s",KW_STRING,UMSCODE_ToAddr       },
  104.         { "MsgID"        ,"%s",KW_STRING,UMSCODE_MsgID        },
  105.         { "CreationDate" ,"%s",KW_STRING,UMSCODE_CreationDate },
  106.         { "ReceiveDate"  ,"%s",KW_STRING,UMSCODE_ReceiveDate  },
  107.         { "ReferID"      ,"%s",KW_STRING,UMSCODE_ReferID      },
  108.         { "Group"        ,"%s",KW_STRING,UMSCODE_Group        },
  109.         { "Subject"      ,"%s",KW_STRING,UMSCODE_Subject      },
  110.         { "Attributes"   ,"%s",KW_STRING,UMSCODE_Attributes   },
  111.         { "Comments"     ,"%s",KW_STRING,UMSCODE_Comments     },
  112.         { "Organization" ,"%s",KW_STRING,UMSCODE_Organization },
  113.         { "Distribution" ,"%s",KW_STRING,UMSCODE_Distribution },
  114.         { "Folder"       ,"%s",KW_STRING,UMSCODE_Folder       },
  115.         { "FidoID"       ,"%s",KW_STRING,UMSCODE_FidoID       },
  116.         { "MausID"       ,"%s",KW_STRING,UMSCODE_MausID       },
  117.         { "ReplyGroup"   ,"%s",KW_STRING,UMSCODE_ReplyGroup   },
  118.         { "ReplyName"    ,"%s",KW_STRING,UMSCODE_ReplyName    },
  119.         { "ReplyAddr"    ,"%s",KW_STRING,UMSCODE_ReplyAddr    },
  120.         { "LogicalToName","%s",KW_STRING,UMSCODE_LogicalToName},
  121.         { "LogicalToAddr","%s",KW_STRING,UMSCODE_LogicalToAddr},
  122.         { "FileName"     ,"%s",KW_STRING,UMSCODE_FileName     },
  123.         { "RFCMsgNum"    ,"%s",KW_STRING,UMSCODE_RFCMsgNum    },
  124.  
  125.         { "FidoText"     ,"%s",KW_STRING,UMSCODE_FidoText     },
  126.         { "ErrorText"    ,"%s",KW_STRING,UMSCODE_ErrorText    },
  127.         { "Newsreader"   ,"%s",KW_STRING,UMSCODE_Newsreader   },
  128.  
  129.         { "RFCAttr"      ,"%s",KW_STRING,UMSCODE_RfcAttr      },
  130.         { "FTNAttr"      ,"%s",KW_STRING,UMSCODE_FtnAttr      },
  131.         { "ZerAttr"      ,"%s",KW_STRING,UMSCODE_ZerAttr      },
  132.         { "MausAttr"     ,"%s",KW_STRING,UMSCODE_MausAttr     },
  133.  
  134.         { "TempFileName" ,"%s",KW_STRING,UMSCODE_TempFileName },
  135.  
  136.         { "CDate","%d-%b-%y %X",KW_DATE,UMSCODE_CreationDate },
  137.         { "IDate","%d-%b-%y %X",KW_DATE,UMSCODE_ReceiveDate  },
  138.  
  139.         { "MsgNum"      ,"%ld"  ,KW_NUMBER,12 },
  140.         { "ChainUp"     ,"%ld"  ,KW_NUMBER, 3 },
  141.         { "ChainDown"   ,"%ld"  ,KW_NUMBER, 4 },
  142.         { "ChainLeft"   ,"%ld"  ,KW_NUMBER, 5 },
  143.         { "ChainRight"  ,"%ld"  ,KW_NUMBER, 6 },
  144.         { "HardLink"    ,"%ld"  ,KW_NUMBER,10 },
  145.         { "SoftLink"    ,"%ld"  ,KW_NUMBER,11 },
  146.  
  147.         { "GlobalStatus","%08lx",KW_FLAG, 7 },
  148.         { "UserStatus"  ,"%08lx",KW_FLAG, 8 },
  149.         { "LoginStatus" ,"%08lx",KW_FLAG, 9 },
  150.  
  151.         { "QuoteText","> ",KW_QTEXT,UMSCODE_MsgText },
  152.  
  153.         { NULL,0,0 }
  154. };
  155.  
  156. char *DefaultFormat = "\
  157. Group..: <Group>\n\
  158. From...: <FromName> (<FromAddr>)\n\
  159. To.....: <ToName> (<ToAddr>)\n\
  160. Subject: <Subject>\n\
  161. \n\
  162. <MsgText>\n\
  163. ";
  164.  
  165. static char filteradd[] = " AND readaccess=1 AND viewaccess=1";
  166.  
  167. #define FILTERADDSTR  filteradd
  168. #define NULLFILTERSTR (&filteradd[5])
  169. #define FILTERADDLEN  35
  170.  
  171.  
  172. // Functions
  173. // ---------
  174.  
  175. LONG PrintMessage(char *format);
  176.  
  177.  
  178. // CTRL-C Stuff
  179. // ------------
  180.  
  181. int brk(void)
  182. {
  183.         return(0);
  184. }
  185.  
  186. #define ABORTED (SetSignal(0,0) & SIGBREAKF_CTRL_C)
  187.  
  188.  
  189. // Main Function
  190. // -------------
  191.  
  192. int main(int argc,char *argv[])
  193. {
  194.         char *filter;
  195.         char *format = DefaultFormat;
  196.         char *language=NULL;
  197.         int erg = RETURN_ERROR, umserr;
  198.         int nr=0;
  199.         int oldtag = UMSTAG_RNoUpdate;
  200.         int direction = 1;
  201.         int fi;
  202.         struct RDArgs *args_ptr;
  203.  
  204.         onbreak(brk);
  205.  
  206.         if (argc<2 || *argv[1] == '?')
  207.         {
  208.                 fprintf(stderr,"\33[1m%s\33[0m, written by Stefan Stuntz, Public Domain.\n\nTemplate: %s\n%s",&VersionString[6],TemplateString,UsageString);
  209.         }
  210.  
  211.         {
  212.                 int i;
  213.  
  214.                 for (i=0; i<OPT_COUNT; i++)
  215.                 opts[i]=NULL;
  216.         }
  217.  
  218.         if (args_ptr = ReadArgs(TemplateString, opts, NULL))
  219.         {
  220.                 if (opts[OPT_FORMATFILE])
  221.                 {
  222.                         FILE *f;
  223.                         int len;
  224.                         if (f=fopen((char *)opts[OPT_FORMATFILE],"rb"))
  225.                         {
  226.                                 fseek(f,0,2);
  227.                                 len=ftell(f);
  228.                                 fseek(f,0,0);
  229.                                 if (!(len>0 && (format=calloc(1,len+1)) && fread(format,1,len,f)==len))
  230.                                         format = DefaultFormat;
  231.                                 fclose(f);
  232.                         }
  233.                         else
  234.                         {
  235.                                 fprintf(stderr,"\7Format file \"%s\" not found.\n",opts[OPT_FORMATFILE]);
  236.                                 FreeArgs(args_ptr);
  237.                                 return(20);
  238.                         }
  239.                 }
  240.                 else
  241.                         if (opts[OPT_FORMAT])
  242.                                 format = (char *)opts[OPT_FORMAT];
  243.  
  244.                 if (opts[OPT_SETOLDFLAG])
  245.                         oldtag    = TAG_IGNORE;
  246.  
  247.                 if (opts[OPT_BACKWARDS])
  248.                         direction = -1;
  249.  
  250.                 if (!strnicmp(format,"LANGUAGE: ",10))
  251.                 {
  252.                         language = format+10;
  253.                         if (!(format=strchr(language,'\n')))
  254.                         {
  255.                                 fprintf(stderr,"\7Invalid language spec in format file.");
  256.                                 FreeArgs(args_ptr);
  257.                                 return(20);
  258.                         }
  259.                         *format++=0;
  260.                 }
  261.  
  262.                 if (!(filter = malloc(strlen((char *)(opts[OPT_FILTER]))+FILTERADDLEN)))
  263.                 {
  264.                         fprintf(stderr,"\7Out of memory.\n");
  265.                         FreeArgs(args_ptr);
  266.                         return(20);
  267.                 }
  268.  
  269.                 if (opts[OPT_FILTER] && *(char *)opts[OPT_FILTER])
  270.                 {
  271.                         strcpy(filter,(char *)opts[OPT_FILTER]);
  272.                         strcat(filter,FILTERADDSTR);
  273.                 }
  274.                 else
  275.                 {
  276.                         strcpy(filter,NULLFILTERSTR);
  277.                 }
  278.  
  279.                 if (LocaleBase = OpenLibrary("locale.library",38))
  280.                         Locale = OpenLocale(language);
  281.  
  282.                 if (UMSBase = OpenLibrary(UMSNAME,UMSVERSION))
  283.                 {
  284.                         if (acc = UMSRLogin((char *)opts[OPT_SERVER],(char *)opts[OPT_USER],(char *)opts[OPT_PASSWORD]))
  285.                         {
  286.                                 if (!(fi = UmsFilterExpression(filter,acc,0,0,1)))
  287.                                 {
  288.                                         erg = RETURN_OK;
  289.                                         while (nr = UMSSearchTags(acc,
  290.                                                     UMSTAG_SearchLast     ,nr,
  291.                                                     UMSTAG_SearchLocal    ,TRUE,
  292.                                                     UMSTAG_SearchMask     ,1,
  293.                                                     UMSTAG_SearchMatch    ,1,
  294.                                                                         UMSTAG_SearchDirection,direction,
  295.                                                     TAG_DONE))
  296.                                         {
  297.                                                 if (ABORTED)
  298.                                                 {
  299.                                                         fprintf(stderr,"\7*** User break.\n");
  300.                                                         erg = RETURN_WARN;
  301.                                                         break;
  302.                                                 }
  303.  
  304.                                                 if (umserr=UMSReadMsgTags(acc,
  305.                                                     UMSTAG_RMsgNum    ,nr,
  306.                                                     UMSTAG_RMsgInfo   ,&MessageInfo,
  307.                                                     UMSTAG_RTextFields,TextFields,
  308.                                                     UMSTAG_RReadAll   ,TRUE,
  309.                                                     oldtag            ,TRUE,
  310.                                                     TAG_DONE))
  311.                                                 {
  312.                                                         if (!TextFields[UMSCODE_Group] || !*TextFields[UMSCODE_Group])
  313.                                                                 TextFields[UMSCODE_Group]="Netmail";
  314.                                                         MessageInfo.msgi_MsgNum = nr;
  315.                                                         if ( PrintMessage(format) ) {
  316.                                                                 erg = RETURN_WARN;
  317.                                                                 UMSFreeMsg(acc,nr);
  318.                                                                 break;
  319.                                                         }
  320.                                                         UMSFreeMsg(acc,nr);
  321.                                                 }
  322.                                                 else
  323.                                                 {
  324.                                                         fprintf(stderr,"UMS-Error %d: %s\n",UMSErrNum(acc),UMSErrTxt(acc));
  325.                                                         erg = RETURN_WARN;
  326.                                                         /* kludge for bad behavior of UMSSearchTags() */
  327.                                                         if ( umserr==UMSERR_ServerTerminated ) {
  328.                                                                 erg = RETURN_ERROR;
  329.                                                                 break;
  330.                                                         }
  331.                                                 }
  332.                                         }
  333.                                 }
  334.                                 else printf("\7Expression Error %ld\n",fi);
  335.  
  336.                                 UMSLogout(acc);
  337.                         }
  338.                         else fprintf(stderr,"\7UMS-Login failed.\n");
  339.  
  340.                         CloseLibrary(UMSBase);
  341.                 }
  342.                 else fprintf(stderr,"\7Could not open ums.library V10.\n");
  343.  
  344.                 if (LocaleBase)
  345.                 {
  346.                         if (Locale) CloseLocale(Locale);
  347.                         CloseLibrary(LocaleBase);
  348.                 }
  349.  
  350.                 FreeArgs(args_ptr);
  351.         }
  352.         else
  353.         {
  354.                 PrintFault(IoErr(), NULL);
  355.                 return(RETURN_ERROR);
  356.         }
  357.  
  358.         return(erg);
  359. }
  360.  
  361.  
  362. struct Keyword *FindKeyword(char *name)
  363. {
  364.         struct Keyword *k;
  365.  
  366.         for (k=Keywords;k->name;k++)
  367.         {
  368.                 if (!stricmp(name,k->name)) return(k);
  369.         }
  370.         return(NULL);
  371. }
  372.  
  373.  
  374. #ifdef _DCC
  375. VOID DatePutCharFunc(__A0 struct MyHook *h, __A1 UBYTE c, __A2 struct Locale *loc)
  376. {
  377.         *h->h_Data++=c;
  378. }
  379. #else
  380. VOID __asm DatePutCharFunc(register __a0 struct MyHook *h,register __a1 UBYTE c,register __a2 struct Locale *loc)
  381. {
  382.         *h->h_Data++ = c;
  383. }
  384. #endif
  385.  
  386.  
  387. LONG PrintMessage(char *format)
  388. {
  389.         static char buf[50];
  390.         char *c = format;
  391.         char *ob,*cb,*fmt;
  392.         int len;
  393.         struct Keyword *k;
  394.  
  395.         while (*c)
  396.         {
  397.                 if (*c=='<')
  398.                 {
  399.                         ob=c;
  400.                         if (!(cb=strchr(ob+1,'>'))) break;
  401.                         c=cb+1;
  402.                         if ((len=cb-ob-1)>49) break;
  403.                         strncpy(buf,ob+1,len); buf[len]=0;
  404.                         if (fmt=strchr(buf,',')) *fmt++=0;
  405.                         if (k=FindKeyword(buf))
  406.                         {
  407.                                 if (!fmt) fmt=k->format;
  408.                                 if (k->type==KW_STRING)
  409.                                 {
  410.                                         printf(fmt,TextFields[k->code] ? TextFields[k->code] : "");
  411.                                 }
  412.                                 else if (k->type==KW_NUMBER)
  413.                                 {
  414.                                         printf(fmt,((LONG *)&MessageInfo)[k->code]);
  415.                                 }
  416.                                 else if (k->type==KW_FLAG)
  417.                                 {
  418.                                         if ( *fmt!='%' )
  419.                                         {
  420.                                                 char    *scan,*cfstart=fmt,output[34],*pptr;
  421.                                                 ULONG   p,flags=((LONG *)&MessageInfo)[k->code];
  422.  
  423.                                                 if ( pptr=strchr(fmt,'%') )
  424.                                                 {
  425.                                                         scan=pptr-1;
  426.                                                         fmt=pptr;
  427.                                                 }
  428.                                                 else
  429.                                                 {
  430.                                                         scan=fmt+strlen(fmt)-1;
  431.                                                         fmt="%s";
  432.                                                 }
  433.  
  434.                                                 pptr=output;
  435.                                                 p=1;
  436.                                                 while ( scan>=cfstart )
  437.                                                 {
  438.                                                         if ( *scan!='-' )
  439.                                                         {
  440.                                                                 if ( flags&p )
  441.                                                                 {
  442.                                                                         *pptr++=toupper(*scan);
  443.                                                                 }
  444.                                                                 else
  445.                                                                 {
  446.                                                                         if ( isupper(*scan) )
  447.                                                                                 *pptr++='-';
  448.                                                                 }
  449.                                                         }
  450.                                                         scan--;
  451.                                                         p<<=1;
  452.                                                 }
  453.                                                 *pptr='\0';
  454.                                                 printf(fmt,output);
  455.                                         }
  456.                                         else
  457.                                         {
  458.                                                 printf(fmt,((LONG *)&MessageInfo)[k->code]);
  459.                                         }
  460.                                 }
  461.                                 else if (k->type==KW_DATE && Locale)
  462.                                 {
  463.                                         LONG secs;
  464.                                         char *dstr = TextFields[UMSCODE_CreationDate] ? TextFields[UMSCODE_CreationDate] : "";
  465.  
  466.                                         if (k->code == UMSCODE_CreationDate)
  467.                                         {
  468.                                                 secs = DateToSeconds(dstr);
  469.                                         }
  470.                                         else
  471.                                         {
  472.                                                 if (!(secs = MessageInfo.msgi_Date)) secs=1;
  473.                                         }
  474.  
  475.                                         if (secs)
  476.                                         {
  477.                                                 struct DateStamp ds;
  478.                                                 static char buf[256];
  479.                                                 struct MyHook hook = {{0,0},(APTR)DatePutCharFunc,NULL,buf };
  480.  
  481.                                                 ds.ds_Days   = secs/(24*60*60);
  482.                                                 ds.ds_Minute = (secs%(24*60*60))/60;
  483.                                                 ds.ds_Tick   = (secs%60)*50;
  484.  
  485.                                                 FormatDate(Locale,fmt,&ds,&hook);
  486.                                                 printf("%s",buf);
  487.                                         }
  488.                                         else
  489.                                                 printf("%s",dstr);
  490.                                 }
  491.                                 else if (k->type==KW_QTEXT)
  492.                                 {
  493.                                         char *str = TextFields[k->code] ? TextFields[k->code] : "";
  494.                                         int pos=0,npos;
  495.  
  496.                                         while (*str)
  497.                                         {
  498.                                                 if (pos==0) printf("%s",fmt);
  499.  
  500.                                                 switch (*str)
  501.                                                 {
  502.                                                         case '\r':      putchar('\n');
  503.                                                                                         pos=0;
  504.                                                                                         if (*++str=='\n') str++;
  505.                                                                                         break;
  506.  
  507.                                                         case '\n':      putchar('\n');
  508.                                                                                         pos=0;
  509.                                                                                         if (*++str=='\r') str++;
  510.                                                                                         break;
  511.  
  512.                                                         case '\t':  npos = pos + 8 - (pos%8);
  513.                                                                                         while (pos!=npos) { putchar(' '); pos++; }
  514.                                                                                         str++;
  515.                                                                                         if (++pos>79) { putchar('\n'); pos=0; }
  516.                                                                                         break;
  517.  
  518.                                                         default:                putchar(*str);
  519.                                                                                         str++;
  520.                                                                                         if (++pos>79) { putchar('\n'); pos=0; }
  521.                                                                                         break;
  522.                                                 }
  523.                                         }
  524.                                 }
  525.                         }
  526.                         else
  527.                                 fprintf(stderr,"\7Unknown Keyword: %s\n",buf);
  528.                 }
  529.                 else if (*c=='\\')
  530.                 {
  531.                         if (!(*++c)) break;
  532.                         switch (*c)
  533.                         {
  534.                                 case '\^': putchar('^');  break;
  535.                                 case '\\': putchar('\\'); break;
  536.                                 case 'n' : putchar('\n'); break;
  537.                                 case 'r' : putchar('\r'); break;
  538.                                 case 't' : putchar('\t'); break;
  539.                                 case 'f' : putchar('\f'); break;
  540.                                 case '<' : putchar('<');  break;
  541.                                 case '>' : putchar('>');  break;
  542.                                 case 'e' : putchar(27);   break;
  543.                                 default  : putchar(*c);   break;
  544.                         }
  545.                         c++;
  546.                 }
  547.                 else if (*c=='^')
  548.                 {
  549.                         if (!(*++c)) break;
  550.                         putchar(*c & (~64));
  551.                         c++;
  552.                 }
  553.                 else
  554.                 {
  555.                         putchar(*c);
  556.                         c++;
  557.                 }
  558.                 if ( ABORTED ) {
  559.                         puts("\n*** User break");
  560.                         return 5;
  561.                 }
  562.         }
  563.         return 0;
  564. }
  565.