/*
lite.* - ngetlite main files
Copyright (C) 2000-2004 Matthew Mueller <donut AT dakotacom.net>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <errno.h>
#include <time.h>
#include "log.h"
#include "path.h"
#include "lite.h"
#include "litenntp.h"
#include <string.h>
#include "strreps.h"
#include "sockstuff.h"
char *newstrcpy(char *&dest, const char *src){
int l;
if (dest) free(dest);
l=strlen(src);
dest=(char*)malloc(l+1);
return strcpy(dest,src);
}
int maxretry=20;
c_prot_nntp nntp;
void showhelp(void){
printf("ngetlite v"PACKAGE_VERSION" - 'lite' nntp fetcher for nget\n"
"Copyright 2000-2004 Matthew Mueller <donut AT dakotacom.net>\n");
printf("USAGE: ngetlite <listfiles ...>\n");
printf("listfiles are generated with nget and the -w <listfile> param\n");
exit (0);
}
char *Bfgets(char *buf,int len,FILE*f){
char *r=fgets(buf,len,f);
if (!r)return NULL;
int l=strlen(buf);
if (l>0 && (buf[l-1]=='\n' || buf[l-1]=='\r')){
buf[--l]=0;
if (l>0 && (buf[l-1]=='\n' || buf[l-1]=='\r'))
buf[--l]=0;
}
return r;
}
void dofile(const char *arg){
FILE *listf=fopen(arg,"r+");
if (listf==NULL){
printf("couldn't open %s: %s\n",arg,strerror(errno));
return;
}
char buf[2048];
printf("using litelist file: %s\n",arg);
char *group=NULL;
char *outfile=NULL;
char *host=NULL, *user=NULL, *pass=NULL;
char *cp;
int tempi,i,partdone,retry;
long flagpos,temppos;
char *article=NULL;
ulong lines,bytes;
#define FCHK(a) {if (a) {if (ferror(listf)) {printf(__FILE__":%i ",__LINE__);} goto dofile_ferror;}}
#define Lfgets(buf) {FCHK(Bfgets(buf,2048,listf)==NULL);}
while (!feof(listf)){
FCHK((flagpos=ftell(listf))<0);
Lfgets(buf);
if (strcmp(buf,"1")==0)
partdone=1;
else{
if (strcmp(buf,"0")){
printf("invalid litelist file\n");
goto dofile_error;
return;
}
partdone=0;
}
Lfgets(buf);
newstrcpy(group,buf);
Lfgets(buf);
newstrcpy(outfile,buf);
if (fexists(outfile)) {
printf("%s already exists, skipping\n", outfile);
partdone=1;
}
Lfgets(buf);
tempi=atoi(buf);
for (i=0;i<tempi;i++){
Lfgets(buf);
newstrcpy(host,buf);
//we'll be tricky and make user/pass point to parts of the mem allocated for the host string, rather then allocating seperate mem for all of them. hahaha!
user=pass=NULL;
cp=strchr(host, '\t');
if (cp) {
*cp='\0';
user=cp+1;
cp=strchr(user, '\t');
if (cp) {
*cp='\0';
pass=cp+1;
}
}
Lfgets(buf);
newstrcpy(article,buf);
Lfgets(buf);
bytes=atoul(buf);
Lfgets(buf);
lines=atoul(buf);
if (partdone)
continue;
retry=0;
while (retry<maxretry){
try {
nntp.doopen(host, user, pass);
if (*group)
nntp.dogroup(group);
nntp.doarticle(article,bytes,lines,outfile);
partdone=1;
FCHK((temppos=ftell(listf))<0);
FCHK(fseek(listf,flagpos,SEEK_SET));
FCHK(fputc('1',listf)<0);
FCHK(fseek(listf,temppos,SEEK_SET));
break;
}catch(ApplicationExFatal &e){
printCaughtEx_nnl(e);
printf(" (fatal application error, exiting..)\n");
exit(-1);
}catch(baseEx &e){
if (e.isfatal()){
printCaughtEx_nnl(e);
printf(" (skipping)\n");
break;
}
else{
printCaughtEx_nnl(e);
retry++;
printf(" (retrying %i)\n",retry);
sleep(1);
continue;
}
}
}
}
}
goto dofile_done;
dofile_ferror:
if (ferror(listf))
printf("file error %s: %s\n",arg,strerror(errno));
goto dofile_error;
dofile_error:
dofile_done:
if (listf)
fclose(listf);
safefree(group);
return;
}
int main (int argc, char ** argv){
char *env_str=getenv("NGETLITE_TIMEOUT");
if (env_str && *env_str)
sock_timeout=atoi(env_str);
if ((env_str=getenv("NGETLITE_TRIES")) && *env_str)
maxretry=atoi(env_str);
try {
sockstuff_init();
} catch (baseEx &e) {
printCaughtEx(e);
return 1;
}
quiet=0;debug=1;
srand(time(NULL));
if (argc<2) showhelp();
for (int i=1;i<argc;i++){
dofile(argv[i]);
}
}
syntax highlighted by Code2HTML, v. 0.9.1