home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume30 / tin / part14 < prev    next >
Encoding:
Text File  |  1992-05-19  |  47.0 KB  |  2,010 lines

  1. Newsgroups: comp.sources.misc
  2. From: iain%anl433.uucp@germany.eu.net (Iain J. Lea)
  3. Subject:  v30i014:  tin - threaded full screen newsreader, Part14/14
  4. Message-ID: <1992May20.173051.236@sparky.imd.sterling.com>
  5. X-Md4-Signature: 54bb81c5eedeec6b90b74b63e4ec7cae
  6. Date: Wed, 20 May 1992 17:30:51 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: iain%anl433.uucp@germany.eu.net (Iain J. Lea)
  10. Posting-number: Volume 30, Issue 14
  11. Archive-name: tin/part14
  12. Environment: BSD, SCO, ISC, SUNOS, SYSVR3, SYSVR4, ULTRIX, XENIX
  13. Supersedes: tin: Volume 29, Issue 19-30
  14.  
  15. #! /bin/sh
  16. # This is a shell archive.  Remove anything before this line, then feed it
  17. # into a shell via "sh file" or similar.  To overwrite existing files,
  18. # type "sh file -c".
  19. # The tool that generated this appeared in the comp.sources.unix newsgroup;
  20. # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
  21. # Contents:  FTP INSTALL.NNTP common.patch debug.c hashstr.c inews.c
  22. #   patchlev.h prompt.c screen.c search.c wildmat.3 xindex.c xuser.c
  23. # Wrapped by kent@sparky on Tue May 19 13:38:07 1992
  24. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  25. echo If this archive is complete, you will see the following message:
  26. echo '          "shar: End of archive 14 (of 14)."'
  27. if test -f 'FTP' -a "${1}" != "-c" ; then 
  28.   echo shar: Will not clobber existing file \"'FTP'\"
  29. else
  30.   echo shar: Extracting \"'FTP'\" \(2568 characters\)
  31.   sed "s/^X//" >'FTP' <<'END_OF_FILE'
  32. XThis document informs you how to get tin source & binaries in one of 3 ways.
  33. X
  34. X1) Via FTP.
  35. X2) Source code via mail.
  36. X3) Pre-compiled Binaries. 
  37. X
  38. X--------------------------------------------------------------------------------
  39. X
  40. X1) FTP sites that carry the latest version of tin are:
  41. X  
  42. X    ftp.Germany.EU.net  [192.76.144.129]  cd pub/news/tin
  43. X    src.doc.ic.ac.uk    [146.169.2.1]     cd ??
  44. X
  45. XNOTE1: Both sites are in Europe (Germany & England respectively).
  46. XNOTE2: There will be a small time lag before each of these sites makes
  47. X       the newest version available as I post firstly to alt.sources
  48. X
  49. X--------------------------------------------------------------------------------
  50. X
  51. X2) For people that do not have FTP access I am willing to send a copy of the 
  52. X   latest released version (or a beta version of the next patchlevel if so 
  53. X   desired).
  54. X
  55. X2.1) I can handle the following media formats. Specify:
  56. X    5.25 & 3.5 inch floppy disks.
  57. X    0.25 (1/4) inch cartridge tapes (you supply it).
  58. X    5.25 inch ISO Read/Write optical disks (you supply it).
  59. X
  60. X2.2) I can handle the following software formats. Specify:
  61. X    Unix   *.tar *.tar.Z *.tar.z *.tar.zoo
  62. X    Msdos  *.zoo *.zip formats 
  63. X
  64. X2.3) I make a small handling charge for this service as listed below:
  65. X    Germany  15 Deustche Marks
  66. X    England   5 Pounds Sterling
  67. X    USA      10 Dollars 
  68. X
  69. XIf you find the above points 2.1 - 2.3 OK send money/cheque with a self-addressed
  70. Xenvelope stating which media & software format you want to the following address:
  71. X
  72. X    Iain J. Lea
  73. X    BrueckenStr. 12
  74. X    8500 Nuernberg 90
  75. X    Germany.
  76. X
  77. X    Phone. +49-911-331963 (home) +49-911-3089-407 (work) +49-911-3089-290 (FAX)
  78. X    Email. iain%anl433.uucp@Germany.EU.net
  79. X
  80. X--------------------------------------------------------------------------------
  81. X
  82. X3) For people that are having problems compiling tin I am willing to send a 
  83. X   copy of a pre-compiled binary for the following machines:
  84. X
  85. X    i386/486 + SCO Xenix 2.3
  86. X    i386/486 + SCO Unix 3.2
  87. X    i386/486 + ISC Unix 3.2 v3.0
  88. X    SunSparc + SunOS 4.1
  89. X    SonyMIPS + NewsOS 4.1
  90. X    DecMIPS  + Ultrix 4.2
  91. X    DG Avion + DG/UX 4.3
  92. X    Apollo68xxx + DomainOS10.3
  93. X    Siemens MX330 + Sinix v5.23
  94. X    Siemens MX350i + Sinix v5.4
  95. X
  96. X    NOTE: Specify how you want tin to be compiled to access news:
  97. X          1) local spool directory (specify path for newsspool & newslib)
  98. X          2) local spool directory & via NNTP
  99. X          3) via NNTP only
  100. X          4) local spool directory & via news archived on CD-ROM
  101. X    
  102. XFor conditions & shipping read points 2.1 - 2.3 above. 
  103. X
  104. XEnjoy
  105. X    Iain.
  106. END_OF_FILE
  107.   if test 2568 -ne `wc -c <'FTP'`; then
  108.     echo shar: \"'FTP'\" unpacked with wrong size!
  109.   fi
  110.   # end of 'FTP'
  111. fi
  112. if test -f 'INSTALL.NNTP' -a "${1}" != "-c" ; then 
  113.   echo shar: Will not clobber existing file \"'INSTALL.NNTP'\"
  114. else
  115.   echo shar: Extracting \"'INSTALL.NNTP'\" \(3160 characters\)
  116.   sed "s/^X//" >'INSTALL.NNTP' <<'END_OF_FILE'
  117. XThis document explains the install procedure for the supplied patch to the
  118. XNNTP server nntpd & to the TIN newsreader to retrieve index files from the
  119. XNNTP server. 
  120. X
  121. XNNTP server
  122. X-----------
  123. X1) Copy the following files to <nntp-source-dir>/server
  124. X     cp xindex.c <nntp-source-dir>/server
  125. X     cp xuser.c <nntp-source-dir>/server
  126. X
  127. X2) Copy the following files to <nntp-source-dir>
  128. X     cp server.patch <nntp-source-dir>
  129. X     cp common.patch <nntp-source-dir>
  130. X
  131. X3) Patch the files in <nntp-source-dir>/common & <nntp-source-dir>/server
  132. X     cd <nntp-source-dir>
  133. X     patch < common.patch
  134. X     patch < server.patch
  135. X
  136. X4) Copy <nntp-source-dir>/common/conf.h.dist to <nntp-source-dir>/common/conf.h
  137. X     cd <nntp-source-dir>/common
  138. X     cp conf.h.dist conf.h
  139. X
  140. X5) Edit <nntp-source-dir>/common/conf.h to suit your sites needs. The XINDEX
  141. X   & XUSER are #defined by default. You may need to change the path for
  142. X   the #define SUBSCRIBTIONS. The default is /usr/lib/news/subscriptions.
  143. X     cd <nntp-source-dir>/common
  144. X     [vi|emacs] conf.h
  145. X
  146. X6) Recompile & install the NNTP server nntpd
  147. X     cd  <nntp-source-dir>
  148. X     make server
  149. X     make install_server
  150. X
  151. XTIN client
  152. X----------
  153. X1) Edit tin Makefile to enable XINDEX & XUSER functionality.
  154. X     cd <tin-dir>
  155. X     [vi|emacs] Makefile
  156. X     Add -DNNTP_XINDEX to CFLAGS if you want tin to retrieve index files 
  157. X     from the server.
  158. X     Add -DNNTP_XUSER to CFLAGS if you want tin to log the username to
  159. X     the NNTP logfile.
  160. X     Add -DNNTP_EXTS to CFLAGS if you want both NNTP_XINDEX & NNTP_XUSER
  161. X     enabled.
  162. X
  163. X2) Recompile & install tin.
  164. X     cd <tin-dir>
  165. X     make <system>
  166. X     make install
  167. X
  168. XTIN daemon (on NNTP server)
  169. X---------------------------
  170. X1) Edit tin Makefile to enable index daemon functionality.
  171. X     cd <tin-dir>
  172. X     [vi|emacs] Makefile
  173. X     Add -DINDEX_DAEMON to CFLAGS to create a version of tin 'tind' to
  174. X     create & update index files on the NNTP server.
  175. X
  176. X2) Compile & install tind.
  177. X     cd <tin-dir>
  178. X     make <system>
  179. X     make install_daemon
  180. X
  181. X3) Add entry to crontab to start 'tind' index daemon every so often.
  182. X     cd /usr/spool/cron/crontabs
  183. X     [vi|emacs] root
  184. X     Add following line to run tind every 30 minutes: 
  185. X       0,30 * * * * su news -c '/usr/lib/news/tind'
  186. X
  187. XOK. If you have gotten this far you will have the following configuration:
  188. X  o  tind will run every 30 minutes to update a central directory (usually
  189. X     /usr/spool/news/.index) of tin index files for all groups in the active
  190. X     file. The directory can be changed by 'tind -I dir' if so desired.
  191. X
  192. X  o  The NNTP server nntpd will service all requests for tin index files
  193. X     from tin clients. It will do this by returning the contents of the
  194. X     group index file in the index directory (ie. /usr/spool/news/.index/*)
  195. X
  196. X  o  The tin client will issue requests for index files to the NNTP server
  197. X     therefore saving space on the client machine and ensuring that there
  198. X     are only one copy of index files on the whole network.  Also clients
  199. X     will not have to wait while index files are built locally as the index
  200. X     daemon tind runs frequently on the news server.
  201. X             
  202. XEnjoy & happy newsreading
  203. X
  204. X  Iain
  205. END_OF_FILE
  206.   if test 3160 -ne `wc -c <'INSTALL.NNTP'`; then
  207.     echo shar: \"'INSTALL.NNTP'\" unpacked with wrong size!
  208.   fi
  209.   # end of 'INSTALL.NNTP'
  210. fi
  211. if test -f 'common.patch' -a "${1}" != "-c" ; then 
  212.   echo shar: Will not clobber existing file \"'common.patch'\"
  213. else
  214.   echo shar: Extracting \"'common.patch'\" \(2369 characters\)
  215.   sed "s/^X//" >'common.patch' <<'END_OF_FILE'
  216. XFiles common.old/Makefile and common/Makefile are identical
  217. XFiles common.old/README and common/README are identical
  218. XFiles common.old/README.HPUX and common/README.HPUX are identical
  219. XFiles common.old/README.IRIX and common/README.IRIX are identical
  220. XFiles common.old/README.LIB and common/README.LIB are identical
  221. XFiles common.old/README.MTXNIU and common/README.MTXNIU are identical
  222. XFiles common.old/README.SYSV and common/README.SYSV are identical
  223. XFiles common.old/README.XENIX and common/README.XENIX are identical
  224. XFiles common.old/clientlib.c and common/clientlib.c are identical
  225. XFiles common.old/clientlib.h and common/clientlib.h are identical
  226. XOnly in common: conf.h
  227. Xdiff -rcs common.old/conf.h.dist common/conf.h.dist
  228. X*** common.old/conf.h.dist    Wed May  6 09:01:11 1992
  229. X--- common/conf.h.dist    Mon May  4 07:31:14 1992
  230. X***************
  231. X*** 7,12 ****
  232. X--- 7,20 ----
  233. X   * Compile time options.
  234. X   */
  235. X    
  236. X+ /*
  237. X+  * Extensions to NNTP RFC977 (I.Lea 07-03-92)
  238. X+  */
  239. X+ 
  240. X+ #define XUSER            /* log clients username to nntp logfile */
  241. X+ #define XINDEX            /* retieve tin index files from server */
  242. X+ #define SUBSCRIPTIONS_FILE    "/usr/lib/news/subscriptions"
  243. X+ 
  244. X  
  245. X  #undef    ALONE        /* True if we're running without inetd */
  246. X  
  247. XOnly in common: conf.h.dst.old
  248. XOnly in common: conf.h.norisc
  249. Xdiff -rcs common.old/nntp.h common/nntp.h
  250. X*** common.old/nntp.h    Wed May  6 09:01:11 1992
  251. X--- common/nntp.h    Tue Mar 10 08:52:12 1992
  252. X***************
  253. X*** 38,43 ****
  254. X--- 38,46 ----
  255. X  #define    OK_GOODBYE    205    /* Closing connection */
  256. X  #define    OK_GROUP    211    /* Group selected */
  257. X  #define    OK_GROUPS    215    /* Newsgroups follow */
  258. X+ #ifdef XINDEX
  259. X+ #define    OK_XINDEX    218    /* Group index file follows */
  260. X+ #endif
  261. X  #define    OK_ARTICLE    220    /* Article (head & body) follows */
  262. X  #define    OK_HEAD        221    /* Head follows */
  263. X  #define    OK_BODY        222    /* Body follows */
  264. X***************
  265. X*** 57,62 ****
  266. X--- 60,68 ----
  267. X  #define    ERR_GOODBYE    400    /* Have to hang up for some reason */
  268. X  #define    ERR_NOGROUP    411    /* No such newsgroup */
  269. X  #define    ERR_NCING    412    /* Not currently in newsgroup */
  270. X+ #ifdef XINDEX
  271. X+ #define    ERR_XINDEX    418    /* No index file for newsgroup */
  272. X+ #endif
  273. X  #define    ERR_NOCRNT    420    /* No current article selected */
  274. X  #define    ERR_NONEXT    421    /* No next article in this group */
  275. X  #define    ERR_NOPREV    422    /* No previous article in this group */
  276. XFiles common.old/version.c and common/version.c are identical
  277. END_OF_FILE
  278.   if test 2369 -ne `wc -c <'common.patch'`; then
  279.     echo shar: \"'common.patch'\" unpacked with wrong size!
  280.   fi
  281.   # end of 'common.patch'
  282. fi
  283. if test -f 'debug.c' -a "${1}" != "-c" ; then 
  284.   echo shar: Will not clobber existing file \"'debug.c'\"
  285. else
  286.   echo shar: Extracting \"'debug.c'\" \(4195 characters\)
  287.   sed "s/^X//" >'debug.c' <<'END_OF_FILE'
  288. X/*
  289. X *  Project   : tin - a threaded Netnews reader
  290. X *  Module    : debug.c
  291. X *  Author    : I.Lea
  292. X *  Created   : 01-04-91
  293. X *  Updated   : 10-05-92
  294. X *  Notes     : debug routines
  295. X *  Copyright : (c) Copyright 1991-92 by Iain Lea
  296. X *              You may  freely  copy or  redistribute  this software,
  297. X *              so  long as there is no profit made from its use, sale
  298. X *              trade or  reproduction.  You may not change this copy-
  299. X *              right notice, and it must be included in any copy made
  300. X */
  301. X
  302. X#include "tin.h"
  303. X#include "nntplib.h"
  304. X
  305. Xint debug;
  306. X
  307. X/*
  308. X *  nntp specific debug routines
  309. X */
  310. Xvoid debug_nntp (func, line)
  311. X    char *func;    
  312. X    char *line;    
  313. X{
  314. X#ifdef DEBUG
  315. X    FILE *fp;
  316. X
  317. X    if (debug != 1)
  318. X        return;
  319. X
  320. X    if ((fp = fopen ("/tmp/NNTP","a+")) != NULL) {
  321. X        fprintf (fp,"%s: %s\n", func, line);
  322. X        fclose (fp);
  323. X        chmod ("/tmp/NNTP", 0666);
  324. X    }
  325. X#endif
  326. X}
  327. X
  328. X
  329. Xvoid debug_nntp_respcode (respcode)
  330. X    int respcode;
  331. X{
  332. X#ifdef DEBUG
  333. X    debug_nntp ("get_respcode", nntp_respcode (respcode));
  334. X#endif
  335. X}    
  336. X
  337. X/*
  338. X *  tin specific debug routines
  339. X */
  340. Xvoid debug_print_arts ()
  341. X{
  342. X#ifdef DEBUG
  343. X    int i;
  344. X
  345. X    if (debug != 2)
  346. X        return;
  347. X
  348. X    for (i = 0; i < top; i++) {    /* for each group */
  349. X        debug_print_header (&arts[i]);
  350. X    }
  351. X#endif
  352. X}
  353. X
  354. X
  355. Xvoid debug_print_header (s)
  356. X    struct article_t *s;
  357. X{
  358. X#ifdef DEBUG
  359. X    FILE *fp;
  360. X
  361. X    if (debug != 2)
  362. X        return;
  363. X
  364. X    if ((fp = fopen ("/tmp/ARTS","a+")) != NULL) {
  365. X        fprintf (fp,"art=[%5ld] tag=[%s] kill=[%s] hot=[%s]\n", s->artnum,
  366. X            (s->tagged ? "TRUE" : "FALSE"),
  367. X            (s->killed ? "TRUE" : "FALSE"),
  368. X            (s->hot ? "TRUE" : "FALSE"));
  369. X        fprintf (fp,"subj=[%-38s]\n", s->subject);
  370. X        fprintf (fp,"date=[%s]  from=[%s]  name=[%s]\n", s->date, s->from, s->name);
  371. X         if (s->archive) {
  372. X             fprintf (fp, "arch=[%-38s]  ", s->archive);
  373. X         } else {
  374. X             fprintf (fp, "arch=[]  ");
  375. X         }
  376. X         if (s->part) {
  377. X             fprintf (fp, "part=[%s]  ", s->part);
  378. X         } else {
  379. X             fprintf (fp, "part=[]  ");
  380. X         }
  381. X         if (s->patch) {
  382. X             fprintf (fp, "patch=[%s]\n", s->patch);
  383. X        } else {
  384. X             fprintf (fp, "patch=[]\n");
  385. X         }
  386. X        fprintf (fp,"thread=[%d]  inthread=[%d]  unread=[%d]\n\n",
  387. X            s->thread, s->inthread, s->unread);
  388. X/*        fprintf (fp,"thread=[%s]  inthread=[%s]  unread=[%s]\n",
  389. X            (s->thread == ART_NORMAL ? "ART_NORMAL" : "ART_EXPIRED"),
  390. X            (s->inthread ? "TRUE" : "FALSE"),
  391. X            (s->unread ? "TRUE" : "FALSE"));
  392. X*/
  393. X        fflush (fp);
  394. X        fclose (fp);
  395. X        chmod ("/tmp/DUMP", 0666);
  396. X    }
  397. X#endif
  398. X}
  399. X
  400. X
  401. Xvoid debug_print_comment (comment)
  402. X    char *comment;
  403. X{
  404. X#ifdef DEBUG
  405. X    FILE *fp;
  406. X
  407. X    if (debug != 2)
  408. X        return;
  409. X
  410. X    if ((fp = fopen ("/tmp/BASE","a+")) != NULL) {
  411. X        fprintf (fp,"\n%s\n\n", comment);
  412. X        fflush (fp);
  413. X        fclose (fp);
  414. X        chmod ("/tmp/BASE", 0666);
  415. X    }
  416. X#endif
  417. X}
  418. X
  419. X
  420. Xvoid debug_print_base ()
  421. X{
  422. X#ifdef DEBUG
  423. X    FILE *fp;
  424. X    int i;
  425. X
  426. X    if (debug != 2)
  427. X        return;
  428. X
  429. X    if ((fp = fopen ("/tmp/BASE","a+")) != NULL) {
  430. X        for (i = 0; i < top_base; i++) {
  431. X            fprintf (fp, "base[%3d]=[%5ld]\n",i,base[i]);
  432. X        }
  433. X        fflush (fp);
  434. X        fclose (fp);
  435. X        chmod ("/tmp/BASE", 0666);
  436. X    }
  437. X#endif
  438. X}
  439. X
  440. X
  441. Xvoid debug_print_active ()
  442. X{
  443. X#ifdef DEBUG
  444. X    FILE *fp;
  445. X    int i;
  446. X
  447. X    if (debug != 2)
  448. X        return;
  449. X
  450. X    if ((fp = fopen ("/tmp/ACTIVE","w")) != NULL) {
  451. X        for (i = 0; i < num_active; i++) {    /* for each group */
  452. X            fprintf (fp, "[%4d]=[%-28s] max=[%4ld] min=[%4ld] mod=[%c] nxt=[%4d] flag=[%d]\n",
  453. X                i, active[i].name, active[i].max, active[i].min,
  454. X                active[i].moderated, active[i].next, active[i].flag);
  455. X            fprintf (fp, "read=[%d] show=[%d] thread=[%d] sort=[%d] author=[%d] auto=[%d] process=[%d]\n",
  456. X                active[i].attribute.read,    active[i].attribute.showall,
  457. X                active[i].attribute.thread,  active[i].attribute.sortby,
  458. X                active[i].attribute.author,  active[i].attribute.autosave,
  459. X                active[i].attribute.process);
  460. X            fprintf (fp, "server=[%s] ", (active[i].attribute.server  == (char *) 0 ? "" : active[i].attribute.server));
  461. X            fprintf (fp, "maildir=[%s] ",(active[i].attribute.maildir == (char *) 0 ? "" : active[i].attribute.maildir));            
  462. X            fprintf (fp, "savedir=[%s] ",(active[i].attribute.savedir == (char *) 0 ? "" : active[i].attribute.savedir));
  463. X            fprintf (fp, "sigfile=[%s]\n\n",(active[i].attribute.sigfile == (char *) 0 ? "" : active[i].attribute.sigfile));
  464. X        }
  465. X        fflush (fp);
  466. X        fclose (fp);
  467. X        chmod ("/tmp/ACTIVE", 0666);
  468. X    }
  469. X#endif
  470. X}
  471. END_OF_FILE
  472.   if test 4195 -ne `wc -c <'debug.c'`; then
  473.     echo shar: \"'debug.c'\" unpacked with wrong size!
  474.   fi
  475.   # end of 'debug.c'
  476. fi
  477. if test -f 'hashstr.c' -a "${1}" != "-c" ; then 
  478.   echo shar: Will not clobber existing file \"'hashstr.c'\"
  479. else
  480.   echo shar: Extracting \"'hashstr.c'\" \(2510 characters\)
  481.   sed "s/^X//" >'hashstr.c' <<'END_OF_FILE'
  482. X/*
  483. X *  Project   : tin - a threaded Netnews reader
  484. X *  Module    : hashstr.c
  485. X *  Author    : I.Lea & R.Skrenta
  486. X *  Created   : 01-04-91
  487. X *  Updated   : 21-03-92
  488. X *  Notes     :
  489. X *  Copyright : (c) Copyright 1991-92 by Iain Lea & Rich Skrenta
  490. X *              You may  freely  copy or  redistribute  this software,
  491. X *              so  long as there is no profit made from its use, sale
  492. X *              trade or  reproduction.  You may not change this copy-
  493. X *              right notice, and it must be included in any copy made
  494. X */
  495. X
  496. X#include    "tin.h"
  497. X
  498. X/*
  499. X *  Maintain a table of all strings we have seen.
  500. X *  If a new string comes in, add it to the table and return a pointer
  501. X *  to it.  If we've seen it before, just return the pointer to it.
  502. X *
  503. X *  Usage:  hash_str("some string") returns char *
  504. X *
  505. X *  Spillovers are chained on the end
  506. X */
  507. X
  508. X/*
  509. X *  Arbitrary table size, but make sure it's prime!
  510. X */
  511. X
  512. X#define        HASHNODE_TABLE_SIZE    2411
  513. X
  514. Xstruct hashnode *table[HASHNODE_TABLE_SIZE];
  515. X
  516. X
  517. Xchar *hash_str (s)
  518. X    char *s;
  519. X{
  520. X    long h;                /* result of hash:  index into hash table */
  521. X    struct hashnode *p;    /* used to descend the spillover structs */
  522. X
  523. X    if (s == (char *) 0) {
  524. X        return ((char *) 0);
  525. X    }
  526. X
  527. X    {
  528. X        unsigned char *t = (unsigned char *) s;
  529. X
  530. X        h = *t++;
  531. X        while (*t)
  532. X            h = ((h << 1) ^ *t++) % (long) HASHNODE_TABLE_SIZE;
  533. X    }
  534. X
  535. X    p = table[h];
  536. X
  537. X    if (p == (struct hashnode *) 0) {
  538. X        table[h] = add_string (s);
  539. X        return table[h]->s;
  540. X    }
  541. X
  542. X    while (1) {
  543. X        if (strcmp (s, p->s) == 0) {
  544. X            return (p->s);
  545. X        }
  546. X
  547. X        if (p->next == (struct hashnode *) 0) {
  548. X            p->next = add_string (s);
  549. X            return p->next->s;
  550. X        } else {
  551. X            p = p->next;
  552. X        }
  553. X    }
  554. X    /* NOTREACHED */
  555. X}
  556. X
  557. X
  558. Xstruct hashnode *add_string (s)
  559. X    char *s;
  560. X{
  561. X    int *iptr;
  562. X    struct hashnode *p;
  563. X
  564. X    p = (struct hashnode *) my_malloc ((unsigned) sizeof (struct hashnode));
  565. X
  566. X    p->next = (struct hashnode *) 0;
  567. X    iptr = (int *) my_malloc ((unsigned) strlen (s) + sizeof (int) + 1);
  568. X    *iptr++ = -1;
  569. X    p->s = (char *) iptr;
  570. X    strcpy (p->s, s);
  571. X    return (p);
  572. X}
  573. X
  574. X
  575. Xvoid hash_init ()
  576. X{
  577. X    int i;
  578. X
  579. X    for (i = 0; i < HASHNODE_TABLE_SIZE; i++) {
  580. X        table[i] = (struct hashnode *) 0;
  581. X    }
  582. X}
  583. X
  584. X
  585. Xvoid hash_reclaim ()
  586. X{
  587. X    int i;
  588. X    int *iptr;
  589. X    struct hashnode *p, *next;
  590. X
  591. X    for (i = 0; i < HASHNODE_TABLE_SIZE; i++)
  592. X        if (table[i] != (struct hashnode *) 0) {
  593. X            p = table[i];
  594. X            while (p != (struct hashnode *) 0) {
  595. X                next = p->next;
  596. X                if (p->s != (char *) 0) {
  597. X                    iptr = (int *) p->s;
  598. X                    iptr--;
  599. X                    free ((char *) iptr);
  600. X                }
  601. X                free ((char *) p);
  602. X                p = next;
  603. X            }
  604. X            table[i] = (struct hashnode *) 0;
  605. X        }
  606. X}
  607. END_OF_FILE
  608.   if test 2510 -ne `wc -c <'hashstr.c'`; then
  609.     echo shar: \"'hashstr.c'\" unpacked with wrong size!
  610.   fi
  611.   # end of 'hashstr.c'
  612. fi
  613. if test -f 'inews.c' -a "${1}" != "-c" ; then 
  614.   echo shar: Will not clobber existing file \"'inews.c'\"
  615. else
  616.   echo shar: Extracting \"'inews.c'\" \(3615 characters\)
  617.   sed "s/^X//" >'inews.c' <<'END_OF_FILE'
  618. X/*
  619. X *  Project   : tin - a threaded Netnews reader
  620. X *  Module    : inews.c
  621. X *  Author    : I.Lea
  622. X *  Created   : 17-03-92
  623. X *  Updated   : 06-05-92
  624. X *  Notes     : NNTP builtin version of inews
  625. X *  Copyright : (c) Copyright 1991-92 by Iain Lea
  626. X *              You may  freely  copy or  redistribute  this software,
  627. X *              so  long as there is no profit made from its use, sale
  628. X *              trade or  reproduction.  You may not change this copy-
  629. X *              right notice, and it must be included in any copy made
  630. X */
  631. X
  632. X#include    "tin.h"
  633. X#include    "nntplib.h"
  634. X
  635. X#ifdef BSD
  636. X#    ifdef apollo
  637. X#        include    </bsd4.3/usr/include/netdb.h>
  638. X#    else
  639. X#        include    <netdb.h>
  640. X#    endif
  641. X#endif
  642. X
  643. X
  644. Xint submit_inews (name)
  645. X    char *name;
  646. X{
  647. X    int    ret_code = FALSE;
  648. X
  649. X#if !defined(INDEX_DAEMON) && !defined(XSPOOLDIR)
  650. X
  651. X#ifdef NNTP_INEWS
  652. X    char    from_name[256];
  653. X    char    host_name[128];
  654. X    char    line[NNTP_STRLEN];
  655. X    FILE    *fp;
  656. X    int    len = 0;
  657. X    int    respcode;
  658. X
  659. X    if ((fp = fopen (name, "r")) == NULL) {
  660. X        return (ret_code);
  661. X    }
  662. X
  663. X    /*
  664. X     * Send POST command to NNTP server
  665. X     */
  666. X    put_server ("post");
  667. X
  668. X    /*
  669. X     * Receive CONT_POST or ERROR response code from NNTP server
  670. X     */
  671. X    if ((respcode = get_respcode ()) != CONT_POST) {
  672. X        error_message ("%s", nntp_respcode (respcode));
  673. X        debug_nntp ("submit_inews", nntp_respcode (respcode));
  674. X        return (ret_code);
  675. X    }
  676. X
  677. X    get_host_name (host_name);    
  678. X    get_from_name (from_name);
  679. X    
  680. X    /*
  681. X     * Send Path: and From: article headers
  682. X     */
  683. X#ifdef NNTP_INEWS_GATEWAY
  684. X    sprintf (line, "Path: %s", userid);
  685. X#else
  686. X    sprintf (line, "Path: %s!%s", host_name, userid);
  687. X#endif    
  688. X    put_server (line);
  689. X    sprintf (line, "From: %s", from_name);
  690. X    put_server (line);
  691. X
  692. X    /*
  693. X     * Send article 1 line at a time ending with "."
  694. X     */
  695. X    while (fgets (line, sizeof (line), fp) != NULL) {
  696. X        len = strlen (line);
  697. X        line[len-1] = '\0';
  698. X        fprintf (ser_wr_fp, "%s\r\n", line);
  699. X    }
  700. X    
  701. X    put_server (".");
  702. X
  703. X    /*
  704. X     * Receive OK_POSTED or ERROR response code from NNTP server
  705. X     */
  706. X    if ((respcode = get_respcode ()) != OK_POSTED) {
  707. X        error_message ("%s", nntp_respcode (respcode));
  708. X        debug_nntp ("submit_inews", nntp_respcode (respcode));
  709. X        return (ret_code);
  710. X      }
  711. X      
  712. X    ret_code = TRUE;
  713. X
  714. X#endif /* NNTP_ABLE */
  715. X
  716. X#endif /* INDEX_DAEMON */
  717. X
  718. X    return (ret_code);
  719. X}
  720. X
  721. X/*
  722. X * Find real hostname / substitute hostname if news gateway name 
  723. X */
  724. Xvoid get_host_name (host_name)
  725. X    char *host_name;
  726. X{
  727. X#ifndef INDEX_DAEMON
  728. X
  729. X#ifdef NNTP_INEWS_GATEWAY
  730. X    strcpy (host_name, NNTP_INEWS_GATEWAY);
  731. X#else
  732. X    char host[256];
  733. X
  734. X#    if defined(BSD) || defined(sinix) || defined(RS6000) || defined(HPUX)
  735. X    {
  736. X        struct hostent *host_entry;
  737. X
  738. X        gethostname (host, sizeof (host)); 
  739. X        host_entry = gethostbyname (host);
  740. X        my_strncpy (host, host_entry->h_name, sizeof (host)); 
  741. X    }    
  742. X#    else    
  743. X    {
  744. X        struct utsname uts_name;
  745. X
  746. X        uname (&uts_name);
  747. X        my_strncpy (host, uts_name.nodename, sizeof (host));
  748. X    }
  749. X#    endif
  750. X
  751. X    strcpy (host_name, host);
  752. X#endif
  753. X
  754. X#endif /* INDEX_DAEMON */
  755. X}
  756. X
  757. X/*
  758. X * Find users & hosts name
  759. X */
  760. X
  761. Xvoid get_from_name (from_name)
  762. X    char *from_name;
  763. X{
  764. X#ifndef INDEX_DAEMON
  765. X
  766. X    char full_name[128];
  767. X    char host_name[256];
  768. X    char *ptr;
  769. X    
  770. X    if ((ptr = (char *) getenv ("NAME")) != (char *) 0) {
  771. X        my_strncpy (full_name, ptr, sizeof (full_name));
  772. X    } else {    
  773. X        my_strncpy (full_name, myentry->pw_gecos, sizeof (full_name));
  774. X        if ((ptr = (char *) strchr (full_name, ','))) {
  775. X            *ptr = '\0';            
  776. X        }
  777. X    }
  778. X
  779. X    get_host_name (host_name);
  780. X
  781. X#ifdef NNTP_INEWS_DOMAIN
  782. X    sprintf (from_name, "%s@%s%s (%s)",
  783. X        userid, host_name, NNTP_INEWS_DOMAIN, full_name);
  784. X#else    
  785. X    sprintf (from_name, "%s@%s (%s)", userid, host_name, full_name);
  786. X#endif
  787. X
  788. X    if (debug == 2) {
  789. X        error_message ("FROM: %s", from_name);
  790. X    }    
  791. X
  792. X#endif /* INDEX_DAEMON */
  793. X}
  794. END_OF_FILE
  795.   if test 3615 -ne `wc -c <'inews.c'`; then
  796.     echo shar: \"'inews.c'\" unpacked with wrong size!
  797.   fi
  798.   # end of 'inews.c'
  799. fi
  800. if test -f 'patchlev.h' -a "${1}" != "-c" ; then 
  801.   echo shar: Will not clobber existing file \"'patchlev.h'\"
  802. else
  803.   echo shar: Extracting \"'patchlev.h'\" \(585 characters\)
  804.   sed "s/^X//" >'patchlev.h' <<'END_OF_FILE'
  805. X/*
  806. X *  Project   : tin - a threaded Netnews reader
  807. X *  Module    : patchlev.h
  808. X *  Author    : I.Lea
  809. X *  Created   : 01-04-91
  810. X *  Updated   : 12-05-92
  811. X *  Notes     :
  812. X *  Copyright : (c) Copyright 1991-92 by Iain Lea
  813. X *              You may  freely  copy or  redistribute  this software,
  814. X *              so  long as there is no profit made from its use, sale
  815. X *              trade or  reproduction.  You may not change this copy-
  816. X *              right notice, and it must be included in any copy made
  817. X */
  818. X
  819. X#define VERSION        "1.1"        /* Beta versions are "1.n Beta" */
  820. X#define PATCHLEVEL    3
  821. END_OF_FILE
  822.   if test 585 -ne `wc -c <'patchlev.h'`; then
  823.     echo shar: \"'patchlev.h'\" unpacked with wrong size!
  824.   fi
  825.   # end of 'patchlev.h'
  826. fi
  827. if test -f 'prompt.c' -a "${1}" != "-c" ; then 
  828.   echo shar: Will not clobber existing file \"'prompt.c'\"
  829. else
  830.   echo shar: Extracting \"'prompt.c'\" \(3818 characters\)
  831.   sed "s/^X//" >'prompt.c' <<'END_OF_FILE'
  832. X/*
  833. X *  Project   : tin - a threaded Netnews reader
  834. X *  Module    : prompt.c
  835. X *  Author    : I.Lea
  836. X *  Created   : 01-04-91
  837. X *  Updated   : 12-04-92
  838. X *  Notes     :
  839. X *  Copyright : (c) Copyright 1991-92 by Iain Lea
  840. X *              You may  freely  copy or  redistribute  this software,
  841. X *              so  long as there is no profit made from its use, sale
  842. X *              trade or  reproduction.  You may not change this copy-
  843. X *              right notice, and it must be included in any copy made
  844. X */
  845. X
  846. X#include    "tin.h"
  847. X
  848. X/*
  849. X *  prompt_num
  850. X *  get a number from the user
  851. X *  Return -1 if missing or bad number typed
  852. X */
  853. X
  854. Xint prompt_num (ch, prompt)
  855. X    char ch;
  856. X    char *prompt;
  857. X{
  858. X    char *p;
  859. X    int num;
  860. X    int time_remaining;
  861. X
  862. X#ifndef NO_RESYNC_ACTIVE_FILE
  863. X    time_remaining = alarm (0);
  864. X#endif
  865. X    
  866. X    clear_message ();
  867. X
  868. X    sprintf (msg, "%c", ch);
  869. X
  870. X    if ((p = getline (prompt, TRUE, msg)) != (char *) 0) {
  871. X        strcpy (msg, p);
  872. X        num = atoi (msg);
  873. X    } else {
  874. X        num = -1;
  875. X    }
  876. X
  877. X    clear_message ();
  878. X
  879. X#ifndef NO_RESYNC_ACTIVE_FILE
  880. X    alarm (time_remaining);
  881. X#endif
  882. X    
  883. X    return (num);
  884. X}
  885. X
  886. X/*
  887. X *  prompt_string
  888. X *  get a string from the user
  889. X *  Return TRUE if a valid string was typed, FALSE otherwise
  890. X */
  891. X
  892. Xint prompt_string (prompt, buf)
  893. X    char *prompt;
  894. X    char *buf;
  895. X{
  896. X    char *p;
  897. X    int time_remaining;
  898. X
  899. X#ifndef NO_RESYNC_ACTIVE_FILE
  900. X    time_remaining = alarm (0);
  901. X#endif
  902. X
  903. X    clear_message ();
  904. X
  905. X    if ((p = getline (prompt, FALSE, (char *) 0)) == (char *) 0) {
  906. X        buf[0] = '\0';
  907. X        clear_message ();
  908. X#ifndef NO_RESYNC_ACTIVE_FILE
  909. X        alarm (time_remaining);
  910. X#endif
  911. X        return FALSE;
  912. X    }
  913. X    strcpy (buf, p);
  914. X    
  915. X    clear_message ();
  916. X#ifndef NO_RESYNC_ACTIVE_FILE
  917. X    alarm (time_remaining);
  918. X#endif
  919. X    
  920. X    return TRUE;
  921. X}
  922. X
  923. X/*
  924. X *  prompt_menu_string
  925. X *  get a string from the user
  926. X *  Return TRUE if a valid string was typed, FALSE otherwise
  927. X */
  928. X
  929. Xint prompt_menu_string (line, col, var)
  930. X    int line;
  931. X    int col;
  932. X    char *var;
  933. X{
  934. X    char *p;
  935. X    int time_remaining;
  936. X#ifndef NO_RESYNC_ACTIVE_FILE
  937. X    time_remaining = alarm (0);
  938. X#endif
  939. X
  940. X    MoveCursor (line, col);
  941. X
  942. X    if ((p = getline ("", FALSE, var)) == (char *) 0) {
  943. X#ifndef NO_RESYNC_ACTIVE_FILE
  944. X        alarm (time_remaining);
  945. X#endif
  946. X        return FALSE;
  947. X    }
  948. X    strcpy (var, p);
  949. X#ifndef NO_RESYNC_ACTIVE_FILE
  950. X    alarm (time_remaining);
  951. X#endif
  952. X    
  953. X    return TRUE;
  954. X}
  955. X
  956. X
  957. Xint prompt_yn (line, prompt, prompt_ch)
  958. X    int line;
  959. X    char *prompt;
  960. X    int prompt_ch;
  961. X{
  962. X    char ch;
  963. X    int time_remaining;
  964. X#ifndef NO_RESYNC_ACTIVE_FILE
  965. X    time_remaining = alarm (0);
  966. X#endif
  967. X
  968. X    MoveCursor (line, 0);
  969. X    CleartoEOLN ();
  970. X    printf ("%s%c", prompt, prompt_ch);
  971. X    fflush (stdout);
  972. X    MoveCursor (line, (int) strlen (prompt));
  973. X
  974. X    if ((ch = (char) ReadCh()) == CR) {
  975. X        ch = prompt_ch;
  976. X    }    
  977. X
  978. X    if (line == LINES) {
  979. X        clear_message();
  980. X    } else {
  981. X        MoveCursor (line, (int) strlen (prompt));
  982. X        if (ch == ESC) {
  983. X            fputc (prompt_ch, stdout);
  984. X        } else {
  985. X            fputc (ch, stdout);
  986. X        }
  987. X        fflush (stdout);
  988. X    }
  989. X#ifndef NO_RESYNC_ACTIVE_FILE
  990. X    alarm (time_remaining);
  991. X#endif
  992. X
  993. X    return (ch == 'y' ? TRUE : FALSE);
  994. X}
  995. X
  996. X
  997. Xvoid prompt_on_off (row, col, var, help_text, prompt_text)
  998. X    int row;
  999. X    int col;
  1000. X    int *var;
  1001. X    char *help_text;
  1002. X    char *prompt_text;
  1003. X{
  1004. X    int ch, var_orig;
  1005. X    int time_remaining;
  1006. X#ifndef NO_RESYNC_ACTIVE_FILE
  1007. X    time_remaining = alarm (0);
  1008. X#endif
  1009. X
  1010. X    var_orig = *var;
  1011. X
  1012. X    show_menu_help (help_text);
  1013. X    do {
  1014. X        MoveCursor (row, col + (int) strlen (prompt_text));
  1015. X        if ((ch = (char) ReadCh ()) == ' ') {
  1016. X            *var = !*var;
  1017. X            printf ("%s", (*var ? "ON " : "OFF"));
  1018. X            fflush (stdout);
  1019. X        }
  1020. X    } while (ch != CR && ch != ESC);
  1021. X
  1022. X    if (ch == ESC) {
  1023. X        *var = var_orig;
  1024. X        printf ("%s", (*var ? "ON " : "OFF"));
  1025. X        fflush (stdout);
  1026. X    }
  1027. X#ifndef NO_RESYNC_ACTIVE_FILE
  1028. X    alarm (time_remaining);
  1029. X#endif
  1030. X}
  1031. X
  1032. X
  1033. Xvoid continue_prompt ()
  1034. X{
  1035. X    char ch;
  1036. X    int time_remaining;
  1037. X#ifndef NO_RESYNC_ACTIVE_FILE
  1038. X    time_remaining = alarm (0);
  1039. X#endif
  1040. X    
  1041. X    info_message (txt_hit_any_key);
  1042. X    ch = (char) ReadCh ();
  1043. X#ifndef NO_RESYNC_ACTIVE_FILE
  1044. X    alarm (time_remaining);
  1045. X#endif
  1046. X}
  1047. X
  1048. X
  1049. END_OF_FILE
  1050.   if test 3818 -ne `wc -c <'prompt.c'`; then
  1051.     echo shar: \"'prompt.c'\" unpacked with wrong size!
  1052.   fi
  1053.   # end of 'prompt.c'
  1054. fi
  1055. if test -f 'screen.c' -a "${1}" != "-c" ; then 
  1056.   echo shar: Will not clobber existing file \"'screen.c'\"
  1057. else
  1058.   echo shar: Extracting \"'screen.c'\" \(2916 characters\)
  1059.   sed "s/^X//" >'screen.c' <<'END_OF_FILE'
  1060. X/*
  1061. X *  Project   : tin - a threaded Netnews reader
  1062. X *  Module    : screen.c
  1063. X *  Author    : I.Lea & R.Skrenta
  1064. X *  Created   : 01-04-91
  1065. X *  Updated   : 18-04-92
  1066. X *  Notes     :
  1067. X *  Copyright : (c) Copyright 1991-92 by Iain Lea & Rich Skrenta
  1068. X *              You may  freely  copy or  redistribute  this software,
  1069. X *              so  long as there is no profit made from its use, sale
  1070. X *              trade or  reproduction.  You may not change this copy-
  1071. X *              right notice, and it must be included in any copy made
  1072. X */
  1073. X
  1074. X#include    "tin.h"
  1075. X
  1076. Xextern int errno;
  1077. X
  1078. Xchar msg[LEN];
  1079. Xstruct screen_t *screen;
  1080. X
  1081. X
  1082. Xvoid info_message (str)
  1083. X    char *str;
  1084. X{
  1085. X    clear_message ();                /* Clear any old messages hanging around */
  1086. X    center_line (LINES, FALSE, str);    /* center the message at screen bottom */
  1087. X    if (! cmd_line) {
  1088. X        MoveCursor (LINES, 0);
  1089. X    }
  1090. X}
  1091. X
  1092. X
  1093. Xvoid wait_message (str)
  1094. X    char *str;
  1095. X{
  1096. X    clear_message ();      /* Clear any old messages hanging around */
  1097. X    fputs (str, stdout);
  1098. X    fflush (stdout);
  1099. X}
  1100. X
  1101. X
  1102. Xvoid error_message (template, str)
  1103. X    char *template;
  1104. X    char *str;
  1105. X{
  1106. X    errno = 0;
  1107. X
  1108. X    clear_message ();      /* Clear any old messages hanging around */
  1109. X    
  1110. X    fprintf (stderr, template, str);
  1111. X    fflush (stderr);
  1112. X
  1113. X    if (cmd_line) {
  1114. X        fputc ('\n', stderr);
  1115. X        fflush (stderr);
  1116. X    } else {
  1117. X        MoveCursor (LINES, 0);
  1118. X        sleep (2);
  1119. X    }
  1120. X}
  1121. X
  1122. X
  1123. Xvoid perror_message (template, str)
  1124. X    char *template;
  1125. X    char *str;
  1126. X{
  1127. X    char str2[512];
  1128. X
  1129. X    clear_message ();      /* Clear any old messages hanging around */
  1130. X    
  1131. X    sprintf (str2, template, str);
  1132. X    perror (str2);
  1133. X    errno = 0;
  1134. X
  1135. X    if (cmd_line) {
  1136. X        fputc ('\n', stderr);
  1137. X        fflush (stderr);
  1138. X    } else {
  1139. X        MoveCursor (LINES, 0);
  1140. X        sleep (2);
  1141. X    }
  1142. X}
  1143. X
  1144. X
  1145. Xvoid clear_message ()
  1146. X{
  1147. X    if (! cmd_line) {
  1148. X        MoveCursor (LINES, 0);
  1149. X        CleartoEOLN ();
  1150. X    }
  1151. X}
  1152. X
  1153. X
  1154. Xvoid center_line (line, inverse, str)
  1155. X    int line;
  1156. X    int inverse;
  1157. X    char *str;
  1158. X{
  1159. X    int pos;
  1160. X
  1161. X    if (! cmd_line) {
  1162. X        pos = (COLS - (int) strlen (str)) / 2;
  1163. X        MoveCursor (line, pos);
  1164. X        if (inverse) {
  1165. X            StartInverse ();
  1166. X        }
  1167. X    }
  1168. X
  1169. X    fputs (str, stdout);
  1170. X    fflush (stdout);
  1171. X
  1172. X    if (! cmd_line) {
  1173. X        if (inverse) {
  1174. X            EndInverse ();
  1175. X        }
  1176. X    }
  1177. X}
  1178. X
  1179. X
  1180. Xvoid draw_arrow (line)
  1181. X    int line;
  1182. X{
  1183. X    MoveCursor (line, 0);
  1184. X
  1185. X    if (draw_arrow_mark) {
  1186. X        fputs ("->", stdout);
  1187. X        fflush (stdout);
  1188. X    } else {
  1189. X        StartInverse ();
  1190. X        fputs (screen[line-INDEX_TOP].col, stdout);
  1191. X        fflush (stdout);
  1192. X        EndInverse ();
  1193. X    }
  1194. X    MoveCursor (LINES, 0);
  1195. X}
  1196. X
  1197. X
  1198. Xvoid erase_arrow (line)
  1199. X    int line;
  1200. X{
  1201. X    MoveCursor (line, 0);
  1202. X
  1203. X    if (draw_arrow_mark) {
  1204. X        fputs ("  ", stdout);
  1205. X    } else {
  1206. X        EndInverse ();
  1207. X        fputs (screen[line-INDEX_TOP].col, stdout);
  1208. X    }
  1209. X    fflush (stdout);
  1210. X}
  1211. X
  1212. X
  1213. Xvoid show_title (title)
  1214. X    char *title;
  1215. X{    
  1216. X    int col;
  1217. X    
  1218. X    col = (COLS - (int) strlen (txt_type_h_for_help))+1;
  1219. X    if (col) {
  1220. X        MoveCursor (0, col);
  1221. X        if (mail_check ()) {        /* you have mail message in */
  1222. X            fputs (txt_you_have_mail, stdout);
  1223. X        } else {
  1224. X            fputs (txt_type_h_for_help, stdout);
  1225. X        }
  1226. X    }
  1227. X    center_line (0, TRUE, title);
  1228. X}
  1229. X
  1230. X
  1231. Xvoid ring_bell ()
  1232. X{
  1233. X    fputc ('\007', stdout);
  1234. X    fflush (stdout);
  1235. X}
  1236. END_OF_FILE
  1237.   if test 2916 -ne `wc -c <'screen.c'`; then
  1238.     echo shar: \"'screen.c'\" unpacked with wrong size!
  1239.   fi
  1240.   # end of 'screen.c'
  1241. fi
  1242. if test -f 'search.c' -a "${1}" != "-c" ; then 
  1243.   echo shar: Will not clobber existing file \"'search.c'\"
  1244. else
  1245.   echo shar: Extracting \"'search.c'\" \(7173 characters\)
  1246.   sed "s/^X//" >'search.c' <<'END_OF_FILE'
  1247. X/*
  1248. X *  Project   : tin - a threaded Netnews reader
  1249. X *  Module    : search.c
  1250. X *  Author    : I.Lea & R.Skrenta
  1251. X *  Created   : 01-04-91
  1252. X *  Updated   : 13-03-92
  1253. X *  Notes     :
  1254. X *  Copyright : (c) Copyright 1991-92 by Iain Lea & Rich Skrenta
  1255. X *              You may  freely  copy or  redistribute  this software,
  1256. X *              so  long as there is no profit made from its use, sale
  1257. X *              trade or  reproduction.  You may not change this copy-
  1258. X *              right notice, and it must be included in any copy made
  1259. X */
  1260. X
  1261. X#include    "tin.h"
  1262. X
  1263. Xextern FILE *note_fp;
  1264. Xextern int cur_groupnum;
  1265. Xextern int first_group_on_screen;
  1266. Xextern int last_group_on_screen;
  1267. Xextern int first_subj_on_screen;
  1268. Xextern int last_subj_on_screen;
  1269. Xextern int index_point;
  1270. Xextern int note_line;
  1271. Xextern int note_page;
  1272. Xextern int note_end;
  1273. Xextern long note_mark[MAX_PAGES];
  1274. X
  1275. X/*
  1276. X * last search patterns
  1277. X */
  1278. X
  1279. Xchar default_author_search[LEN];
  1280. Xchar default_group_search[LEN];
  1281. Xchar default_subject_search[LEN];
  1282. Xchar default_art_search[LEN];
  1283. X
  1284. X
  1285. X/*
  1286. X *  group.c & page.c
  1287. X */
  1288. Xint search_author (only_unread, current_art, forward)
  1289. X    int only_unread;
  1290. X    int current_art;
  1291. X    int forward;
  1292. X{
  1293. X    char buf[LEN];
  1294. X    char buf2[LEN];
  1295. X    int i, patlen;
  1296. X
  1297. X    clear_message ();
  1298. X
  1299. X    if (forward) {
  1300. X        sprintf (buf2, txt_author_search_forwards, default_author_search);
  1301. X    } else {
  1302. X        sprintf (buf2, txt_author_search_backwards, default_author_search);
  1303. X    }
  1304. X    
  1305. X    if (! prompt_string (buf2, buf)) {
  1306. X        return -1;
  1307. X    }
  1308. X    
  1309. X    if (strlen (buf)) {
  1310. X        strcpy (default_author_search, buf);
  1311. X    } else {
  1312. X        if (default_author_search[0]) {
  1313. X            strcpy (buf, default_author_search);
  1314. X        } else {
  1315. X            info_message (txt_no_search_string);    
  1316. X            return -1;
  1317. X        }
  1318. X    }
  1319. X
  1320. X    wait_message (txt_searching);
  1321. X
  1322. X    make_lower (default_author_search, buf);
  1323. X
  1324. X    patlen = strlen (default_author_search);
  1325. X
  1326. X    i = current_art;
  1327. X
  1328. X    do {
  1329. X        if (forward) {
  1330. X            i = next_response (i);
  1331. X            if (i < 0)
  1332. X                i = base[0];
  1333. X        } else {
  1334. X            i = prev_response (i);
  1335. X            if (i < 0)
  1336. X                i = base[top_base - 1] + 
  1337. X                    num_of_responses (top_base - 1);
  1338. X        }
  1339. X
  1340. X        if (only_unread && arts[i].unread != ART_UNREAD) {
  1341. X            continue;
  1342. X        }
  1343. X            
  1344. X        if (arts[i].name == (char *) 0) {
  1345. X            make_lower (arts[i].from, buf2);
  1346. X        } else {
  1347. X            sprintf (msg, "%s (%s)", arts[i].from, arts[i].name);
  1348. X            make_lower (msg, buf2);
  1349. X        }
  1350. X
  1351. X        if (str_str (buf2, buf, patlen) != 0) {
  1352. X            clear_message ();
  1353. X            return i;
  1354. X        }
  1355. X    } while (i != current_art);
  1356. X
  1357. X    info_message (txt_no_match);
  1358. X    return -1;
  1359. X}
  1360. X
  1361. X/*
  1362. X * select.c
  1363. X */
  1364. Xvoid search_group (forward)
  1365. X    int forward;
  1366. X{
  1367. X    char buf[LEN];
  1368. X    char buf2[LEN];
  1369. X    int i, patlen;
  1370. X
  1371. X    clear_message ();
  1372. X
  1373. X    if (forward) {
  1374. X        sprintf (buf2, txt_search_forwards, default_group_search);
  1375. X    } else {
  1376. X        sprintf (buf2, txt_search_backwards, default_group_search);
  1377. X    }
  1378. X
  1379. X    if (! prompt_string (buf2, buf)) {
  1380. X        return;
  1381. X    }
  1382. X
  1383. X    if (strlen (buf)) {
  1384. X        strcpy (default_group_search, buf);
  1385. X    } else {
  1386. X        if (default_group_search[0]) {
  1387. X            strcpy (buf, default_group_search);
  1388. X        } else {
  1389. X            info_message (txt_no_search_string);    
  1390. X            return;
  1391. X        }
  1392. X    }
  1393. X
  1394. X    wait_message (txt_searching);
  1395. X
  1396. X    make_lower (default_group_search, buf);
  1397. X
  1398. X    patlen = strlen (default_group_search);
  1399. X
  1400. X    i = cur_groupnum;
  1401. X
  1402. X    do {
  1403. X        if (forward)
  1404. X            i++;
  1405. X        else
  1406. X            i--;
  1407. X
  1408. X        if (i >= group_top)
  1409. X            i = 0;
  1410. X        if (i < 0)
  1411. X            i = group_top - 1;
  1412. X
  1413. X        make_lower (active[my_group[i]].name, buf2);
  1414. X
  1415. X        if (str_str (buf2, buf, patlen) != 0) {
  1416. X            if (i >= first_group_on_screen
  1417. X            &&  i < last_group_on_screen) {
  1418. X                clear_message ();
  1419. X                erase_group_arrow ();
  1420. X                cur_groupnum = i;
  1421. X                draw_group_arrow ();
  1422. X            } else {
  1423. X                cur_groupnum = i;
  1424. X                group_selection_page ();
  1425. X            }
  1426. X            return;
  1427. X        }
  1428. X    } while (i != cur_groupnum);
  1429. X
  1430. X    info_message (txt_no_match);
  1431. X}
  1432. X
  1433. X/*
  1434. X * group.c
  1435. X */
  1436. X
  1437. Xvoid search_subject (forward, group)
  1438. X    int forward;
  1439. X    char *group;
  1440. X{
  1441. X    char buf[LEN];
  1442. X    char buf2[LEN];
  1443. X    int i, j, patlen;
  1444. X
  1445. X    if (index_point < 0) {
  1446. X        info_message (txt_no_arts);
  1447. X        return;
  1448. X    }
  1449. X    
  1450. X    clear_message ();
  1451. X
  1452. X    if (forward) {
  1453. X        sprintf (buf2, txt_search_forwards, default_subject_search);
  1454. X    } else {
  1455. X        sprintf (buf2, txt_search_backwards, default_subject_search);
  1456. X    }
  1457. X
  1458. X    if (! prompt_string (buf2, buf)) {
  1459. X        return;
  1460. X    }
  1461. X
  1462. X    if (strlen (buf)) {
  1463. X        strcpy (default_subject_search, buf);
  1464. X    } else {
  1465. X        if (default_subject_search[0]) {
  1466. X            strcpy (buf, default_subject_search);
  1467. X        } else {
  1468. X            info_message (txt_no_search_string);    
  1469. X            return;
  1470. X        }
  1471. X    }
  1472. X
  1473. X    wait_message (txt_searching);
  1474. X
  1475. X    make_lower (default_subject_search, buf);
  1476. X
  1477. X    patlen = strlen (default_subject_search);
  1478. X
  1479. X    i = index_point;
  1480. X
  1481. X    do {
  1482. X        if (forward)
  1483. X            i++;
  1484. X        else
  1485. X            i--;
  1486. X
  1487. X        if (i >= top_base)
  1488. X            i = 0;
  1489. X        if (i < 0)
  1490. X            i = top_base - 1;
  1491. X
  1492. X        j = (int) base[i];
  1493. X
  1494. X        make_lower (arts[j].subject, buf2);
  1495. X
  1496. X        if (str_str (buf2, buf, patlen) != 0) {
  1497. X            if (i >= first_subj_on_screen
  1498. X                &&  i < last_subj_on_screen) {
  1499. X                clear_message ();
  1500. X                erase_subject_arrow ();
  1501. X                index_point = i;
  1502. X                draw_subject_arrow ();
  1503. X            } else {
  1504. X                index_point = i;
  1505. X                show_group_page (group);
  1506. X            }
  1507. X            return;
  1508. X        }
  1509. X    } while (i != index_point);
  1510. X
  1511. X    info_message (txt_no_match);
  1512. X}
  1513. X
  1514. X/*
  1515. X *  page.c (search article body)
  1516. X */
  1517. X
  1518. Xint search_article (forward)
  1519. X    int forward;
  1520. X{
  1521. X    char buf[LEN];
  1522. X    char buf2[LEN];
  1523. X    char string[LEN];
  1524. X    char pattern[LEN];
  1525. X    char *p, *q;
  1526. X    int ctrl_L;
  1527. X    int i, j, patlen;
  1528. X    int orig_note_end;
  1529. X    int orig_note_page;
  1530. X
  1531. X    clear_message ();
  1532. X
  1533. X    if (forward) {
  1534. X        sprintf (buf2, txt_search_forwards, default_art_search);
  1535. X    } else {
  1536. X        sprintf (buf2, txt_search_backwards, default_art_search);
  1537. X    }
  1538. X
  1539. X    if (! prompt_string (buf2, buf)) {
  1540. X        return FALSE;
  1541. X    }
  1542. X
  1543. X    if (strlen (buf)) {
  1544. X        strcpy (default_art_search, buf);
  1545. X    } else {
  1546. X        if (default_art_search[0]) {
  1547. X            strcpy (buf, default_art_search);
  1548. X        } else {
  1549. X            info_message (txt_no_search_string);    
  1550. X            return FALSE;
  1551. X        }
  1552. X    }
  1553. X
  1554. X    wait_message (txt_searching);
  1555. X    
  1556. X    make_lower (default_art_search, pattern);
  1557. X
  1558. X    patlen = strlen (default_art_search);
  1559. X
  1560. X    /*
  1561. X     *  save current position in article
  1562. X     */
  1563. X    orig_note_end = note_end;
  1564. X    orig_note_page = note_page;
  1565. X    
  1566. X    while (! note_end) {
  1567. X        note_line = 1;
  1568. X        ctrl_L = FALSE;
  1569. X
  1570. X        if (note_page == 0) {
  1571. X            note_line += 4;
  1572. X        } else {
  1573. X            note_line += 2;
  1574. X        }
  1575. X        while (note_line < LINES) {
  1576. X            if (fgets (buf, sizeof buf, note_fp) == NULL) {
  1577. X                note_end = TRUE;
  1578. X                break;
  1579. X            }
  1580. X            buf[LEN-1] = '\0';
  1581. X            for (p = buf, q = buf2;    *p && *p != '\n' && q<&buf2[LEN]; p++) {
  1582. X                if (*p == '\b' && q > buf2) {
  1583. X                    q--;
  1584. X                } else if (*p == '\f') {        /* ^L */
  1585. X                    *q++ = '^';
  1586. X                    *q++ = 'L';
  1587. X                    ctrl_L = TRUE;
  1588. X                } else if (*p == '\t') {
  1589. X                    i = q - buf2;
  1590. X                    j = (i|7) + 1;
  1591. X
  1592. X                    while (i++ < j) {
  1593. X                        *q++ = ' ';
  1594. X                    }
  1595. X                } else if (((*p) & 0xFF) < ' ') {
  1596. X                    *q++ = '^';
  1597. X                    *q++ = ((*p) & 0xFF) + '@';
  1598. X                } else {
  1599. X                    *q++ = *p;
  1600. X                }
  1601. X            }
  1602. X            *q = '\0';
  1603. X
  1604. X            make_lower (buf2, string);
  1605. X
  1606. X            if (str_str (string, pattern, patlen) != 0) {
  1607. X                fseek (note_fp, note_mark[note_page], 0);
  1608. X                return TRUE;
  1609. X            }
  1610. X
  1611. X            note_line += ((int) strlen(buf2) / COLS) + 1;
  1612. X
  1613. X            if (ctrl_L) {
  1614. X                break;
  1615. X            }
  1616. X        }
  1617. X        if (! note_end) {
  1618. X            note_mark[++note_page] = ftell (note_fp);
  1619. X        }
  1620. X    }
  1621. X
  1622. X    note_end = orig_note_end;
  1623. X    note_page = orig_note_page;
  1624. X    fseek (note_fp, note_mark[note_page], 0);
  1625. X    info_message (txt_no_match);
  1626. X    return FALSE;
  1627. X}
  1628. X
  1629. X
  1630. Xvoid make_lower (s, t)
  1631. X    char *s;
  1632. X    char *t;
  1633. X{
  1634. X
  1635. X    while (*s) {
  1636. X        if (isupper(*s))
  1637. X            *t = tolower(*s);
  1638. X        else
  1639. X            *t = *s;
  1640. X        s++;
  1641. X        t++;
  1642. X    }
  1643. X    *t = 0;
  1644. X}
  1645. END_OF_FILE
  1646.   if test 7173 -ne `wc -c <'search.c'`; then
  1647.     echo shar: \"'search.c'\" unpacked with wrong size!
  1648.   fi
  1649.   # end of 'search.c'
  1650. fi
  1651. if test -f 'wildmat.3' -a "${1}" != "-c" ; then 
  1652.   echo shar: Will not clobber existing file \"'wildmat.3'\"
  1653. else
  1654.   echo shar: Extracting \"'wildmat.3'\" \(2247 characters\)
  1655.   sed "s/^X//" >'wildmat.3' <<'END_OF_FILE'
  1656. X.TH WILDMAT 3
  1657. X.SH NAME
  1658. Xwildmat \- perform shell-style wildcard matching
  1659. X.SH SYNOPSIS
  1660. X.nf
  1661. X.B "int"
  1662. X.B "wildmat(text, pattern)"
  1663. X.B "    char        *text;"
  1664. X.B "    char        *pattern;"
  1665. X.fi
  1666. X.SH DESCRIPTION
  1667. X.I Wildmat
  1668. Xcompares the
  1669. X.I text
  1670. Xagainst the
  1671. X.I pattern
  1672. Xand
  1673. Xreturns non-zero if the pattern matches the text.
  1674. XThe pattern is interpreted similar to shell filename wildcards, and not
  1675. Xas a full regular expression such as those handled by the
  1676. X.IR grep (1)
  1677. Xfamily of programs or the
  1678. X.IR regex (3)
  1679. Xor
  1680. X.IR regexp (3)
  1681. Xset of routines.
  1682. X.PP
  1683. XThe pattern is interpreted according to the following rules:
  1684. X.TP
  1685. X.BI \e x
  1686. XTurns off the special meaning of
  1687. X.I x
  1688. Xand matches it directly; this is used mostly before a question mark or
  1689. Xasterisk, and is not valid inside square brackets.
  1690. X.TP
  1691. X.B ?
  1692. XMatches any single character.
  1693. X.TP
  1694. X.B *
  1695. XMatches any sequence of zero or more characters.
  1696. X.TP
  1697. X.BI [ x...y ]
  1698. XMatches any single character specified by the set
  1699. X.IR x...y .
  1700. XA minus sign may be used to indicate a range of characters.
  1701. XThat is,
  1702. X.I [0\-5abc]
  1703. Xis a shorthand for
  1704. X.IR [012345abc] .
  1705. XMore than one range may appear inside a character set;
  1706. X.I [0-9a-zA-Z._]
  1707. Xmatches almost all of the legal characters for a host name.
  1708. XThe close bracket,
  1709. X.IR ] ,
  1710. Xmay be used if it is the first character in the set.
  1711. XThe minus sign,
  1712. X.IR \- ,
  1713. Xmay be used if it is either the first or last character in the set.
  1714. X.TP
  1715. X.BI [^ x...y ]
  1716. XThis matches any character
  1717. X.I not
  1718. Xin the set
  1719. X.IR x...y ,
  1720. Xwhich is interpreted as described above.
  1721. XFor example,
  1722. X.I [^]\-]
  1723. Xmatches any character other than a close bracket or minus sign.
  1724. X.SH "BUGS AND LIMITATIONS"
  1725. XThere is no way to end a range with a close bracket.
  1726. X.SH HISTORY
  1727. XWritten by Rich $alz <rsalz@bbn.com> in 1986, and posted to Usenet
  1728. Xseveral times since then, most notably in comp.sources.misc in
  1729. XMarch, 1991.
  1730. X.PP
  1731. XLars Mathiesen <thorinn@diku.dk> enhanced the multi-asterisk failure
  1732. Xmode in early 1991.
  1733. X.PP
  1734. XRich and Lars increased the efficiency of star patterns and reposted it
  1735. Xto comp.sources.misc in April, 1991.
  1736. X.PP
  1737. XRobert Elz <kre@munnari.oz.au> added minus sign and close bracket handling
  1738. Xin June, 1991.
  1739. X.PP
  1740. X.de R$
  1741. XThis is revision \\$3, dated \\$4.
  1742. X..
  1743. X.R$ $Id: wildmat.3,v 1.7 91/07/05 17:50:16 rsalz Exp $
  1744. X.SH "SEE ALSO"
  1745. Xgrep(1), regex(3), regexp(3).
  1746. END_OF_FILE
  1747.   if test 2247 -ne `wc -c <'wildmat.3'`; then
  1748.     echo shar: \"'wildmat.3'\" unpacked with wrong size!
  1749.   fi
  1750.   # end of 'wildmat.3'
  1751. fi
  1752. if test -f 'xindex.c' -a "${1}" != "-c" ; then 
  1753.   echo shar: Will not clobber existing file \"'xindex.c'\"
  1754. else
  1755.   echo shar: Extracting \"'xindex.c'\" \(3476 characters\)
  1756.   sed "s/^X//" >'xindex.c' <<'END_OF_FILE'
  1757. X/*
  1758. X *  Project   : NNTP (RFC 977) extension
  1759. X *  Module    : xindex.c
  1760. X *  Author    : I.Lea
  1761. X *  Created   : 07-03-92
  1762. X *  Updated   : 22-03-92
  1763. X *  Notes     : Add a command to retieve index files from the
  1764. X *              NNTP server so as to save space on the client.
  1765. X *              Ideas borrowed from XTHREAD nntp extension code
  1766. X *              posted by Tim Iverson to alt.sources in mid'91.
  1767. X *  Copyright : (c) Copyright 1992 by Iain Lea
  1768. X *              You may  freely  copy or  redistribute  this software,
  1769. X *              so  long as there is no profit made from its use, sale
  1770. X *              trade or  reproduction.  You may not change this copy-
  1771. X *              right notice, and it must be included in any copy made
  1772. X */
  1773. X
  1774. X#include "common.h"
  1775. X
  1776. X#ifdef XINDEX
  1777. X
  1778. X#undef    DEBUG_XINDEX        /* set to define to turn on more debug info */
  1779. X#define HASH_VALUE 1409        /* mod value for hashing group name */
  1780. X
  1781. X#ifdef __STDC__
  1782. Xvoid xindex (int argc, char *argv[]);
  1783. Xstatic void find_index_file (char *group, char *index_file);
  1784. Xstatic long hash_groupname (char *group);
  1785. X#else
  1786. Xvoid xindex ();
  1787. Xstatic void find_index_file ();
  1788. Xstatic long hash_groupname ();
  1789. X#endif
  1790. X
  1791. X/*
  1792. X *  Usage: XINDEX GROUP
  1793. X *
  1794. X *  GROUP    Group for which to retrieve index file
  1795. X *
  1796. X *  This command is NOT documented in RFC977.
  1797. X */
  1798. X
  1799. Xvoid xindex (argc, argv)
  1800. X    int    argc;
  1801. X    char    *argv[];
  1802. X{
  1803. X    char    line[NNTP_STRLEN];
  1804. X    char    group[256];
  1805. X    char    index_file[256];
  1806. X    char    *cp;
  1807. X    FILE    *fp;
  1808. X    
  1809. X    /*
  1810. X     * "parse" the argument list
  1811. X     */
  1812. X    if (argc == 1) {
  1813. X        printf("%d Usage: XINDEX group\r\n", ERR_CMDSYN);
  1814. X        (void) fflush(stdout);
  1815. X        return;
  1816. X    } else {
  1817. X        strncpy (group, argv[1], sizeof (group)-1);
  1818. X#if defined(SYSLOG) && defined(DEBUG_XINDEX)
  1819. X        syslog(LOG_INFO, "%s xindex %s", hostname, group);
  1820. X#endif
  1821. X
  1822. X        find_index_file(group, index_file);
  1823. X        
  1824. X        if ((fp = fopen(index_file, "r")) == NULL) {
  1825. X#ifdef SYSLOG
  1826. X            syslog(LOG_INFO, "%s xindex cannot open %s (%s)",
  1827. X                hostname, group, index_file);
  1828. X#endif
  1829. X            printf("%d XINDEX Cannot open %s\r\n",
  1830. X                ERR_XINDEX, group);
  1831. X            (void) fflush(stdout);
  1832. X            return;
  1833. X        }
  1834. X
  1835. X        printf("%d XINDEX group in index format\r\n", OK_XINDEX);
  1836. X        (void) fflush(stdout);
  1837. X        
  1838. X        while (fgets(line, sizeof(line), fp) != NULL) {
  1839. X            if ((cp = index(line, '\n')) != NULL)
  1840. X                *cp = '\0';
  1841. X            putline(line);
  1842. X        }
  1843. X        (void) fclose(fp);
  1844. X    
  1845. X        putline(".");
  1846. X        (void) fflush(stdout);
  1847. X    }
  1848. X}
  1849. X
  1850. X/*
  1851. X *  Look in <SPOOLDIR>/.index directory for the index file for the
  1852. X *  given group.  Hashing the group name gets a number. See if that
  1853. X *  #.1 file exists; if so, read first line. Group we want? If not,
  1854. X *  try #.2.  Repeat until no such file or we find the right file.
  1855. X */
  1856. X
  1857. Xstatic void find_index_file (group, index_file)
  1858. X    char *group;
  1859. X    char *index_file;
  1860. X{
  1861. X    char buf[256], *p;
  1862. X    FILE *fp;
  1863. X    int i = 1;
  1864. X    unsigned long hash;
  1865. X
  1866. X    hash = hash_groupname (group);
  1867. X
  1868. X    while (1) {
  1869. X        sprintf (index_file, "%s/.index/%lu.%d", SPOOLDIR, hash, i);
  1870. X        
  1871. X        if ((fp = fopen (index_file, "r")) == NULL) {
  1872. X            return;
  1873. X        }
  1874. X
  1875. X        if (fgets (buf, sizeof (buf), fp) == NULL) {
  1876. X            fclose (fp);
  1877. X            return;
  1878. X        }
  1879. X        fclose (fp);
  1880. X
  1881. X        for (p = buf; *p && *p != '\n'; p++) {
  1882. X            continue;
  1883. X        }    
  1884. X        *p = '\0';
  1885. X
  1886. X        if (strcmp (buf, group) == 0) {
  1887. X            return;
  1888. X        }    
  1889. X        i++;
  1890. X    }    
  1891. X}
  1892. X
  1893. X/*
  1894. X * hash group name for filename of group
  1895. X */
  1896. X
  1897. Xstatic long hash_groupname (group)
  1898. X    char *group;
  1899. X{
  1900. X    unsigned long hash_value;
  1901. X    unsigned char *ptr = (unsigned char *) group;
  1902. X
  1903. X    hash_value = *ptr++;
  1904. X
  1905. X    while (*ptr)
  1906. X        hash_value = ((hash_value << 1) ^ *ptr++) % HASH_VALUE;
  1907. X
  1908. X    return (hash_value);
  1909. X}
  1910. X
  1911. X
  1912. X#endif /* XINDEX */
  1913. X
  1914. END_OF_FILE
  1915.   if test 3476 -ne `wc -c <'xindex.c'`; then
  1916.     echo shar: \"'xindex.c'\" unpacked with wrong size!
  1917.   fi
  1918.   # end of 'xindex.c'
  1919. fi
  1920. if test -f 'xuser.c' -a "${1}" != "-c" ; then 
  1921.   echo shar: Will not clobber existing file \"'xuser.c'\"
  1922. else
  1923.   echo shar: Extracting \"'xuser.c'\" \(1344 characters\)
  1924.   sed "s/^X//" >'xuser.c' <<'END_OF_FILE'
  1925. X/*
  1926. X *  Project   : NNTP (RFC 977) extension
  1927. X *  Module    : xuser.c
  1928. X *  Author    : I.Lea / T.Iverson (iverson@xstor.com)
  1929. X *  Created   : 07-03-92
  1930. X *  Updated   : 07-03-92
  1931. X *  Notes     : Add a command to log nntp clients username.
  1932. X *              Ideas borrowed from XTHREAD nntp extension code
  1933. X *              posted by Tim Iverson to alt.sources in mid'91.
  1934. X *  Copyright : (c) Copyright 1991-92 by Iain Lea
  1935. X *              You may  freely  copy or  redistribute  this software,
  1936. X *              so  long as there is no profit made from its use, sale
  1937. X *              trade or  reproduction.  You may not change this copy-
  1938. X *              right notice, and it must be included in any copy made
  1939. X */
  1940. X
  1941. X#include "common.h"
  1942. X
  1943. X#ifdef XUSER
  1944. X
  1945. X/*
  1946. X *  Usage: XUSER USER
  1947. X *
  1948. X *  USER    log clients username to nntp logfile
  1949. X *
  1950. X *  This command is NOT documented in RFC977.
  1951. X */
  1952. X
  1953. Xvoid xuser (argc, argv)
  1954. X    int    argc;
  1955. X    char    *argv[];
  1956. X{
  1957. X    char    userinfo[NNTP_STRLEN];
  1958. X    int    i;
  1959. X    
  1960. X    /*
  1961. X     * "parse" the argument list
  1962. X     */
  1963. X    if (argc == 1) {
  1964. X        printf("%d Usage: XUSER user\r\n", ERR_CMDSYN);
  1965. X        (void) fflush(stdout);
  1966. X        return;
  1967. X    } else {
  1968. X        sprintf (userinfo, "user %s", argv[1]);
  1969. X        for (i = 2 ; i < argc ; i++) {
  1970. X            strcat (userinfo,  " ");
  1971. X            strcat (userinfo,  argv[i]);
  1972. X        }
  1973. X    }
  1974. X
  1975. X#ifdef SYSLOG
  1976. X        syslog(LOG_INFO, "%s %s", hostname, userinfo);
  1977. X#endif
  1978. X}
  1979. X
  1980. X#endif /* XUSER */
  1981. X
  1982. END_OF_FILE
  1983.   if test 1344 -ne `wc -c <'xuser.c'`; then
  1984.     echo shar: \"'xuser.c'\" unpacked with wrong size!
  1985.   fi
  1986.   # end of 'xuser.c'
  1987. fi
  1988. echo shar: End of archive 14 \(of 14\).
  1989. cp /dev/null ark14isdone
  1990. MISSING=""
  1991. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ; do
  1992.     if test ! -f ark${I}isdone ; then
  1993.     MISSING="${MISSING} ${I}"
  1994.     fi
  1995. done
  1996. if test "${MISSING}" = "" ; then
  1997.     echo You have unpacked all 14 archives.
  1998.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1999. else
  2000.     echo You still must unpack the following archives:
  2001.     echo "        " ${MISSING}
  2002. fi
  2003. exit 0
  2004. exit 0 # Just in case...
  2005.