home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume30 / netvote / part01 < prev    next >
Encoding:
Text File  |  1992-06-18  |  35.7 KB  |  1,246 lines

  1. Newsgroups: comp.sources.misc
  2. From: dave@elxr.jpl.Nasa.Gov (Dave Hayes)
  3. Subject:  v30i061:  netvote - USENET Newsgroup Voting Software, Part01/01
  4. Message-ID: <1992Jun17.221834.5991@sparky.imd.sterling.com>
  5. X-Md4-Signature: 0a120b1a4b8d6f0067656740aef806f8
  6. Date: Wed, 17 Jun 1992 22:18:34 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: dave@elxr.jpl.Nasa.Gov (Dave Hayes)
  10. Posting-number: Volume 30, Issue 61
  11. Archive-name: netvote/part01
  12. Environment: Perl
  13.  
  14. This is the voting software I used on soc.personals.ads.*
  15. I make no guarantees or warranties...but it worked for
  16. me. It is written in PERL...if you don't have that then
  17. you're on your own to get it.
  18.  
  19. This software is designed to sit at the end of an alias pipe
  20. from some mailer. It recieves mail messages and attempts to
  21. parse a reasonable vote out of them. Whether it finds a vote
  22. or not it sends a reply back to the voter informing him/her
  23. of what (if anything) it was able to do.
  24.  
  25. I left it tailored for the last vote so you could see what I did
  26. more clearly. 
  27.  
  28. Dave Hayes - Network & Communications Engineering - JPL / NASA - Pasadena CA
  29. dave@elxr.jpl.nasa.gov       dave@jato.jpl.nasa.gov         ...usc!elroy!dxh
  30. -------------
  31. #! /bin/sh
  32. # This is a shell archive.  Remove anything before this line, then feed it
  33. # into a shell via "sh file" or similar.  To overwrite existing files,
  34. # type "sh file -c".
  35. # The tool that generated this appeared in the comp.sources.unix newsgroup;
  36. # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
  37. # Contents:  README multi multi/README multi/acknowledge
  38. #   multi/cfv.config multi/cfv_handler.pl multi/makeme multi/official
  39. #   multi/perlsu.c multi/refused single single/README
  40. #   single/acknowledge single/cfv_handler.pl single/makeme
  41. #   single/official single/perlsu.c single/refused
  42. # Wrapped by kent@sparky on Wed Jun 17 17:11:30 1992
  43. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  44. echo If this archive is complete, you will see the following message:
  45. echo '          "shar: End of archive 1 (of 1)."'
  46. if test -f 'README' -a "${1}" != "-c" ; then 
  47.   echo shar: Will not clobber existing file \"'README'\"
  48. else
  49.   echo shar: Extracting \"'README'\" \(161 characters\)
  50.   sed "s/^X//" >'README' <<'END_OF_FILE'
  51. XThis contains two packages:
  52. X
  53. X    single - contains software designed for a vote on a SINGLE newsgroup
  54. X
  55. X    multi  - This will run a single vote on MULTIPLE newsgroups
  56. END_OF_FILE
  57.   if test 161 -ne `wc -c <'README'`; then
  58.     echo shar: \"'README'\" unpacked with wrong size!
  59.   fi
  60.   # end of 'README'
  61. fi
  62. if test ! -d 'multi' ; then
  63.     echo shar: Creating directory \"'multi'\"
  64.     mkdir 'multi'
  65. fi
  66. if test -f 'multi/README' -a "${1}" != "-c" ; then 
  67.   echo shar: Will not clobber existing file \"'multi/README'\"
  68. else
  69.   echo shar: Extracting \"'multi/README'\" \(2343 characters\)
  70.   sed "s/^X//" >'multi/README' <<'END_OF_FILE'
  71. XThis is the voting software I used on soc.personals.ads.*
  72. XI make no guarantees or warranties...but it worked for 
  73. Xme. It is written in PERL...if you don't have that then
  74. Xyou're on your own to get it. 
  75. X
  76. X[*] OVERVIEW
  77. X
  78. XThis software is designed to sit at the end of an alias pipe
  79. Xfrom some mailer. It recieves mail messages and attempts to
  80. Xparse a reasonable vote out of them. Whether it finds a vote
  81. Xor not it sends a reply back to the voter informing him/her
  82. Xof what (if anything) it was able to do.
  83. X
  84. X[*] WHAT'S HERE
  85. X
  86. XI left it tailored for the last vote so you could see what I did
  87. Xmore clearly. Here are the files in this distribution:
  88. X
  89. Xacknowledge - The automatic acknowledgement that is sent
  90. X    a voter via email.
  91. X
  92. Xcfv.config - Most all the configuration data is in here
  93. X
  94. Xcfv_handler.pl - This is the handler for incoming mail. Look
  95. X    inside it to configure it for the path name of the 
  96. X    above file. 
  97. X
  98. Xofficial - Used to do an official tally of votes.  
  99. X
  100. Xrefused - Sent to voter when a vote is refused for some reason
  101. X
  102. X[*] CONFIGURATION
  103. X
  104. XEdit the cfv_handler.pl file to tell it where the cfv.config file
  105. Xis.
  106. X
  107. XEdit the cfv.config file to suit your needs. Everything should be 
  108. Xself explanatory. You'll probably find that the current patterns
  109. Xare ok, feel free to add more according to your needs.
  110. X
  111. X[*] INSTALLATION
  112. X
  113. XSince (for some reason - if you find out please let ME know) 
  114. Xsendmail aliases can be almost any uid, a setuid program is needed
  115. Xto avoid making the vote data world writable. The "makeme" script
  116. X(I *really* didn't want to use 'make') will do this in two 
  117. Xways:
  118. X
  119. X"makeme static" will only work if you have a statically linked
  120. XPERL binary  in this directory AND an "undump" for your system 
  121. Xsomewhere in your path. This is the "preferred" way to make a 
  122. Xsetuid perl program.
  123. X
  124. X"makeme" will make a C wrapper around the program. Make sure that
  125. Xif you do it this way that you don't decide to move this directory
  126. Xto somewhere else without rerunning "makeme".
  127. X
  128. XOnce that is done, a binary called "cfv_handler" should be resident
  129. Xin this directory. Next decide upon an alias for your vote and do
  130. Xthis in your /etc/aliases file:
  131. X
  132. Xvote_address: "| <your directory>/cfv_handler"
  133. X
  134. X[*] TRIVIA
  135. X
  136. XAny problems, bugs, or enhancements should be sent to dave@elxr.jpl.nasa.gov...
  137. Xas this is pretty trivial code I have no problem supporting it.
  138. X
  139. X
  140. X
  141. END_OF_FILE
  142.   if test 2343 -ne `wc -c <'multi/README'`; then
  143.     echo shar: \"'multi/README'\" unpacked with wrong size!
  144.   fi
  145.   # end of 'multi/README'
  146. fi
  147. if test -f 'multi/acknowledge' -a "${1}" != "-c" ; then 
  148.   echo shar: Will not clobber existing file \"'multi/acknowledge'\"
  149. else
  150.   echo shar: Extracting \"'multi/acknowledge'\" \(140 characters\)
  151.   sed "s/^X//" >'multi/acknowledge' <<'END_OF_FILE'
  152. X[This is a recording...]
  153. X
  154. XYour vote on soc.personals.ads.{groups} has been received by my 
  155. Xautomatic voting software. Thank you for voting!
  156. END_OF_FILE
  157.   if test 140 -ne `wc -c <'multi/acknowledge'`; then
  158.     echo shar: \"'multi/acknowledge'\" unpacked with wrong size!
  159.   fi
  160.   # end of 'multi/acknowledge'
  161. fi
  162. if test -f 'multi/cfv.config' -a "${1}" != "-c" ; then 
  163.   echo shar: Will not clobber existing file \"'multi/cfv.config'\"
  164. else
  165.   echo shar: Extracting \"'multi/cfv.config'\" \(1510 characters\)
  166.   sed "s/^X//" >'multi/cfv.config' <<'END_OF_FILE'
  167. X#######################CONFIGURE THESE CONSTANTS
  168. X#
  169. X# Pathname of working directory (all files relative to here)
  170. X$cfv_dir="/home/dave/news/cfv/ads";    
  171. X#
  172. X# Groups you are running a vote for
  173. X@groups = ("soc.personals.ads.male.seeking-male",
  174. X       "soc.personals.ads.male.seeking-female",
  175. X       "soc.personals.ads.female.seeking-male",
  176. X       "soc.personals.ads.female.seeking-female");
  177. X#
  178. X# Pathnames of some files (probably won't need to change these)
  179. X$mass_ack   = "$cfv_dir/mass_acknowledge"; # Where the currently voted people go
  180. X$votes      = "$cfv_dir/votes";              # Where the votes go
  181. X$single_ack = "$cfv_dir/acknowledge";       # Canned vote acknowledgement 
  182. X$refused    = "$cfv_dir/refused";          # Canned vote refusal
  183. X#
  184. X# Other parameters
  185. X$start_date = "4/16/92 06:00";               # Votes start at this time
  186. X$end_date   = "5/18/92 18:00";             # Votes end at this time. 
  187. X$moderator  = "dave@elxr";                 # Who to send errors to
  188. X$backup_err = "$cfv_dir/errors";           # Where to send errors to if above fails
  189. X#
  190. X# Regexp definitions.
  191. X# The software looks for a match such that one of the below regexps
  192. Xpreceeds one of the 
  193. X# above newsgroups. Note the "\\" used to denote a "\", thus a PERL token of "\n"
  194. X# should be written as "\\n" below. 
  195. X#
  196. X# Valid YES vote substring regexps.
  197. X@yesvotes = (
  198. X         "\\sy\\s",
  199. X         "yes",
  200. X         "in.*favo[ur].*"
  201. X);
  202. X#
  203. X# Valid NO vote substring regexps
  204. X@novotes = (
  205. X        "\\sn\\s",
  206. X        "no",
  207. X        "against.*"
  208. X);
  209. X#
  210. X# Why'd Larry make us do this junk?
  211. X1;
  212. X
  213. X
  214. X
  215. END_OF_FILE
  216.   if test 1510 -ne `wc -c <'multi/cfv.config'`; then
  217.     echo shar: \"'multi/cfv.config'\" unpacked with wrong size!
  218.   fi
  219.   # end of 'multi/cfv.config'
  220. fi
  221. if test -f 'multi/cfv_handler.pl' -a "${1}" != "-c" ; then 
  222.   echo shar: Will not clobber existing file \"'multi/cfv_handler.pl'\"
  223. else
  224.   echo shar: Extracting \"'multi/cfv_handler.pl'\" \(5308 characters\)
  225.   sed "s/^X//" >'multi/cfv_handler.pl' <<'END_OF_FILE'
  226. X#!/usr/bin/perl
  227. X#
  228. X# CFV_HANDLER - Handle a CFV from usenet. Expects candidate messages on STDIN.
  229. X# 
  230. X# Copyright (c) 1991 by    Dave Hayes - dave@elxr.jpl.nasa.gov
  231. X#
  232. X# All rights reserved.
  233. X#
  234. X# Permission is given to distribute these sources, as long as the
  235. X# copyright messages are not removed, and no monies are exchanged.
  236. X#
  237. X# Rev 2 - Handles multiple newsgroup votes
  238. X#
  239. X#####################CONFIGURE THIS STUFF!
  240. X#
  241. Xrequire '/home/dave/news/cfv/ads/cfv.config';
  242. X#
  243. X#####################END OF CONFIGURATION STUFF!
  244. X#
  245. X$debug = 0;     # Use this if you want verbosity on ERRLOG
  246. X#
  247. X# This may be a faster way to read messages. With MailMan I didn't
  248. X# care if the message was in an array. Here I do cause I'm searching the
  249. X# body.
  250. X# Thanks to goehring@mentor.cc.purdue.edu (Scott Goehring)
  251. X$* = 1;
  252. X$save = $/; undef $/; $message = <STDIN>; $/ = $save;
  253. Xstudy $message;
  254. X($from) = $message =~ /^From: (.+)$/;
  255. X($subject) = $message =~ /^Subject: (.+)$/;
  256. X$subject =~ tr/A-Z/a-z/;
  257. X&maildebug("Message from '$from' with subject '$subject'");
  258. X#
  259. X# Check the date now. Must be within bounds
  260. X($smon,$sday,$syr,$shr,$smin) = split(/[\s\:\/]/,$start_date);
  261. X($emon,$eday,$eyr,$ehr,$emin) = split(/[\s\:\/]/,$end_date);
  262. X($x1,$cmin,$chr,$cday,$cmon,$cyr,$x2,$x3,$x4) = (localtime);
  263. X$s = &numdate($syr,$smon,$sday,$shr,$smin);
  264. X$e = &numdate($eyr,$emon,$eday,$ehr,$emin);
  265. X$c = &numdate($cyr,$cmon+1,$cday,$chr,$cmin);
  266. Xif ($s > $c || $c > $e) {
  267. X    &mailwarn("Invalid date to vote. Message follows:");
  268. X    print ERRLOG $message;
  269. X    open(ACK,"<$refused") || &mailwarn("Couldn't open '$refused': out
  270. Xof date vote from '$from': $!"); 
  271. X    open(MAIL,"|/usr/lib/sendmail -t") || &mailwarn("Couldn't pipe to
  272. Xmail: out of date vote from '$from'"); 
  273. X    print MAIL <<EOT;
  274. XFrom: $moderator
  275. XTo: $from
  276. XSubject: Error in your vote
  277. XEOT
  278. X    print MAIL <ACK>;
  279. X    print MAIL "\nYour vote is not with in the date bounds
  280. X'$start_date' and '$end_date'.\n";
  281. X    close(MAIL);
  282. X    &maildie("EOT.",0);
  283. X}
  284. X
  285. X#
  286. X# Now check for a valid vote.
  287. Xforeach $group (@groups) {
  288. X    $got = 0;
  289. X    foreach $yv (@yesvotes) {
  290. X    if (($message =~ /$yv[^\n]*$group/i) || ($message =~ /$group[^\n]*$yv/i))  {
  291. X        #
  292. X        # A YES vote
  293. X        #
  294. X        &mass_ack;
  295. X        open(VOTES,">>$votes") || &mailwarn("Couldn't open
  296. X'$votes': YES vote from '$from' : ($<,$>) $!");
  297. X        print VOTES "[Y] $group $from\n"; close(VOTES);
  298. X        $got = 1;
  299. X        $vote{$group} = "Y";
  300. X    }
  301. X    }
  302. X    foreach $nv (@novotes) {
  303. X    if (($message =~ /$nv[^\n]*$group/i) || ($message =~ /$group[^\n]*$nv/i))  {
  304. X        #
  305. X        # A NO vote
  306. X        #
  307. X        &mass_ack;
  308. X        open(VOTES,">>$votes") || &mailwarn("Couldn't open
  309. X'$votes': NO vote from '$from' : $! ");
  310. X        print VOTES "[N] $group $from\n";
  311. X        close(VOTES);
  312. X        $vote{$group} = "N";
  313. X        $got = 1;
  314. X    }
  315. X    }
  316. X    if (!$got) {
  317. X    open(VOTES,">>$votes") || &mailwarn("Couldn't open '$votes': NO
  318. Xvote from '$from' : $! ");
  319. X    print VOTES "[A] $group $from\n";
  320. X    close(VOTES);
  321. X    $vote{$group} = "A";
  322. X    }
  323. X}
  324. X
  325. Xopen(ACK,"<$single_ack") || &mailwarn("Couldn't open '$single_ack':
  326. XYES vote from '$from': $!"); 
  327. Xopen(MAIL,"|/usr/lib/sendmail -t") || &mailwarn("Couldn't pipe to
  328. Xmail: out of date vote from '$from'");
  329. Xprint MAIL <<EOT;
  330. XFrom: $moderator
  331. XTo: $from
  332. XSubject: Your vote
  333. XEOT
  334. X
  335. Xprint MAIL <ACK>;
  336. Xprint MAIL "\nYour vote was recorded like so:\n";
  337. Xforeach $group (@groups) {
  338. X    if ($vote{$group} eq "A") { $v = "Abstain"; }
  339. X    if ($vote{$group} eq "Y") { $v = "Yes"; }
  340. X    if ($vote{$group} eq "N") { $v = "No"; }
  341. X    print MAIL "\tFor group $group: $v\n";
  342. X}
  343. Xclose(MAIL); close(ACK);
  344. X
  345. X######
  346. X###### SUBROUTINES GO HERE
  347. X######
  348. Xsub mass_ack {
  349. X    return if (defined($acked));
  350. X    open(MASS,">>$mass_ack") || &mailwarn("Couldn't open '$mass_ack':
  351. XYES vote from '$from' : ($<,$>) $!");
  352. X    print MASS "$from\n"; close(MASS);
  353. X    $acked = 1;
  354. X}
  355. X
  356. Xsub mailwarn {
  357. X    local($reason) = shift(@_);
  358. X    &setup_mail if (!defined($mail_is_on));
  359. X    print ERRLOG <<EOT;
  360. XFrom: cfv_daemon
  361. XTo: $moderator
  362. XSubject: CFV daemon report
  363. X
  364. XWarning about Mail from: '$from' with subject: '$subject':
  365. XReason: $reason.
  366. XEOT
  367. X
  368. X}
  369. Xsub maillog {
  370. X    local($reason) = shift(@_);
  371. X
  372. X    &setup_mail if (!defined($mail_is_on));
  373. X    print ERRLOG <<EOT;
  374. XFrom: cfv_daemon
  375. XTo: $moderator
  376. XSubject: CFV daemon report
  377. X
  378. XMail from: '$from' with subject: '$subject' logged:
  379. XReason: $reason.
  380. XEOT
  381. X    close(ERRLOG);
  382. X}
  383. Xsub maildebug {
  384. X    local($reason) = shift(@_);
  385. X    
  386. X    return 0 if (!$debug);
  387. X    &setup_mail if (!defined($mail_is_on));
  388. X    print ERRLOG <<EOT;
  389. XFrom: cfv_daemon
  390. XTo: $moderator
  391. XSubject: CFV daemon report
  392. X
  393. XDebug Mail from: '$from' with subject: '$subject':
  394. XReason: $reason.
  395. XEOT
  396. X}
  397. X
  398. Xsub maildie {    
  399. X    local($reason) = shift(@_);
  400. X    local($exitcode) = shift(@_);
  401. X
  402. X    exit 0 if ($exitcode == 0);
  403. X    &setup_mail if (!defined($mail_is_on));
  404. X    print ERRLOG <<EOT;
  405. XFrom: cfv_daemon
  406. XTo: $moderator
  407. XSubject: CFV daemon report
  408. X
  409. XMail from: '$from' with subject: '$subject' failed:
  410. XReason: $reason.
  411. XEOT
  412. X    close(ERRLOG);
  413. X    exit $exitcode;
  414. X}
  415. X
  416. Xsub numdate {
  417. X    local($y,$m,$d,$mn,$h) = @_;
  418. X    local($n);
  419. X
  420. X    $n = $h + (100*$mn) + (10000*$d) + (1000000*$m) + ($y * 100000000);
  421. X    &maildebug("Converted ($y,$m,$d,$mn,$h) to $n");
  422. X    return $n;
  423. X}
  424. X    
  425. Xsub setup_mail {
  426. X    $mail_is_on = 1;
  427. X    if (!open(ERRLOG,"| /usr/lib/sendmail -t")) {
  428. X    open(ERRLOG,">>$backup_err") || warn "Augh! Can't redirect
  429. XERRLOG to someplace useful!\n";
  430. X   }
  431. X    select(ERRLOG); $| = 1; 
  432. X}
  433. END_OF_FILE
  434.   if test 5308 -ne `wc -c <'multi/cfv_handler.pl'`; then
  435.     echo shar: \"'multi/cfv_handler.pl'\" unpacked with wrong size!
  436.   fi
  437.   # end of 'multi/cfv_handler.pl'
  438. fi
  439. if test -f 'multi/makeme' -a "${1}" != "-c" ; then 
  440.   echo shar: Will not clobber existing file \"'multi/makeme'\"
  441. else
  442.   echo shar: Extracting \"'multi/makeme'\" \(214 characters\)
  443.   sed "s/^X//" >'multi/makeme' <<'END_OF_FILE'
  444. X#!/bin/csh 
  445. Xif ("$1" == "static") then
  446. X    ./perl -u cfv_handler
  447. X    undump cfv_handler perl core
  448. X    chmod 4755 cfv_handler
  449. Xelse
  450. X    setenv PWD `pwd`
  451. X    cc -o cfv_handler perlsu.c -DPWD=\"$PWD/\"
  452. X    chmod 4755 cfv_handler
  453. Xendif
  454. X
  455. END_OF_FILE
  456.   if test 214 -ne `wc -c <'multi/makeme'`; then
  457.     echo shar: \"'multi/makeme'\" unpacked with wrong size!
  458.   fi
  459.   # end of 'multi/makeme'
  460. fi
  461. if test -f 'multi/official' -a "${1}" != "-c" ; then 
  462.   echo shar: Will not clobber existing file \"'multi/official'\"
  463. else
  464.   echo shar: Extracting \"'multi/official'\" \(3279 characters\)
  465.   sed "s/^X//" >'multi/official' <<'END_OF_FILE'
  466. X#!/usr/bin/perl
  467. X# 
  468. X#    OFFICIAL - official status of CFV
  469. X#            and deal with duplicates properly
  470. X#
  471. Xdie "usage: official [-l|-f|-d]
  472. X\twhere -l does last vote priority
  473. X\t      -f does first vote priority
  474. X\t      -d discards duplicates\n" if (!defined($ARGV[0]));
  475. X#
  476. X# Get config
  477. X# 
  478. Xrequire 'cfv.config';
  479. X#
  480. X# Raw, time-ordered, data
  481. X#
  482. X@votes = `cat votes`;
  483. X#
  484. X# This builds an associative array that has cleaned data
  485. X#
  486. X$y =0; $n = 0;
  487. Xfor ($i=0; $i<=$#votes; $i++) {
  488. X    if ($votes[$i] =~ /^\[([YNA])\]\s+(\S+)\s+(.*)/) {
  489. X    $p = "$3\n"; 
  490. X    push(@people,$p) if (grep($_ eq $p,@people) == 0);
  491. X    $g = $2;
  492. X    $v = $1;
  493. X    } else {
  494. X    print "Bad syntax in vote: <$votes[$i]>\n";
  495. X    next;
  496. X    } 
  497. X    if (!defined($vote{$p,$g})) {
  498. X    if ($v eq "Y") {
  499. X        $vote{$p,$g} = "yes";
  500. X        $y++;
  501. X    } elsif ($v eq "N") {
  502. X        $vote{$p,$g} = "no";
  503. X        $n++;
  504. X    } elsif ($v eq "A") {
  505. X        $vote{$p,$g} = "abs";
  506. X        $n++;
  507. X    } else { 
  508. X        print "Bad vote: <$votes[$i]>\n";
  509. X    }
  510. X    next;
  511. X    }
  512. X    $first{$p,$g} = $vote{$p,$g} if (!defined($first{$p,$g}));
  513. X    if ($v eq "Y") {
  514. X    $last{$p,$g} = "yes";
  515. X    $y++;
  516. X    } elsif ($v eq "N") {
  517. X    $last{$p,$g} = "no";
  518. X    $n++;
  519. X    } elsif ($v eq "A") {
  520. X    $last{$p,$g} = "abs";
  521. X    $n++;
  522. X    } else { 
  523. X    print "Bad vote: <$votes[$i]>\n";
  524. X    }
  525. X    $vote{$p,$g} = "dup";
  526. X}
  527. X#
  528. X# Filter the array appropriately
  529. X#
  530. Xprint "[DAVE'S AUTOMATIC USENET CFV HANDLER - Rev 2]\n";
  531. X
  532. Xforeach $group (@groups) {
  533. X    @tmass = @people;
  534. X    @tyes  = grep($vote{$_,$group} eq "yes",@tmass);
  535. X    @tno   = grep($vote{$_,$group} eq "no",@tmass);
  536. X    @tdups = grep($vote{$_,$group} eq "dup",@tmass);
  537. X#
  538. X# Now deal with duplicates. 
  539. X#
  540. X    if ($ARGV[0] eq "-l") {
  541. X    $method = "Last vote taken as valid";
  542. X    foreach $person (@tdups) {
  543. X        push(@tyes,$person) if ($last{$person,$group} eq "yes");
  544. X        push(@tno,$person) if ($last{$person,$group} eq "no");
  545. X        $vote{$person,$group} = $last{$person,$group};
  546. X    }
  547. X    } elsif ($ARGV[0] eq "-f") {
  548. X    $method = "First vote taken as valid";
  549. X    foreach $person (@tdups) {
  550. X        push(@tyes,$person) if ($first{$person,$group} eq "yes");
  551. X        push(@tno,$person) if ($first{$person,$group} eq "no");
  552. X        $vote{$person,$group} = $first{$person,$group};
  553. X    }
  554. X    } elsif ($ARGV[0] eq "-d") {
  555. X    $method = "Duplicates discarded";
  556. X    } else {
  557. X    die "Illegal argument: $ARGV[0]\n";
  558. X    }
  559. X
  560. X# Tally ho!
  561. X#
  562. X    $tyes = $#tyes + 1;
  563. X    $tno  = $#tno + 1;
  564. X    $tmass = $#tmass + 1;
  565. X    $tdups =  $#tdups + 1;
  566. X    $tmass -= $tdups if ($tdups > 0);
  567. X    $pyes = $tyes/$tmass * 100; $pyes = sprintf("%02.2f",$pyes);
  568. X    $pno  = $tno/$tmass * 100;  $pno  = sprintf("%02.2f",$pno);
  569. X    $pct  = $tyes + $tno;
  570. X    $pdiff = $tyes - $tno;
  571. X
  572. X    print "
  573. X   NewsGroup: $group
  574. XTotal  Votes: $tmass\t
  575. XYes    Votes: $tyes\t($pyes%)
  576. XNo     Votes: $tno\t($pno%)
  577. XYes-No Votes: $pdiff
  578. XDuplicates:   $tdups 
  579. XDuplicate Resolution: $method\n";
  580. X}
  581. X
  582. Xprint "\nVote Key - Number refers to column:\n";
  583. Xfor $i (0..$#groups) {
  584. X    print "\t$i: $groups[$i]\n";
  585. X    $k = $i % 10; $m = int($i/10);
  586. X    $row1 .= "$m";
  587. X    $row2 .= "$k";
  588. X    $row3 .= "=";
  589. X}
  590. Xprint "
  591. X-VOTE COLUMN-
  592. X$row1
  593. X$row2
  594. X$row3
  595. X";
  596. X
  597. Xforeach $p (sort @people) {
  598. X    for $i (0..$#groups) {
  599. X    print "Y" if ($vote{$p,$groups[$i]} eq "yes");
  600. X    print "N" if ($vote{$p,$groups[$i]} eq "no");
  601. X    print "A" if ($vote{$p,$groups[$i]} eq "abs");
  602. X    }
  603. X    print "\t\t$p";
  604. X}
  605. X
  606. X
  607. X
  608. X
  609. END_OF_FILE
  610.   if test 3279 -ne `wc -c <'multi/official'`; then
  611.     echo shar: \"'multi/official'\" unpacked with wrong size!
  612.   fi
  613.   # end of 'multi/official'
  614. fi
  615. if test -f 'multi/perlsu.c' -a "${1}" != "-c" ; then 
  616.   echo shar: Will not clobber existing file \"'multi/perlsu.c'\"
  617. else
  618.   echo shar: Extracting \"'multi/perlsu.c'\" \(392 characters\)
  619.   sed "s/^X//" >'multi/perlsu.c' <<'END_OF_FILE'
  620. X/*
  621. X * PERLSU.C - SetUid wrapper for PERL
  622. X */
  623. X#include <malloc.h>
  624. X/*
  625. X * Here is the working directory. Should be defined on the command line
  626. X */
  627. X#ifndef PWD
  628. X#define PWD "./"
  629. X#endif
  630. X
  631. Xmain(argc,argv,envp) int argc; char *argv[]; char *envp[]; {
  632. X  
  633. X  char *buf;
  634. X
  635. X  buf = malloc(sizeof(argv[0]) + 100);
  636. X  strcpy(buf,PWD);
  637. X  strcat(buf,argv[0]);
  638. X  strcat(buf,".pl");
  639. X  execve(buf,argv,envp);
  640. X}
  641. X
  642. X  
  643. END_OF_FILE
  644.   if test 392 -ne `wc -c <'multi/perlsu.c'`; then
  645.     echo shar: \"'multi/perlsu.c'\" unpacked with wrong size!
  646.   fi
  647.   # end of 'multi/perlsu.c'
  648. fi
  649. if test -f 'multi/refused' -a "${1}" != "-c" ; then 
  650.   echo shar: Will not clobber existing file \"'multi/refused'\"
  651. else
  652.   echo shar: Extracting \"'multi/refused'\" \(336 characters\)
  653.   sed "s/^X//" >'multi/refused' <<'END_OF_FILE'
  654. X[This is a recording...]
  655. X
  656. XYour vote for soc.personals.ads.{group} has been refused by the automatic 
  657. Xvoting software for the reasons listed below. If you are just 
  658. Xsending mail about the CFV to me, rest assured I will get it and 
  659. Xignore this message. Otherwise, you may want to resend your vote 
  660. Xaccording to the guidelines in the CFV.
  661. END_OF_FILE
  662.   if test 336 -ne `wc -c <'multi/refused'`; then
  663.     echo shar: \"'multi/refused'\" unpacked with wrong size!
  664.   fi
  665.   # end of 'multi/refused'
  666. fi
  667. if test ! -d 'single' ; then
  668.     echo shar: Creating directory \"'single'\"
  669.     mkdir 'single'
  670. fi
  671. if test -f 'single/README' -a "${1}" != "-c" ; then 
  672.   echo shar: Will not clobber existing file \"'single/README'\"
  673. else
  674.   echo shar: Extracting \"'single/README'\" \(2269 characters\)
  675.   sed "s/^X//" >'single/README' <<'END_OF_FILE'
  676. XThis is the voting software I used on comp.security.misc 
  677. XI make no guarantees or warranties...but it worked for 
  678. Xme. It is written in PERL...if you don't have that then
  679. Xyou're on your own to get it. 
  680. X
  681. X[*] OVERVIEW
  682. X
  683. XThis software is designed to sit at the end of an alias pipe
  684. Xfrom some mailer. It recieves mail messages and attempts to
  685. Xparse a reasonable vote out of them. Whether it finds a vote
  686. Xor not it sends a reply back to the voter informing him/her
  687. Xof what (if anything) it was able to do.
  688. X
  689. X[*] WHAT'S HERE
  690. X
  691. XI left it tailored for the last vote so you could see what I did
  692. Xmore clearly. Here are the files in this distribution:
  693. X
  694. Xacknowledge - The automatic acknowledgement that is sent
  695. X    a voter via email.
  696. X
  697. Xcfv.config - Most all the configuration data is in here
  698. X
  699. Xcfv_handler.pl - This is the handler for incoming mail. Look
  700. X    inside it to configure it for the path name of the 
  701. X    above file. 
  702. X
  703. Xofficial - Used to do an official tally of votes.  
  704. X
  705. Xrefused - Sent to voter when a vote is refused for some reason
  706. X
  707. X[*] CONFIGURATION
  708. X
  709. XEdit the cfv_handler.pl file to suit your needs. Everything is 
  710. Xself explanatory. You'll probably find that the current patterns
  711. Xare ok, feel free to add more according to your needs.
  712. X
  713. X[*] INSTALLATION
  714. X
  715. XSince (for some reason - if you find out please let ME know) 
  716. Xsendmail aliases can be almost any uid, a setuid program is needed
  717. Xto avoid making the vote data world writable. The "makeme" script
  718. X(I *really* didn't want to use 'make') will do this in two 
  719. Xways:
  720. X
  721. X"makeme static" will only work if you have a statically linked
  722. XPERL binary  in this directory AND an "undump" for your system 
  723. Xsomewhere in your path. This is the "preferred" way to make a 
  724. Xsetuid perl program.
  725. X
  726. X"makeme" will make a C wrapper around the program. Make sure that
  727. Xif you do it this way that you don't decide to move this directory
  728. Xto somewhere else without rerunning "makeme".
  729. X
  730. XOnce that is done, a binary called "cfv_handler" should be resident
  731. Xin this directory. Next decide upon an alias for your vote and do
  732. Xthis in your /etc/aliases file:
  733. X
  734. Xvote_address: "| <your directory>/cfv_handler"
  735. X
  736. X[*] TRIVIA
  737. X
  738. XAny problems, bugs, or enhancements should be sent to dave@elxr.jpl.nasa.gov...
  739. Xas this is pretty trivial code I have no problem supporting it.
  740. X
  741. X
  742. X
  743. END_OF_FILE
  744.   if test 2269 -ne `wc -c <'single/README'`; then
  745.     echo shar: \"'single/README'\" unpacked with wrong size!
  746.   fi
  747.   # end of 'single/README'
  748. fi
  749. if test -f 'single/acknowledge' -a "${1}" != "-c" ; then 
  750.   echo shar: Will not clobber existing file \"'single/acknowledge'\"
  751. else
  752.   echo shar: Extracting \"'single/acknowledge'\" \(132 characters\)
  753.   sed "s/^X//" >'single/acknowledge' <<'END_OF_FILE'
  754. X[This is a recording...]
  755. X
  756. XYour vote on comp.security.misc has been received by my 
  757. Xautomatic voting software. Thank you for voting!
  758. END_OF_FILE
  759.   if test 132 -ne `wc -c <'single/acknowledge'`; then
  760.     echo shar: \"'single/acknowledge'\" unpacked with wrong size!
  761.   fi
  762.   # end of 'single/acknowledge'
  763. fi
  764. if test -f 'single/cfv_handler.pl' -a "${1}" != "-c" ; then 
  765.   echo shar: Will not clobber existing file \"'single/cfv_handler.pl'\"
  766. else
  767.   echo shar: Extracting \"'single/cfv_handler.pl'\" \(7107 characters\)
  768.   sed "s/^X//" >'single/cfv_handler.pl' <<'END_OF_FILE'
  769. X#!/usr/bin/perl
  770. X#
  771. X# CFV_HANDLER - Handle a CFV from usenet. Expects candidate messages on STDIN.
  772. X# 
  773. X# Copyright (c) 1991 by    Dave Hayes - dave@elxr.jpl.nasa.gov
  774. X#
  775. X# All rights reserved.
  776. X#
  777. X# Permission is given to distribute these sources, as long as the
  778. X# copyright messages are not removed, and no monies are exchanged.
  779. X#
  780. X#######################CONFIGURE HERE
  781. X#
  782. X# Pathname of working directory (all files relative to here)
  783. X$cfv_dir="/home/dave/news/cfv/sec";    
  784. X#
  785. X# Group you are running a vote for
  786. X$group = "comp.security.misc";
  787. X#
  788. X# Pathnames of some files (shouldn't need to change these)
  789. X$mass_ack   = "$cfv_dir/mass_acknowledge"; # Where the currently voted people go
  790. X$votes      = "$cfv_dir/votes";              # Where the votes go
  791. X$single_ack = "$cfv_dir/acknowledge";       # Canned vote acknowledgement 
  792. X$refused    = "$cfv_dir/refused";          # Canned vote refusal
  793. X# 
  794. X# Other things
  795. X$start_date = "4/13/92 06:00";               # Voting starts 
  796. X$end_date   = "5/13/92 18:00";             # Voting ends
  797. X$moderator  = "dave@elxr";                 # Who to send errors to
  798. X$backup_err = "$cfv_dir/errors";           # Where to send errors to if above fails
  799. X#
  800. X# Regexp definitions.
  801. X# The software looks for a match such that one of the below regexps
  802. Xpreceeds one of the
  803. X# above newsgroups. Note the "\\" used to denote a "\", thus a PERL token of "\n"
  804. X# should be written as "\\n" below.
  805. X#
  806. X# Valid YES vote substrings
  807. X@yesvotes = (
  808. X         "yes.*$group",
  809. X         "in.*favo[ur].*$group"
  810. X);
  811. X#
  812. X# Valid NO vote regexps
  813. X@novotes = (
  814. X        "no.*$group",
  815. X        "against.*$group"
  816. X);
  817. X#
  818. X#####################END OF CONFIGURATION STUFF!
  819. X#
  820. X$debug = 0;     # Use this if you want verbosity on ERRLOG
  821. X#
  822. X# This may be a faster way to read messages. With MailMan I didn't
  823. X# care if the message was in an array. Here I do cause I'm searching the
  824. X# body.
  825. X# Thanks to goehring@mentor.cc.purdue.edu (Scott Goehring)
  826. X$* = 1;
  827. X$save = $/; undef $/; $message = <STDIN>; $/ = $save;
  828. Xstudy $message;
  829. X($from) = $message =~ /^From: (.+)$/;
  830. X($subject) = $message =~ /^Subject: (.+)$/;
  831. X$subject =~ tr/A-Z/a-z/;
  832. X&maildebug("Message from '$from' with subject '$subject'");
  833. X#
  834. X# Check that we have a valid subject
  835. Xforeach $sub (@subjects) {
  836. X    $found = 1 if ($subject =~ /$sub/i);
  837. X}
  838. Xif (!defined($found)) {
  839. X    &mailwarn("Invalid subject. (@subjects) Message follows:");
  840. X    print ERRLOG $message;
  841. X    &maildie("EOT.",0);
  842. X}
  843. X#
  844. X# Check the date now. Must be within bounds
  845. X($smon,$sday,$syr,$shr,$smin) = split(/[\s\:\/]/,$start_date);
  846. X($emon,$eday,$eyr,$ehr,$emin) = split(/[\s\:\/]/,$end_date);
  847. X($x1,$cmin,$chr,$cday,$cmon,$cyr,$x2,$x3,$x4) = (localtime);
  848. X$s = &numdate($syr,$smon,$sday,$shr,$smin);
  849. X$e = &numdate($eyr,$emon,$eday,$ehr,$emin);
  850. X$c = &numdate($cyr,$cmon+1,$cday,$chr,$cmin);
  851. Xif ($s > $c || $c > $e) {
  852. X    &mailwarn("Invalid date to vote. Message follows:");
  853. X    print ERRLOG $message;
  854. X    open(ACK,"<$refused") || &mailwarn("Couldn't open '$refused': out
  855. Xof date vote from '$from': $!"); 
  856. X    open(MAIL,"|/usr/lib/sendmail -t") || &mailwarn("Couldn't pipe to
  857. Xmail: out of date vote from '$from'"); 
  858. X    print MAIL <<EOT;
  859. XFrom: $moderator
  860. XTo: $from
  861. XSubject: Error in your vote
  862. XEOT
  863. X    print MAIL <ACK>;
  864. X    print MAIL "\nYour vote is not with in the date bounds
  865. X'$start_date' and '$end_date'.\n";
  866. X    close(MAIL);
  867. X    &maildie("EOT.",0);
  868. X}
  869. X
  870. X#
  871. X# Now check for a valid vote.
  872. Xforeach $yv (@yesvotes) {
  873. X    if ($message =~ /$yv/i) {
  874. X    #
  875. X    # A YES vote
  876. X    #
  877. X    open(MASS,">>$mass_ack") || &mailwarn("Couldn't open
  878. X'$mass_ack': YES vote from '$from' : ($<,$>) $!");
  879. X     print MASS "$from\n";
  880. X    close(MASS);
  881. X    open(VOTES,">>$votes") || &mailwarn("Couldn't open '$votes':
  882. XYES vote from '$from' : ($<,$>) $!");
  883. X    print VOTES "[Y] $from\n";
  884. X    close(VOTES);
  885. X    open(ACK,"<$single_ack") || &mailwarn("Couldn't open
  886. X'$single_ack': YES vote from '$from': $!"); 
  887. X    open(MAIL,"|/usr/lib/sendmail -t") || &mailwarn("Couldn't pipe
  888. Xto mail: out of date vote from '$from'"); 
  889. X    print MAIL <<EOT;
  890. XFrom: $moderator
  891. XTo: $from
  892. XSubject: Your vote
  893. XEOT
  894. X    print MAIL <ACK>;
  895. X    print MAIL "\nYour YES vote was recorded successfully.\n";
  896. X    close(MAIL); close(ACK);
  897. X    &maildie("",0);
  898. X    }
  899. X}
  900. Xforeach $nv (@novotes) {
  901. X    if ($message =~ /$nv/i) {
  902. X    #
  903. X    # A NO vote
  904. X    #
  905. X    open(MASS,">>$mass_ack") || &mailwarn("Couldn't open
  906. X'$mass_ack': NO vote from '$from' : $!");
  907. X    print MASS "$from\n";
  908. X    close(MASS);
  909. X    open(VOTES,">>$votes") || &mailwarn("Couldn't open '$votes': NO
  910. Xvote from '$from' : $! ");
  911. X    print VOTES "[N] $from\n";
  912. X    close(VOTES);
  913. X    open(ACK,"<$single_ack") || &mailwarn("Couldn't open
  914. X'$single_ack': NO vote from '$from' : $!"); 
  915. X    open(MAIL,"|/usr/lib/sendmail -t") || &mailwarn("Couldn't pipe
  916. Xto mail: out of date vote from '$from'"); 
  917. X    print MAIL <<EOT;
  918. XFrom: $moderator
  919. XTo: $from
  920. XSubject: Your Vote
  921. XEOT
  922. X    print MAIL <ACK>;
  923. X    print MAIL "\nYour NO vote was recorded successfully.\n";
  924. X    &maildie("",0);
  925. X    }
  926. X}
  927. X#
  928. X# If we get here this is an invalid vote
  929. Xopen(ACK,"<$refused") || &mailwarn("Couldn't open '$refused': INVALID
  930. Xvote from '$from' : $!"); 
  931. Xopen(MAIL,"|/usr/lib/sendmail -t") || &mailwarn("Couldn't pipe to
  932. Xmail: out of date vote from '$from'"); 
  933. Xprint MAIL <<EOT;
  934. XFrom: $moderator
  935. XTo: $from
  936. XSubject: Error in your vote
  937. XEOT
  938. Xprint MAIL <ACK>;
  939. Xprint MAIL "\nNo valid vote could be found in your message.\n\nValid
  940. XYES votes are of the wildcard form:\n\n";
  941. Xprint MAIL join("\n",@yesvotes);
  942. Xprint MAIL "\n\nValid NO votes are of the wildcard form:\n\n";
  943. Xprint MAIL join("\n",@novotes);
  944. Xclose(ACK); close(MAIL);
  945. X$message =~ s/^/>>>/g;
  946. X&mailwarn("Invalid vote. Message follows:\n\n$message");
  947. X&maildie("EOT",0);
  948. X
  949. X######
  950. X###### SUBROUTINES GO HERE
  951. X######
  952. Xsub mailwarn {
  953. X    local($reason) = shift(@_);
  954. X    &setup_mail if (!defined($mail_is_on));
  955. X    print ERRLOG <<EOT;
  956. XFrom: cfv_daemon
  957. XTo: $moderator
  958. XSubject: CFV daemon report
  959. X
  960. XWarning about Mail from: '$from' with subject: '$subject':
  961. XReason: $reason.
  962. XEOT
  963. X
  964. X}
  965. Xsub maillog {
  966. X    local($reason) = shift(@_);
  967. X
  968. X    &setup_mail if (!defined($mail_is_on));
  969. X    print ERRLOG <<EOT;
  970. XFrom: cfv_daemon
  971. XTo: $moderator
  972. XSubject: CFV daemon report
  973. X
  974. XMail from: '$from' with subject: '$subject' logged:
  975. XReason: $reason.
  976. XEOT
  977. X    close(ERRLOG);
  978. X}
  979. Xsub maildebug {
  980. X    local($reason) = shift(@_);
  981. X    
  982. X    return 0 if (!$debug);
  983. X    &setup_mail if (!defined($mail_is_on));
  984. X    print ERRLOG <<EOT;
  985. XFrom: cfv_daemon
  986. XTo: $moderator
  987. XSubject: CFV daemon report
  988. X
  989. XDebug Mail from: '$from' with subject: '$subject':
  990. XReason: $reason.
  991. XEOT
  992. X}
  993. X
  994. Xsub maildie {    
  995. X    local($reason) = shift(@_);
  996. X    local($exitcode) = shift(@_);
  997. X
  998. X    exit 0 if ($exitcode == 0);
  999. X    &setup_mail if (!defined($mail_is_on));
  1000. X    print ERRLOG <<EOT;
  1001. XFrom: cfv_daemon
  1002. XTo: $moderator
  1003. XSubject: CFV daemon report
  1004. X
  1005. XMail from: '$from' with subject: '$subject' failed:
  1006. XReason: $reason.
  1007. XEOT
  1008. X    close(ERRLOG);
  1009. X    exit $exitcode;
  1010. X}
  1011. X
  1012. Xsub numdate {
  1013. X    local($y,$m,$d,$mn,$h) = @_;
  1014. X    local($n);
  1015. X
  1016. X    $n = $h + (100*$mn) + (10000*$d) + (1000000*$m) + ($y * 100000000);
  1017. X    &maildebug("Converted ($y,$m,$d,$mn,$h) to $n");
  1018. X    return $n;
  1019. X}
  1020. X    
  1021. Xsub setup_mail {
  1022. X    $mail_is_on = 1;
  1023. X    if (!open(ERRLOG,"| /usr/lib/sendmail -t")) {
  1024. X    open(ERRLOG,">>$backup_err") || warn "Augh! Can't redirect
  1025. XERRLOG to someplace useful!\n";
  1026. X   }
  1027. X    select(ERRLOG); $| = 1; 
  1028. X}
  1029. END_OF_FILE
  1030.   if test 7107 -ne `wc -c <'single/cfv_handler.pl'`; then
  1031.     echo shar: \"'single/cfv_handler.pl'\" unpacked with wrong size!
  1032.   fi
  1033.   # end of 'single/cfv_handler.pl'
  1034. fi
  1035. if test -f 'single/makeme' -a "${1}" != "-c" ; then 
  1036.   echo shar: Will not clobber existing file \"'single/makeme'\"
  1037. else
  1038.   echo shar: Extracting \"'single/makeme'\" \(214 characters\)
  1039.   sed "s/^X//" >'single/makeme' <<'END_OF_FILE'
  1040. X#!/bin/csh 
  1041. Xif ("$1" == "static") then
  1042. X    ./perl -u cfv_handler
  1043. X    undump cfv_handler perl core
  1044. X    chmod 4755 cfv_handler
  1045. Xelse
  1046. X    setenv PWD `pwd`
  1047. X    cc -o cfv_handler perlsu.c -DPWD=\"$PWD/\"
  1048. X    chmod 4755 cfv_handler
  1049. Xendif
  1050. X
  1051. END_OF_FILE
  1052.   if test 214 -ne `wc -c <'single/makeme'`; then
  1053.     echo shar: \"'single/makeme'\" unpacked with wrong size!
  1054.   fi
  1055.   # end of 'single/makeme'
  1056. fi
  1057. if test -f 'single/official' -a "${1}" != "-c" ; then 
  1058.   echo shar: Will not clobber existing file \"'single/official'\"
  1059. else
  1060.   echo shar: Extracting \"'single/official'\" \(2473 characters\)
  1061.   sed "s/^X//" >'single/official' <<'END_OF_FILE'
  1062. X#!/usr/bin/perl
  1063. X# 
  1064. X#    OFFICIAL - official status of CFV
  1065. X#            and deal with duplicates properly
  1066. X#
  1067. Xdie "usage: official [-l|-f|-d]
  1068. X\twhere -l does last vote priority
  1069. X\t      -f does first vote priority
  1070. X\t      -d discards duplicates\n" if (!defined($ARGV[0]));
  1071. X#
  1072. X# Raw, time-ordered, data
  1073. X#
  1074. X@votes = `cat votes`;
  1075. X#
  1076. X# This builds an associative array that has cleaned data
  1077. X#
  1078. X$y =0; $n = 0;
  1079. Xfor ($i=0; $i<=$#votes; $i++) {
  1080. X    if ($votes[$i] =~ /^\[([YN])\]\s+(.*)/) {
  1081. X    $p = "$2\n";
  1082. X    $v = $1;
  1083. X    } else {
  1084. X    print "Bad syntax in vote: <$votes[$i]>\n";
  1085. X    next;
  1086. X    } 
  1087. X    if (!defined($vote{$p})) {
  1088. X    if ($v eq "Y") {
  1089. X        $vote{$p} = "yes";
  1090. X        $y++;
  1091. X    } elsif ($v eq "N") {
  1092. X        $vote{$p} = "no";
  1093. X        $n++;
  1094. X    } else { 
  1095. X        print "Bad vote: <$votes[$i]>\n";
  1096. X    }
  1097. X    next;
  1098. X    }
  1099. X    $first{$p} = $vote{$p} if (!defined($first{$p}));
  1100. X    if ($v eq "Y") {
  1101. X    $last{$p} = "yes";
  1102. X    $y++;
  1103. X    } elsif ($v eq "N") {
  1104. X    $last{$p} = "no";
  1105. X    $n++;
  1106. X    } else { 
  1107. X    print "Bad vote: <$votes[$i]>\n";
  1108. X    }
  1109. X    $vote{$p} = "dup";
  1110. X}
  1111. X#
  1112. X# Filter the array appropriately
  1113. X#
  1114. X@tmass = keys(%vote);
  1115. X@tyes  = grep($vote{$_} eq "yes",@tmass);
  1116. X@tno   = grep($vote{$_} eq "no",@tmass);
  1117. X@tdups = grep($vote{$_} eq "dup",@tmass);
  1118. X#
  1119. X# Now deal with duplicates. 
  1120. X#
  1121. Xif ($ARGV[0] eq "-l") {
  1122. X    $method = "Last vote taken as valid";
  1123. X    foreach $person (@tdups) {
  1124. X    push(@tyes,$person) if ($last{$person} eq "yes");
  1125. X    push(@tno,$person) if ($last{$person} eq "no");
  1126. X    }
  1127. X} elsif ($ARGV[0] eq "-f") {
  1128. X    $method = "First vote taken as valid";
  1129. X    foreach $person (@tdups) {
  1130. X    push(@tyes,$person) if ($first{$person} eq "yes");
  1131. X    push(@tno,$person) if ($first{$person} eq "no");
  1132. X    }
  1133. X} elsif ($ARGV[0] eq "-d") {
  1134. X    $method = "Duplicates discarded";
  1135. X} else {
  1136. X    die "Illegal argument: $ARGV[0]\n";
  1137. X}
  1138. X#
  1139. X# Tally ho!
  1140. X#
  1141. X$tyes = $#tyes + 1;
  1142. X$tno  = $#tno + 1;
  1143. X$tmass = $#tmass + 1;
  1144. X$tdups =  $#tdups + 1;
  1145. X$tmass -= $tdups if ($ARGV[0] eq "-d" && $tdups > 0);
  1146. X$pyes = $tyes/$tmass * 100; $pyes = sprintf("%02.2f",$pyes);
  1147. X$pno  = $tno/$tmass * 100;  $pno  = sprintf("%02.2f",$pno);
  1148. X$pct  = $tyes + $tno;
  1149. X$pdiff = $tyes - $tno;
  1150. X
  1151. Xprint "
  1152. X[DAVE'S AUTOMATIC USENET CFV HANDLER]
  1153. X
  1154. XTotal  Votes: $tmass\t
  1155. XYes    Votes: $tyes\t($pyes%)
  1156. XNo     Votes: $tno\t($pno%)
  1157. XYes-No Votes: $pdiff
  1158. X
  1159. XDuplicates:   $tdups 
  1160. XDuplicate Resolution: $method\n\n";
  1161. X
  1162. Xif ($ARGV[0] eq "-d" && $tdups > 0) {
  1163. X    print "DUPLICATES:\n"; print @tdups; print "\n\n";
  1164. X}
  1165. X
  1166. Xprint "YES VOTES:\n"; print (sort @tyes);
  1167. Xprint "\n\nNO VOTES:\n"; print (sort @tno);
  1168. X
  1169. X
  1170. X
  1171. END_OF_FILE
  1172.   if test 2473 -ne `wc -c <'single/official'`; then
  1173.     echo shar: \"'single/official'\" unpacked with wrong size!
  1174.   fi
  1175.   # end of 'single/official'
  1176. fi
  1177. if test -f 'single/perlsu.c' -a "${1}" != "-c" ; then 
  1178.   echo shar: Will not clobber existing file \"'single/perlsu.c'\"
  1179. else
  1180.   echo shar: Extracting \"'single/perlsu.c'\" \(392 characters\)
  1181.   sed "s/^X//" >'single/perlsu.c' <<'END_OF_FILE'
  1182. X/*
  1183. X * PERLSU.C - SetUid wrapper for PERL
  1184. X */
  1185. X#include <malloc.h>
  1186. X/*
  1187. X * Here is the working directory. Should be defined on the command line
  1188. X */
  1189. X#ifndef PWD
  1190. X#define PWD "./"
  1191. X#endif
  1192. X
  1193. Xmain(argc,argv,envp) int argc; char *argv[]; char *envp[]; {
  1194. X  
  1195. X  char *buf;
  1196. X
  1197. X  buf = malloc(sizeof(argv[0]) + 100);
  1198. X  strcpy(buf,PWD);
  1199. X  strcat(buf,argv[0]);
  1200. X  strcat(buf,".pl");
  1201. X  execve(buf,argv,envp);
  1202. X}
  1203. X
  1204. X  
  1205. END_OF_FILE
  1206.   if test 392 -ne `wc -c <'single/perlsu.c'`; then
  1207.     echo shar: \"'single/perlsu.c'\" unpacked with wrong size!
  1208.   fi
  1209.   # end of 'single/perlsu.c'
  1210. fi
  1211. if test -f 'single/refused' -a "${1}" != "-c" ; then 
  1212.   echo shar: Will not clobber existing file \"'single/refused'\"
  1213. else
  1214.   echo shar: Extracting \"'single/refused'\" \(234 characters\)
  1215.   sed "s/^X//" >'single/refused' <<'END_OF_FILE'
  1216. X[This is a recording...]
  1217. X
  1218. XYour vote for comp.security.misc has been refused by the automatic 
  1219. Xvoting software for the reasons listed below. 
  1220. X
  1221. XYou may want to resend your vote according to the guidelines in the CFV,
  1222. Xor send me a text 
  1223. END_OF_FILE
  1224.   if test 234 -ne `wc -c <'single/refused'`; then
  1225.     echo shar: \"'single/refused'\" unpacked with wrong size!
  1226.   fi
  1227.   # end of 'single/refused'
  1228. fi
  1229. echo shar: End of archive 1 \(of 1\).
  1230. cp /dev/null ark1isdone
  1231. MISSING=""
  1232. for I in 1 ; do
  1233.     if test ! -f ark${I}isdone ; then
  1234.     MISSING="${MISSING} ${I}"
  1235.     fi
  1236. done
  1237. if test "${MISSING}" = "" ; then
  1238.     echo You have the archive.
  1239.     rm -f ark[1-9]isdone
  1240. else
  1241.     echo You still must unpack the following archives:
  1242.     echo "        " ${MISSING}
  1243. fi
  1244. exit 0
  1245. exit 0 # Just in case...
  1246.