home *** CD-ROM | disk | FTP | other *** search
/ back2roots/padua / padua.7z / padua / uucp / sendbatches.lzh / src / sendbatches.c < prev   
Encoding:
C/C++ Source or Header  |  1991-12-14  |  10.4 KB  |  393 lines

  1. #include <stddef.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <time.h>
  6. #include <dos.h>
  7. #include <exec/types.h>
  8. #include <exec/nodes.h>
  9. #include <clib/exec_protos.h>
  10. #include <clib/dos_protos.h>
  11. #include <pragmas/exec_pragmas.h>
  12. #include <pragmas/dos_pragmas.h>
  13.  
  14. /*
  15.  *    Sendbatches - a program to batch news to other sites.
  16.  *
  17.  *    Version 1.0
  18.  *    ⌐ by Walter Mildenberger in 1991. All rights reserved.
  19.  * 
  20.  *    I have tried to be as far as close to the <real, unix-> sendbatches
  21.  *    as I could. Processing of sendbatches is determined by a "batchparms"-
  22.  *    file compatible to the unix-format. Most of the actual programs are
  23.  *    AmigaOS-scripts.
  24.  *
  25.  *    This program is provided "as is", no promises are made for the fitness
  26.  *    of this program. The programer is not responsible for any damage that
  27.  *    might or might not be caused by this program. Use it on your OWN risk!
  28.  *
  29.  *    Distribution:
  30.  * this program is NOT put in the public domain, but you can freely
  31.  *    (re-)distribute it as long as you follow the following terms:
  32.  *        o    no fee is charged except small donations for copying and redistri-
  33.  *            buting (like postage). Everything above $US 7 or DM10 is not small.
  34.  *        o    You are only allowed to copy and redistribute the programs, as long
  35.  *            as you keep ALL sources, scripts, and configuration-files together.
  36.  *            You are allowed to drop the binaries, if you have to, but remember:
  37.  *            not everybody has the right compiler or memory to compile the stuff.
  38.  *        o    You SHOULD send <only to> ME any changes you made, but if you HAVE TO
  39.  *            redistribute modified sources, YOU MUST NOT remove or alter this
  40.  *            copyright-header! (well, you are allowed to fix spelling-errors :-) )
  41.  *
  42.  * Please send any enhancements, suggestions, bug-reports etc.pp. to the
  43.  *    following address:    wasp@chumly.ka.sub.org
  44.  *
  45.  */
  46.  
  47. /* define it correct for your actual News-System (use -d<value> on command */
  48. /* line instead) */
  49.  
  50. /* #define CNEWS */
  51. /* #define AUCPP */
  52. /* #define DUUCP */
  53.  
  54. #define TRANSMISSION_GRADE    "N"
  55. /* which transmission-grade get uux'ed batches ? Dillon's uux defaults to "N" */
  56.  
  57. /*
  58.  * The names of the batch-file vary widely from News-System to News-System:
  59.  * in CNews, this is "NewsArts:out.going/<systemname>/togo", while in
  60.  * //\\migaUUCP+ it is "UUNEWS:<systemname>.nbatch", and in Dillon's UUCP
  61.  * it is "UUSPOOL:Batch/<systemname>.
  62.  *
  63.  * the actual batch-file is determinated by concatenating the strings
  64.  * OUT_GOING <systemname> BATCHFILE .
  65.  *
  66. */
  67.  
  68. #if defined(CNEWS)
  69.  
  70. # define OUT_GOING    "NewsArts:out.going/"
  71. # define BATCH_FILE    "/togo"
  72. # define BATCHPARMS_FILENAME    "NewsCtl:batch/batchparms"
  73.  
  74. #elif defined(AUCPP)
  75.  
  76. # define OUT_GOING    "UUNEWS:"
  77. # define BATCH_FILE    ".nbatch"
  78. # define BATCHPARMS_FILENAME    "UULIB:news/batchparms"
  79.  
  80. #elif defined(DUUCP)
  81.  
  82. # define OUT_GOING    "UUSPOOL:Batch/"
  83. # define BATCH_FILE    ""
  84. # define BATCHPARMS_FILENAME    "UULIB:batchparms"
  85.  
  86. # else
  87. # ERROR_NO_NEWS_SYSTEM_SPECIFIED
  88. #endif
  89.  
  90. #define LOCKSTRING    "sendbatches"
  91.  
  92. #define DEFAULT    "/default/"
  93. #define WHITESPACE    " \t\n"
  94.  
  95. #define MAX_LINKS    128
  96. /*
  97.  * I rather doubt someone using this program has  really 128+ links, but
  98.  * who can know it exactly ?
  99.  *
  100.  */
  101. char *SystemName[MAX_LINKS];
  102.  
  103. #define SN_POOLSIZE    (MAX_LINKS << 5)
  104. char *sn_pool = NULL;
  105.  
  106. extern struct Library *SysBase, *DOSBase;
  107.  
  108. /* The file locking functions are taken from Matt Dillon's AmigaUUCP V1.06D, */
  109. /* copyright by Matt Dillon. */
  110. typedef struct List LIST;
  111. typedef struct Node NODE;
  112.  
  113. typedef struct {
  114.     NODE        Node;
  115.     FILE        *Fi;
  116.     short    Refs;
  117. } LNode;
  118.  
  119.  
  120. LIST LockList = { (NODE *)&LockList.lh_Tail, NULL, (NODE *)&LockList.lh_Head };
  121.  
  122. void __regargs    myerror(char *msg, int errorlevel);
  123. void                main(long argc, char *argv[]);
  124. void __regargs    DoBatch(char *name);
  125. void __regargs    DoRealBatch(char *name);
  126.  
  127. void __regargs LockFile(char *file);
  128. void __regargs UnLockFile( char *file);
  129. void __regargs    FreeLockNode(LNode *node);
  130. void                UnLockFiles(void);
  131.  
  132. void __regargs    myerror(char *msg, int errorlevel)
  133. {    fputs(msg,stderr);
  134.     fflush(stderr);
  135.     if(errorlevel > 5)
  136.     {    if(sn_pool)
  137.             free(sn_pool);
  138.         exit(errorlevel);
  139.     }
  140.     return;
  141. }
  142.  
  143. void main(argc,argv)
  144. LONG argc;
  145. char *argv[];
  146. {    char *pathname;
  147.     int i;
  148.     if(!argc)
  149.         myerror("can't run from Workbench, try again from cli\n",20);
  150.     pathname = getcwd(NULL,256);    /* directory */
  151.     if(!pathname)
  152.         myerror("can't get cd !\n",20);
  153.     for( i = 1; i < argc; i++)
  154.     {    if(*argv[i] != '?')
  155.             SystemName[i-1] = argv[i];
  156.         else
  157.             myerror(    "USAGE: sendbatches [<systems to be batched>]\n"
  158.                         "⌐ by Walter Mildenberger in 1991, all rights reserved\n",20);
  159.     }
  160.     if(!SystemName[0])    /* No parameter given -> get the site-names from the */
  161.     {    chdir(OUT_GOING);
  162.         sn_pool = malloc(SN_POOLSIZE);            
  163. #if defined (CNEWS) 
  164.         if(i = getfnl("#?",sn_pool,SN_POOLSIZE,1))
  165.         {
  166. #elif defined (DUUCP)
  167.         if(i = getfnl("#?",sn_pool,SN_POOLSIZE,0))
  168.         {
  169. #elif defined(AUCPP)
  170.         if(i = getfnl("#?" BATCH_FILE,sn_pool,SN_POOLSIZE,0))
  171.         {
  172. #endif
  173.             if(strbpl(SystemName,MAX_LINKS,sn_pool) != i)
  174.                 myerror("to much out.going-systems, program needs recompiling "
  175.                             "(or use system-list as parameter)!\n",20);
  176.         }
  177.     }
  178. #ifdef AUCPP
  179.     for(i=0; SystemName[i]; i++)    /* <system>.nbatch -> <system> ! */
  180.         if(ptr = strchr(SystemName[i],'.'))
  181.             *ptr = 0;
  182. #endif
  183.     if(!SystemName[0])
  184.         myerror("don't know any system to batch to !\n",20);
  185.     LockFile(LOCKSTRING);
  186. #ifdef CNEWS
  187.     chdir("NewsArts:");
  188. #else
  189.     chdir("UUNEWS:");
  190. #endif
  191.     for(i = 0; SystemName[i] ; i++)
  192.         DoBatch(SystemName[i]);
  193.     UnLockFile(LOCKSTRING);
  194.     if(sn_pool)
  195.         free(sn_pool);
  196.     chdir(pathname);
  197.     free(pathname);
  198. }
  199.  
  200. struct
  201. {    long size,
  202.         limit;
  203.     char batcher[256],
  204.         muncher[256],
  205.         sender[256];
  206. }BatchParms;
  207.  
  208. char workfile[256], tmpfile1[256],tmpfile2[256];
  209. char Buf[1024];
  210.  
  211. void __regargs    DoBatch(char *name)
  212. {    long anzahl;
  213.     BOOL found = FALSE;
  214.     char *ptr;
  215.     FILE *bpf;        /* b)atchp)arms f)ile */
  216.     setmem(&BatchParms,sizeof(BatchParms),0);
  217.     if(bpf = fopen(BATCHPARMS_FILENAME,"r"))
  218.     {    while(!(found || feof(bpf) || ferror(bpf)))
  219.         {    fgets(Buf,sizeof(Buf),bpf);
  220.             found =  !strncmp(name,Buf,strlen(name));
  221.         }
  222.         if(! found)
  223.         {
  224. #ifdef DEBUG
  225.             sprintf(Buf,"can't find batch-parameters for %s, using " DEFAULT "!\n",name);
  226.             myerror(Buf,0);
  227. #endif
  228.             rewind(bpf);
  229.             clrerr(bpf);
  230.             while(!(found || feof(bpf) || ferror(bpf)))
  231.             {    fgets(Buf,sizeof(Buf),bpf);
  232.                 found = !strncmp(DEFAULT,Buf,strlen(DEFAULT));
  233.             }
  234.         }
  235.         fclose(bpf);
  236.         if(! found)
  237.             myerror("can't get batch parameters!\n",20);
  238.         if(ptr = strtok(Buf,WHITESPACE))
  239.         {    if(ptr = strtok(NULL,WHITESPACE))    /* skip sitename, ptr now points to size */
  240.             {    BatchParms.size = atol(ptr);
  241.                 if(ptr = strtok(NULL,WHITESPACE))
  242.                 {    BatchParms.limit = atol(ptr);
  243.                     if(ptr = strtok(NULL,WHITESPACE))
  244.                     {    stccpy(BatchParms.batcher,ptr,sizeof(BatchParms.batcher));
  245.                         if(ptr = strtok(NULL,WHITESPACE))
  246.                         {    stccpy(BatchParms.muncher,ptr,sizeof(BatchParms.muncher));
  247.                             if(ptr = strtok(NULL,WHITESPACE))
  248.                                 stccpy(BatchParms.sender,ptr,sizeof(BatchParms.sender));
  249. #define ERRTEXT    "something is wrong with batchparms-line, "
  250.                             else
  251.                                 myerror(ERRTEXT "sender not found !\n",5);
  252.                         }
  253.                         else
  254.                             myerror(ERRTEXT "muncher not found !\n",5);
  255.                     }
  256.                     else
  257.                         myerror(ERRTEXT "batcher not found !\n",5);
  258.                 }
  259.                 else
  260.                     myerror(ERRTEXT "limit not found !\n",5);
  261.             }
  262.             else
  263.                 myerror(ERRTEXT "size not found !\n",5);
  264.         }
  265.         else
  266.             myerror(ERRTEXT "sitename not found !\n",5);
  267.     }
  268.     else
  269.         myerror("can't open batchparms-file !\n",20);
  270.     if(BatchParms.sender[0])
  271.     {    sprintf(workfile,"UUSPOOL:C.%.7s" TRANSMISSION_GRADE "#?",name);
  272.         anzahl = getfnl(workfile,Buf,sizeof(Buf),0);
  273.         BatchParms.limit -= anzahl;
  274.         if(BatchParms.limit <= 0)
  275.             printf("There are already %ld batchfiles for site %s !\n",anzahl,name);
  276.         else
  277.             DoRealBatch(name);
  278.     }
  279. }
  280.  
  281. void __regargs    DoRealBatch(char *name)
  282. {    FILE *fi, *fo;
  283.     int error;
  284.     strcpy(workfile,OUT_GOING);
  285.     strcat(workfile,name);
  286.     strcat(workfile,BATCH_FILE);
  287.     strcpy(tmpfile1,workfile);
  288.     strcat(tmpfile1,".$$$");
  289.     if(access(workfile,0)==0)
  290.     {    rename(workfile,tmpfile1);
  291.         strcat(workfile,".work");
  292.         if(fo = fopen(workfile,"a"))
  293.         {    if(fi = fopen(tmpfile1,"r"))
  294.             {    while(!(feof(fi) || ferror(fi) || ferror(fo)))
  295.                 {    fgets(Buf,sizeof(Buf),fi);
  296.                     fputs(Buf,fo);
  297.                 }
  298.                 fclose(fi);
  299.             }
  300.             else
  301.                 myerror("can't open tmpfile !\n",20);
  302.             fclose(fo);
  303.         }
  304.         else
  305.             myerror("can't open workfile !\n",20);
  306.         unlink(tmpfile1);
  307.     }
  308.     else
  309.         strcat(workfile,".work");
  310.     sprintf(tmpfile1,"t:batch.%lx.1\0",(LONG)time(NULL));
  311.     sprintf(tmpfile2,"t:batch.%lx.2\0",(LONG)time(NULL));
  312.     if(access(workfile,0)!=0)
  313.         fprintf(stdout,"nothing to queue for %s\n",name);
  314.     while((BatchParms.limit > 0) && (access(workfile,0)==0))
  315.     {    sprintf(Buf,"%s %s %s %ld",BatchParms.batcher,tmpfile1,workfile,BatchParms.size);
  316.         error = system(Buf);
  317.         if(!error)
  318.         {    sprintf(Buf,"%s %s %s",BatchParms.muncher,tmpfile1,tmpfile2);
  319.             error = system(Buf);
  320.             if(! error)
  321.             {    unlink(tmpfile1);
  322.                 sprintf(Buf,"%s %s %s",BatchParms.sender,tmpfile2,name);
  323.                 error = system(Buf);
  324.                 if(! error)
  325.                 {    unlink(tmpfile2);
  326.                     BatchParms.limit--;
  327.                 }
  328.             }
  329.         }
  330.         if(error)
  331.         {    fprintf(stderr," >>%s<< failed with code %d !\n",Buf,error);
  332.             BatchParms.limit = 0;
  333.         }
  334.     }/* End of while */
  335. }
  336.  
  337. void __regargs LockFile(char *file)
  338. {    char *ptr;
  339.     LNode *node;
  340.     LNode *n;
  341.     for (ptr = file + strlen(file); ptr >= file && *ptr != '/' && *ptr != ':'; --ptr)
  342.         ;
  343.     ++ptr;
  344.     if (node = malloc(sizeof(LNode) + strlen(ptr) + 16))
  345.     {    node->Node.ln_Name = (char *)(node + 1);
  346.         sprintf(node->Node.ln_Name, "T:%s.LOCK", ptr);
  347.         for (n = (LNode *)LockList.lh_Head; n != (LNode *)&LockList.lh_Tail; n = (LNode *)n->Node.ln_Succ)
  348.         {    if (strcmp(node->Node.ln_Name, n->Node.ln_Name) == 0)
  349.             {    ++n->Refs;
  350.                 free(node);
  351.                 return;
  352.             }
  353.         }
  354.         while ((node->Fi = fopen(node->Node.ln_Name, "w")) == NULL)
  355.         {    Delay(2);
  356.             chkabort();
  357.         }
  358.         node->Refs = 1;
  359.         AddTail(&LockList, &node->Node);
  360.     }
  361. }
  362.  
  363. void __regargs UnLockFile( char *file)
  364. {    LNode *node;
  365.     short len;
  366.     char *ptr;
  367.     for (ptr = file + strlen(file); ptr >= file && *ptr != '/' && *ptr != ':'; --ptr)
  368.         ;
  369.     ++ptr;
  370.     len = strlen(ptr);
  371.  
  372.     for (node = (LNode *)LockList.lh_Head; node != (LNode *)&LockList.lh_Tail; node = (LNode *)node->Node.ln_Succ)
  373.     {    if (strnicmp(ptr, node->Node.ln_Name + 2, len) == 0 && strlen(node->Node.ln_Name) == len + 7)
  374.         {    if (--node->Refs == 0)
  375.                 FreeLockNode(node);
  376.             return;
  377.         }
  378.     }
  379. }
  380.  
  381. void UnLockFiles(void)
  382. {    register LNode *node;
  383.     while ((node = (LNode *)LockList.lh_Head) != (LNode *)&LockList.lh_Tail)
  384.         FreeLockNode(node);
  385. }
  386.  
  387. void __regargs FreeLockNode(LNode *node)
  388. {    Remove((struct Node*)node);
  389.     fclose(node->Fi);
  390.     unlink(node->Node.ln_Name);
  391.     free(node);
  392. }
  393.