nntpcli.c
上传用户:hepax88
上传日期:2007-01-03
资源大小:1101k
文件大小:19k
源码类别:

TCP/IP协议栈

开发平台:

Visual C++

  1. /*
  2.  * Client routines for Network News Tranfer Protocol ala RFC977
  3.  *
  4.  * Copyright 1990 Anders Klemets - SM0RGV, All Rights Reserved.
  5.  * Permission granted for non-commercial copying and use, provided
  6.  * this notice is retained.
  7.  *
  8.  * Changes copyright 1990 Bernie Roehl, All Rights Reserved.
  9.  * Permission granted for non-commercial copying and use, provided
  10.  * this notice is retained.
  11.  *
  12.  *  Revision history:
  13.  *
  14.  *     May 11, 1990 - br checked for invalid chars in news filenames
  15.  *
  16.  *     May 10, 1990 - br changed date stamp in 'From ' lines to
  17.  *            seconds since GMT (to make parsing and expiry easier)
  18.  *
  19.  *     May 9, 1990 - br added locking of nntp.dat and history files,
  20.  *            second parameter to NNTP DIR, fixed bug in updating of
  21.  *            nntp.dat
  22.  *
  23.  *     early May, 1990 -- br added NNTP TRACE, NNTP DIR,
  24.  *            server-specific newsgroups and connection windows,
  25.  *            locking of newsgroup files using mlock() and rmlock(),
  26.  *            date stamping of 'From ' lines, increased stack space,
  27.  *            updating of nntp.dat only on successful sessions.
  28.  *
  29.  *     July 19, 1990 pa0gri Delinted and cleaned up. (calls and includes)
  30.  *
  31.  */
  32. #include <stdio.h>
  33. #include <sys/types.h>
  34. #include <time.h>
  35. #include <sys/timeb.h>
  36. #include <ctype.h>
  37. #include <string.h>  /* for strchr() */
  38. #ifdef __TURBOC__
  39. #include <dir.h>
  40. #endif
  41. #include "global.h"
  42. #include "timer.h"
  43. #include "cmdparse.h"
  44. #include "commands.h"
  45. #include "socket.h"
  46. #include "usock.h"
  47. #include "netuser.h"
  48. #include "proc.h"
  49. #include "smtp.h"
  50. #include "files.h"
  51. #define NNTPMAXLEN 512
  52. struct nntpservers {
  53. struct timer nntpcli_t;
  54. char *name;
  55. char *groups;
  56. int lowtime, hightime;  /* for connect window */
  57. struct nntpservers *next;
  58. };
  59. #define MAXGROUPDIRS 10
  60. static struct grouploc {
  61. char *prefix;        /* e.g. comp, rec, net, talk, alt ... */
  62. char *directory;     /* directory where these groups should be */
  63. } groupdirs[MAXGROUPDIRS] = { NULL, NULL };
  64. struct nntpservers *Nntpservers = NULL;
  65. static char *Nntpgroups = NULL;
  66. static unsigned short nntptrace = 1;
  67. static char *validchars = "abcdefghijklmnopqrstuvwxyz0123456789-_";
  68. static void nntptick(void *tp);
  69. static void nntp_job(int i1,void *tp,void *v1);
  70. static int gettxt(FILE *network,FILE *fp);
  71. static int getreply(FILE *network);
  72. static int getarticle(FILE *network,char *msgid);
  73. static int dogroups(int argc,char *argv[],void *p);
  74. static int doadds(int argc,char *argv[],void *p);
  75. static int dodrops(int argc,char *argv[],void *p);
  76. static int dokicks(int argc,char *argv[],void *p);
  77. static int dolists(int argc,char *argv[],void *p);
  78. static int donntrace(int argc,char *argv[],void *p);
  79. static int dondir(int argc,char *argv[],void *p);
  80. /* Tracing levels:
  81. 0 - no tracing
  82. 1 - serious errors reported
  83. 2 - transient errors reported
  84. 3 - session progress reported
  85. 4 - actual received articles displayed
  86.  */
  87. static struct cmds Nntpcmds[] = {
  88. "addserver", doadds, 0, 3,
  89. "nntp addserver <nntpserver> <interval>",
  90. "directory", dondir, 0, 0, NULL,
  91. "dropserver", dodrops, 0, 2,
  92. "nntp dropserver <nntpserver>",
  93. "groups", dogroups, 0, 0, NULL,
  94. "kick", dokicks, 0, 2,
  95. "nntp kick <nntpserver>",
  96. "listservers", dolists, 0, 0, NULL,
  97. "trace", donntrace, 0, 0, NULL,
  98. NULL,
  99. };
  100. int
  101. donntp(argc,argv,p)
  102. int argc;
  103. char *argv[];
  104. void *p;
  105. {
  106. return subcmd(Nntpcmds,argc,argv,p);
  107. }
  108. static int
  109. doadds(argc,argv,p)
  110. int argc;
  111. char *argv[];
  112. void *p;
  113. {
  114. struct nntpservers *np;
  115. for(np = Nntpservers; np != NULL; np = np->next)
  116. if(stricmp(np->name,argv[1]) == 0)
  117. break;
  118. if (np == NULL) {
  119. np = (struct nntpservers *) callocw(1,sizeof(struct nntpservers));
  120. np->name = strdup(argv[1]);
  121. np->next = Nntpservers;
  122. Nntpservers = np;
  123. np->groups = NULL;
  124. np->lowtime = np->hightime = -1;
  125. np->nntpcli_t.func = nntptick; /* what to call on timeout */
  126. np->nntpcli_t.arg = (void *)np;
  127. }
  128. if (argc > 3) {
  129. int i;
  130. if (np->groups == NULL) {
  131. np->groups = mallocw(NNTPMAXLEN);
  132. *np->groups = '';
  133. }
  134. for (i = 3; i < argc; ++i) {
  135. if (isdigit(*argv[i])) {
  136. int lh, ll, hh, hl;
  137. sscanf(argv[i], "%d:%d-%d:%d", &lh, &ll, &hh, &hl);
  138. np->lowtime = lh * 100 + ll;
  139. np->hightime = hh * 100 + hl;
  140. } else if ((strlen(np->groups)+strlen(argv[i])+2) >= NNTPMAXLEN)
  141. printf("Group list too long!  Group '%s' ignored!n", argv[i]);
  142. else {  /* it's a group, and it fits... add it to list */
  143. if (*np->groups != '')
  144. strcat(np->groups, ",");
  145. strcat(np->groups, argv[i]);
  146. }
  147. }
  148. if (*np->groups == '') { /* No groups specified? */
  149. free(np->groups);
  150. np->groups = NULL;
  151. }
  152. }
  153. /* set timer duration */
  154. set_timer(&np->nntpcli_t,atol(argv[2])*1000L);
  155. start_timer(&np->nntpcli_t); /* and fire it up */
  156. return 0;
  157. }
  158. static int
  159. dodrops(argc,argv,p)
  160. int argc;
  161. char *argv[];
  162. void *p;
  163. {
  164. struct nntpservers *np, *npprev = NULL;
  165. for(np = Nntpservers; np != NULL; npprev = np, np = np->next)
  166. if(stricmp(np->name,argv[1]) == 0) {
  167. stop_timer(&np->nntpcli_t);
  168. free(np->name);
  169. if (np->groups)
  170. free(np->groups);
  171. if(npprev != NULL)
  172. npprev->next = np->next;
  173. else
  174. Nntpservers = np->next;
  175. free(np);
  176. return 0;
  177. }
  178. printf("No such server enabled.n");
  179. return 0;
  180. }
  181. static int
  182. dolists(argc,argv,p)
  183. int argc;
  184. char *argv[];
  185. void *p;
  186. {
  187. struct nntpservers *np;
  188. for(np = Nntpservers; np != NULL; np = np->next) {
  189. char tbuf[80];
  190. if (np->lowtime != -1 && np->hightime != -1)
  191. sprintf(tbuf, " -- %02d:%02d-%02d:%02d", np->lowtime/100, np->lowtime%100, np->hightime/100, np->hightime%100);
  192. else
  193. tbuf[0] = '';
  194. printf("%-32s (%lu/%lu%s) %sn", np->name,
  195. read_timer(&np->nntpcli_t) /1000L,
  196. dur_timer(&np->nntpcli_t) /1000L,
  197. tbuf, np->groups ? np->groups : "");
  198. }
  199. return 0;
  200. }
  201. static int donntrace(argc, argv, p)
  202. int argc;
  203. char *argv[];
  204. void *p;
  205. {
  206. return setshort(&nntptrace,"NNTP tracing",argc,argv);
  207. }
  208. static char *News_spool = NULL;
  209. static int np_all = 0;  /* non-zero if Newsdir is a malloc'ed space */
  210. static int dondir(argc, argv, p)
  211. int argc;
  212. char *argv[];
  213. void *p;
  214. {
  215. if (argc < 2) {
  216. int i;
  217. printf("spool: %sn", News_spool ? News_spool : Mailspool);
  218. printf("control: %sn", Newsdir);
  219. for (i = 0; i < MAXGROUPDIRS; ++i)
  220. if (groupdirs[i].prefix)
  221. printf("%-10.10s %sn", groupdirs[i].prefix, groupdirs[i].directory);
  222. } else {
  223. char *p;
  224. if ((p = strchr(argv[1], '=')) != NULL) {  /* set a groupdir */
  225. int i;
  226. *p++ = '';
  227. for (i = 0; i < MAXGROUPDIRS; ++i)
  228. if (groupdirs[i].prefix)
  229. if (!strnicmp(groupdirs[i].prefix, argv[1], strlen(argv[1]))) {
  230. if (groupdirs[i].directory) {
  231. free(groupdirs[i].directory);
  232. groupdirs[i].directory = NULL;
  233. }
  234. if (*p == '') {
  235. free(groupdirs[i].prefix);
  236. groupdirs[i].prefix = NULL;
  237. } else
  238. groupdirs[i].directory = strdup(p);
  239. return 0;
  240. }
  241. if (*p == '')  /* trashing a group that's not there */
  242. return 0;
  243. for (i = 0; i < MAXGROUPDIRS; ++i){
  244. if (groupdirs[i].prefix == NULL) {
  245. groupdirs[i].prefix = strdup(argv[1]);
  246. if (groupdirs[i].directory) {
  247. free(groupdirs[i].directory);
  248. groupdirs[i].directory = NULL;
  249. }
  250. groupdirs[i].directory = strdup(p);
  251. return 0;
  252. }
  253. }
  254. printf("Directory table fulln");
  255. }
  256. else {  /* no '=', so just set default */
  257. if (News_spool)
  258. free(News_spool);
  259. News_spool = strdup(argv[1]);
  260. }
  261. if (argc > 2) {  /* they specified a newsdir as well */
  262. if (np_all)
  263. free(Newsdir);
  264. Newsdir = strdup(argv[2]);
  265. np_all = 1;
  266. }
  267. }
  268. return 0;
  269. }
  270. static int
  271. dokicks(argc,argv,p)
  272. int argc;
  273. char *argv[];
  274. void *p;
  275. {
  276. struct nntpservers *np;
  277. for(np = Nntpservers; np != NULL; np = np->next)
  278. if(stricmp(np->name,argv[1]) == 0) {
  279. /* If the timer is not running, the timeout function has
  280. * already been called and we don't want to call it again.
  281. */
  282. if(run_timer(&np->nntpcli_t)) {
  283. stop_timer(&np->nntpcli_t);
  284. nntptick((void *)np);
  285. }
  286. return 0;
  287. }
  288. printf("No such server enabled.n");
  289. return 0;
  290. }
  291. static int
  292. dogroups(argc,argv,p)
  293. int argc;
  294. char *argv[];
  295. void *p;
  296. {
  297. int i;
  298. if(argc < 2) {
  299. if(Nntpgroups == NULL || (Nntpgroups != NULL && strcmp(Nntpgroups,"*") == 0))
  300. printf("All groups are currently enabled.n");
  301. else
  302. printf("Currently enabled newsgroups:n%sn",Nntpgroups);
  303. return 0;
  304. }
  305. if(Nntpgroups == NULL)
  306. Nntpgroups = mallocw(NNTPMAXLEN);
  307. *Nntpgroups = '';
  308. for(i=1; i < argc; ++i) {
  309. if(i > 1)
  310. strcat(Nntpgroups,",");
  311. strcat(Nntpgroups,argv[i]);
  312. }
  313. return 0;
  314. }
  315. /* This is the routine that gets called every so often to connect to
  316.  * NNTP servers.
  317.  */
  318. static void
  319. nntptick(tp)
  320. void *tp;
  321. {
  322. newproc("NNTP client", 3072, nntp_job, 0, tp, NULL,0);
  323. }
  324. static void
  325. nntp_job(i1,tp,v1)
  326. int i1;
  327. void *tp, *v1;
  328. {
  329. FILE *fp, *tmpf;
  330. int s = -1, i;
  331. FILE *network;
  332. /* long pos; */
  333. struct tm *ltm;
  334. time_t t;
  335. int now;
  336. struct nntpservers *np = (struct nntpservers *) tp;
  337. struct sockaddr_in fsocket;
  338. char tbuf[NNTPMAXLEN], buf[NNTPMAXLEN], *cp, *lastdate = NULL;
  339. if (nntptrace >= 3)
  340. printf("NNTP daemon entered, target = %sn",np->name);
  341. if(availmem() != 0){
  342. if (nntptrace >= 2)
  343. printf("NNTP daemon quit -- low memoryn");
  344. /* Memory is tight, don't do anything */
  345. start_timer(&np->nntpcli_t);
  346. return;
  347. }
  348. time(&t); /* more portable than gettime() */
  349. ltm = localtime(&t);
  350. now = ltm->tm_hour * 100 + ltm->tm_min;
  351. if (np->lowtime < np->hightime) {  /* doesn't cross midnight */
  352. if (now < np->lowtime || now >= np->hightime) {
  353. if (nntptrace >= 3)
  354. printf("NNTP window to '%s' not openn", np->name);
  355. start_timer(&np->nntpcli_t);
  356. return;
  357. }
  358. } else {
  359. if (now < np->lowtime && now >= np->hightime) {
  360. if (nntptrace >= 3)
  361. printf("NNTP window to '%s' not openn", np->name);
  362. start_timer(&np->nntpcli_t);
  363. return;
  364. }
  365. }
  366. fsocket.sin_addr.s_addr = resolve(np->name);
  367. if(fsocket.sin_addr.s_addr == 0) {  /* No IP address found */
  368. if (nntptrace >= 2)
  369. printf("NNTP can't resolve host '%s'n", np->name);
  370. /* Try again later */
  371. start_timer(&np->nntpcli_t);
  372. return;
  373. }
  374. fsocket.sin_family = AF_INET;
  375. fsocket.sin_port = IPPORT_NNTP;
  376. s = socket(AF_INET,SOCK_STREAM,0);
  377. if(connect(s,(struct sockaddr *)&fsocket,SOCKSIZE) == -1){
  378. cp = sockerr(s);
  379. logmsg(s,"NNTP %s Connect failed: %s",psocket(&fsocket),
  380. cp != NULL ? cp : "");
  381. if (nntptrace >= 2)
  382. printf("NNTP %s Connect failed: %sn",psocket(&fsocket),
  383. cp != NULL ? cp : "");
  384. goto quit;
  385. }
  386. network = fdopen(s,"r+t");
  387. /* Eat the banner */
  388. i = getreply(network);
  389. if(i == -1 || i >= 400) {
  390. logmsg(fileno(network),"NNTP %s bad reply on banner (response was %d)",psocket(&fsocket),i);
  391. if (nntptrace >= 1)
  392. printf("NNTP %s bad reply on banner (response was %d)n",psocket(&fsocket),i);
  393. goto quit;
  394. }
  395. if (mlock(Newsdir, "nntp")) {
  396. if (nntptrace >= 2)
  397. printf("NNTP %s Connect failed: cannot lock nntp.datn", psocket(&fsocket));
  398. goto quit;
  399. }
  400. sprintf(buf,"%s/nntp.dat",Newsdir);
  401. if((fp = fopen(buf,APPEND_TEXT)) == NULL) {
  402. logmsg(fileno(network),"NNTP %s Connect failed: Cannot open %s",psocket(&fsocket),
  403. buf);
  404. if (nntptrace >= 1)
  405. printf("NNTP %s Connect failed: Cannot open %sn",psocket(&fsocket), buf);
  406. rmlock(Newsdir, "nntp");
  407. goto quit;
  408. }
  409. rewind(fp);
  410. /* for(pos=0L; fgets(buf,NNTPMAXLEN,fp) != NULL;pos=ftell(fp)) { */
  411. for(; fgets(buf,NNTPMAXLEN,fp) != NULL;) {
  412. if((cp = strchr(buf,' ')) == NULL)
  413. continue; /* something wrong with this line, skip it */
  414. *cp = '';
  415. if(stricmp(buf,np->name) == 0) {
  416. rip(cp+1);
  417. lastdate = strdup(cp+1);
  418. break;
  419. }
  420. }
  421. fclose(fp);
  422. rmlock(Newsdir, "nntp");
  423. if(lastdate == NULL)
  424. lastdate = strdup("700101 000000");
  425. /* snapshot the time for use later in re-writing nntp.dat */
  426. time(&t);
  427. ltm = localtime(&t);
  428. /* Get a list of new message-id's */
  429. if (np->groups) {
  430. if (nntptrace >= 3)
  431. printf("==>NEWNEWS %s %sn", np->groups, lastdate);
  432. fprintf(network,"NEWNEWS %s %sn", np->groups, lastdate);
  433. } else {
  434. if (nntptrace >= 3)
  435. printf("==>NEWNEWS %s %sn", Nntpgroups != NULL ? Nntpgroups : "*", lastdate);
  436. fprintf(network,"NEWNEWS %s %sn",Nntpgroups != NULL ? Nntpgroups : "*", lastdate);
  437. }
  438. free(lastdate);
  439. /* Get the response */
  440. if((i = getreply(network)) != 230) { /* protocol error */
  441. logmsg(fileno(network),"NNTP %s protocol error (response was %d)",psocket(&fsocket),i);
  442. if (nntptrace >= 1)
  443. printf("NNTP %s protocol error (response was %d)n",psocket(&fsocket),i);
  444. goto quit;
  445. }
  446. if((tmpf = tmpfile()) == NULL) {
  447. if (nntptrace >= 1)
  448. printf("NNTP %s Cannot open temp filen", psocket(&fsocket));
  449. goto quit;
  450. }
  451. if(gettxt(network,tmpf) == -1) {
  452. logmsg(fileno(network), "NNTP %s giving up: gettxt() failure",psocket(&fsocket));
  453. if (nntptrace >= 1)
  454. printf("NNTP %s giving up: gettxt() failuren",psocket(&fsocket));
  455. fclose(tmpf);
  456. goto quit;
  457. }
  458. /* Open the history file */
  459. if (mlock(Newsdir, "history")) {
  460. if (nntptrace >= 1)
  461. printf("NNTP %s giving up: couldn't lock history filen", psocket(&fsocket));
  462. fclose(tmpf);
  463. goto quit;
  464. }
  465. sprintf(buf,"%s/history",Newsdir);
  466. if((fp = fopen(buf,APPEND_TEXT)) == NULL) {
  467. logmsg(fileno(network),"NNTP %s Connect failed: Cannot open %s",psocket(&fsocket), buf);
  468. if (nntptrace >= 1)
  469. printf("NNTP %s Connect failed: Cannot open %sn",psocket(&fsocket), buf);
  470. fclose(tmpf);
  471. goto quit;
  472. }
  473. /* search through the history file for matching message id's */
  474. rewind(tmpf);
  475. while(fgets(tbuf,NNTPMAXLEN,tmpf) != NULL) {
  476. i = 0;
  477. rewind(fp);
  478. while(fgets(buf,NNTPMAXLEN,fp) != NULL) {
  479. if(stricmp(buf,tbuf) == 0) {
  480. i = 1;
  481. break;
  482. }
  483. kwait(NULL);
  484. }
  485. if(i == 0) { /* not found, get the article */
  486. if(getarticle(network,tbuf) == -1) {
  487. logmsg(fileno(network),"NNTP %s Giving up: could not get article",psocket(&fsocket));
  488. if (nntptrace >= 2)
  489. printf("NNTP %s Giving up: could not get articlen",psocket(&fsocket));
  490. fclose(fp);
  491. rmlock(Newsdir, "history");
  492. fclose(tmpf);
  493. goto quit;
  494. }
  495. fprintf(fp,"%s",tbuf); /* add the new message id */
  496. }
  497. }
  498. fclose(fp);
  499. rmlock(Newsdir, "history");
  500. fclose(tmpf);
  501. if (nntptrace >= 3)
  502. printf("==>QUITn");
  503. fprintf(network,"QUITn");
  504. /* Eat the response */
  505. getreply(network);
  506. /* NOW, update the nntp.dat file */
  507. if (mlock(Newsdir, "nntp")) {
  508. if (nntptrace >= 2)
  509. printf("NNTP %s Could not lock nntp.dat for updaten", psocket(&fsocket));
  510. goto quit;
  511. }
  512. sprintf(buf,"%s/nntp.dat",Newsdir);
  513. fp = fopen(buf,READ_TEXT);
  514. sprintf(buf, "%s/nntp.tmp",Newsdir);
  515. if ((tmpf = fopen(buf, WRITE_TEXT)) == NULL)
  516. if (nntptrace >= 1)
  517. printf("NNTP %s Cannot create temp file '%s'n", psocket(&fsocket), buf);
  518. if (fp == NULL || tmpf == NULL) {
  519. logmsg(fileno(network),"NNTP %s Could not update %s", psocket(&fsocket), buf);
  520. if (nntptrace >= 2)
  521. printf("NNTP %s Could not update %sn",psocket(&fsocket), buf);
  522. if (fp)
  523. fclose(fp);
  524. if (tmpf)
  525. fclose(tmpf);
  526. rmlock(Newsdir, "nntp");
  527. goto quit;
  528. }
  529. while (fgets(tbuf, sizeof(tbuf), fp))
  530. if (strnicmp(tbuf, np->name, strlen(np->name)))
  531. fputs(tbuf, tmpf);
  532. fprintf(tmpf,"%s %02d%02d%02d %02d%02d%02dn",np->name,ltm->tm_year%100,ltm->tm_mon+1,
  533. ltm->tm_mday,ltm->tm_hour,ltm->tm_min,ltm->tm_sec);
  534. fclose(fp);
  535. fclose(tmpf);
  536. sprintf(buf, "%s/nntp.dat", Newsdir);
  537. sprintf(tbuf, "%s/nntp.tmp", Newsdir);
  538. unlink(buf);
  539. rename(tbuf, buf);
  540. rmlock(Newsdir, "nntp");
  541. quit:
  542. if (nntptrace >= 3)
  543. printf("NNTP daemon exitingn");
  544. fclose(network);
  545. /* Restart timer */
  546. start_timer(&np->nntpcli_t);
  547. return;
  548. }
  549. static int
  550. gettxt(network,fp)
  551. FILE *network;
  552. FILE *fp;
  553. {
  554. char buf[NNTPMAXLEN];
  555. int nlines;
  556. for (nlines = 0; fgets(buf,NNTPMAXLEN,network) != NULL; ++nlines) {
  557. if (nntptrace >= 4)
  558. printf("<==%s", buf);
  559. if(strcmp(buf,".n") == 0) {
  560. if (nntptrace >= 3)
  561. printf("NNTP received %d linesn", nlines);
  562. return 0;
  563. }
  564. /* check for escaped '.' characters */
  565. if(strcmp(buf,"..n") == 0)
  566. fputs(".n",fp);
  567. else
  568. fputs(buf,fp);
  569. }
  570. if (nntptrace >= 1)
  571. printf("NNTP receive error after %d linesn", nlines);
  572. return -1;
  573. }
  574. static int
  575. getreply(network)
  576. FILE *network;
  577. {
  578. char buf[NNTPMAXLEN];
  579. int response;
  580. while(fgets(buf,NNTPMAXLEN,network) != NULL) {
  581. /* skip informative messages and blank lines */
  582. if(buf[0] == '' || buf[0] == '1')
  583. continue;
  584. sscanf(buf,"%d",&response);
  585. if (nntptrace >= 3)
  586. printf("<==%sn", buf);
  587. return response;
  588. }
  589. if (nntptrace >= 3)
  590. printf("==No responsen");
  591. return -1;
  592. }
  593. static int
  594. getarticle(network,msgid)
  595. FILE *network;
  596. char *msgid;
  597. {
  598. char buf[NNTPMAXLEN], froml[NNTPMAXLEN], newgl[NNTPMAXLEN];
  599. FILE *fp, *tmpf;
  600. int r;
  601. char *cp;
  602. extern int Smtpquiet;
  603. if (nntptrace >= 3)
  604. printf("==>ARTICLE %s", msgid);
  605. fprintf(network,"ARTICLE %s", msgid);
  606. r = getreply(network);
  607. if(r == -1 || r >= 500)
  608. return -1;
  609. if(r >= 400)
  610. return 0;
  611. if((tmpf = tmpfile()) == NULL) {
  612. if (nntptrace >= 1)
  613. printf("NNTP Cannot open temp file for articlen");
  614. return -1;
  615. }
  616. if(gettxt(network,tmpf) == -1) {
  617. fclose(tmpf);
  618. return -1;
  619. }
  620. /* convert the article into mail format */
  621. rewind(tmpf);
  622. froml[0] = '';
  623. newgl[0] = '';
  624. while(fgets(buf,NNTPMAXLEN,tmpf) != NULL) {
  625. if(strncmp(buf,"From: ",6) == 0) {
  626. struct timeb t;
  627. ftime(&t);
  628. rip(&buf[6]);
  629. sprintf(froml,"From %s %ldn",&buf[6], t.time);
  630. if(newgl[0] != '')
  631. break;
  632. }
  633. if(strncmp(buf,"Newsgroups: ",12) == 0) {
  634. strcpy(newgl,&buf[12]);
  635. if(froml[0] != '')
  636. break;
  637. }
  638. /* invalid article - missing 'From:' line or 'Newsgroups:' line */
  639. if(strcmp(buf,"n") == 0 && (froml[0] == '' || newgl[0] == '')) {
  640. /* fclose(fp); */
  641. fclose(tmpf);
  642. return 0;
  643. }
  644. }
  645. sprintf(buf,"%s/",News_spool ? News_spool : Mailspool);
  646. for(cp=newgl;;++cp) {
  647. if(*cp == '.') {
  648. #ifdef __TURBOC__
  649. mkdir(buf); /* create a subdirectory, if necessary */
  650. #else
  651. mkdir(buf,0755); /* create a subdirectory, if necessary */
  652. #endif
  653. strcat(buf,"/");
  654. continue;
  655. }
  656. if(*cp == ',' || *cp == 'n') {
  657. char tempdir[80], prefix[20], *p;
  658. strcpy(tempdir, buf);
  659. if ((p = strrchr(tempdir, '/')) != NULL) {
  660. *p++ = '';
  661. strcpy(prefix, p);
  662. }
  663. if (mlock(tempdir, prefix)) {
  664. if (nntptrace >= 2)
  665. printf("NNTP group '%s' is lockedn", buf);
  666. return -1;
  667. }
  668. strcat(buf,".txt");
  669. /* open the mail file */
  670. if (nntptrace >= 3)
  671. printf("Writing article to '%s'n", buf);
  672. if((fp = fopen(buf,APPEND_TEXT)) != NULL) {
  673. fputs(froml,fp);
  674. rewind(tmpf);
  675. while(fgets(buf,NNTPMAXLEN,tmpf) != NULL) {
  676. /* for UNIX mail compatiblity */
  677. if(strncmp(buf,"From ",5) == 0)
  678. putc('>',fp);
  679. fputs(buf,fp);
  680. }
  681. putc('n',fp);
  682. fclose(fp);
  683. }
  684. rmlock(tempdir, prefix);
  685. if (*cp == 'n') 
  686. break;
  687. else
  688. sprintf(buf,"%s/",News_spool ? News_spool : Mailspool);
  689. continue;
  690. }
  691. buf[strlen(buf)+1] = '';
  692. buf[strlen(buf)] = strchr(validchars, tolower(*cp)) ? *cp : '_';
  693. }
  694. fclose(tmpf);
  695. strcpy(buf,msgid); /* Get a copy we can munge */
  696. rip(buf); /* remove trailing new-line */
  697. rip(newgl); /* ditto */
  698. #ifdef notdef
  699. printf("New news arrived: %s, article %s%cn",newgl,buf,Smtpquiet?' ':'07');
  700. #else
  701. printf("New news arrived: %s, article %sn",newgl,buf);
  702. #endif
  703. return 0;
  704. }