Content-type: text/html
Sede is primarily a program for `vote administrators', but is also useful for voters to verify the integrity of the results. This program does not rely on trust on the part of voters, voters are presented extensive data to verify and (automatically) re-count. It offers voters a free vote (voters can but do not need to choose one of a limited set of options) and free comment space, providing power to voters and measuring their opinion with more accuracy. Voters can also organize their own votes from within the comment-space, as long as the vote-administration does not alter its content.
Method: Each vote contains three elements: a vote-code, a vote-field, and a comment-field. The vote-code is a string of numbers and letters. The vote-field is where the voter places his/her option of choice. The comment-field is where the voter can place a comment.
Vote-code: If a returned ballot contains a vote with a to the vote-code-database corresponding vote-code in it, this vote will be marked as being a valid vote; as opposed to sending back a vote with a fantasy vote-code, which will be marked as an invalid vote.
Vote: The vote is a field in the ballot, where voters can write their vote, like in a form. The vote can be one of suggested options, or it can be creative input from the voter. All valid votes will be counted, whether they conform to suggested options or not.
Comment: This is a second field belonging to a vote, but its content will not be counted with other comments. The voters can use this space to make their vote even more unique and recognizable for themselves. The voters can also use the comment space to communicate whatever they wish to communicate.
The votes, containing these three elements, will have their vote-fields added together. The count and the votes themselves will be made public, a website is generated for this purpose. If voters remember their vote-code, they can use it to check that their vote was correctly processed. Voters can re-add the published votes again, to check this was correctly done. Besides these lists, more lists and more types of additions are being published, to give voters an as complete as possible overview of what has taken place.
User interface: Sede is a program which operates on data stored in several directories. These operations are named commands, which can be given as an argument to the sede shell wrapper in ${PATH}, or be accessed interactively from a specialized prompt (run sede without arguments). Voters do not need to install or use this program.
Ballots can be encrypted, configurable on a per voter basis, using generally available command line programs.
Sede gives each registered person a random vote-code per "poll/referendum", then sends (emails) each voter their ballot containing this (these) vote-code(s). After receiving the returned and filled-out ballots, processes them into result lists, which can then be published. In these published results each individual vote with their vote-code is present for verification by the voters, as are any attacks.
Voters do not have to install any special software to be able to vote (just an email client). Sede is a program for the administrators of the voting process, and can optionally be used by voters.
The way the persons are decided to be registered is left undefined, registrations minimally require a routing channel for the ballot. If registrations are taken in an anonymous way, the vote becomes anonymous to the vote administration as well.
Typical usage
> sede pollsconf c_template
> sede pollsconf c_pnames
(edit a new ballot)
> sede makes
(create ballots)
> sede sendallmail
(mail all ballots to voters)
> sede processall
(process all returned ballots)
Results can then be published.
The routing channel of the ballots does not need to be (all) email, it is possible to use sede as a back-end and handle voter-interfacing (on a per voter basis) differently.
New users are encouraged to start with one of the pre-configured example polls (_essence or _basic are a good start), and change the setup to their needs. There are a lot of things that can be configured, starting with a working setup will only make things easier. The one file to change for sure is: ${SEDE_ROOT_IN}/c_voters, the voters registration.
The program basically works like this: 4 data directories and 1 storage directory for inactive polls. A poll always starts in directory ${SEDE_ROOT_IN}/ (_IN as in "INput"), all the other data directories are empty at this point. Configuration files (names start with c_), master ballot, voter registration, it is all there, in ${SEDE_ROOT_IN}/.
Once this has been setup (voters are registered, master ballot is written, configuration is as desired), the second directory ${SEDE_ROOT_OUT}/ (_OUT as in "OUTput") can be filled (run `makes`) with actual ballots, the vote-code databases etc. This becomes an actual implementation of the poll configured in ${SEDE_ROOT_IN}/. By removing all this machine created data in ${SEDE_ROOT_OUT}/, and re-running the ballot creation command (`makes`), a new instance of the poll is created in ${SEDE_ROOT_OUT}/, with different vote-codes, but otherwise equal to the first. You might need to do this a couple of times (with a truncated voter registration file ${SEDE_ROOT_IN}/c_voters perhaps), if you have made programming errors in ${SEDE_ROOT_IN}/. Stepping modes for ballot creation are available, to help you track down bugs. A simple ballot can hardly contain bugs though.
Now the ballots can be routed toward voters (run `sendallmail`). Once voters have returned their ballots, these returns must be stored in the third data directory ${SEDE_ROOT_VIN}/ ("Voters INput"). It does not matter in what files they are stored, as long as it is in this directory. After this, on the basis of configuration in ${SEDE_ROOT_IN}/, the results can be processed by running `processall`: adding votes, weeding out false votes, etc. The results of this processing - you guessed it - are automatically put in the last data directory ${SEDE_ROOT_VOUT}/ ("Voters OUTput"). Again, by re-running the command `processall`, the generated data in ${SEDE_ROOT_VOUT}/ is simply re-created on the basis of data in ${SEDE_ROOT_IN}/ (configuration) and ${SEDE_ROOT_OUT}/ (databases) and ${SEDE_ROOT_VIN} (voter input).
In order to prevent unpleasant mistakes this far in the voting process, it is probably a good idea to test-run the returned ballots processing. For this, don't send ballots to voters, but simply copy them into ${SEDE_ROOT_VIN}/ (see `cps`). The program doesn't know this, it assumes the returns are from voters (actually, it has no opinion about this one way or the other). You may wish to edit some ballots in ${SEDE_ROOT_VIN}/ to make it more interesting. Then run `processall', and open up ${SEDE_ROOT_VOUT}/ in a web browser. You can also do this an infinite amount of times, until all issues, if any, are resolved.
${SEDE_ROOT_VINREAD}/ is a directory for a special need: while votes are being processed into result lists for publishing, if so configured, ${SEDE_ROOT_VINREAD}/ can be made to contain all the returned data in ${SEDE_ROOT_VIN}/, except the votes. This may be useful to inspect "the voter input remainder", without having to see the votes. Can also be useful to more easily find (grep) garbled votes that were rejected.
The vote is a section of "magic text" inside the text ballot. You can configure this "magic" (see ${SEDE_ROOT_IN}/c_findvote, ${SEDE_ROOT_IN}/c_findcode and ${SEDE_ROOT_IN}/c_find_votearea). The ballot can contain any number of such vote-areas. Each question on the ballot typically has a unique name, defined in ${SEDE_ROOT_IN}/c_pnames. The master ballot consists of text, into which the "magic text" areas are written, but which does (obviously) not contain any specific vote-codes, because these are different for each voter. In the master-ballot, a number of variables can be expanded (see the master ballot: ${SEDE_ROOT_IN}/c_template). One such variable will expand into the vote-code for any specific voter.
Sede has a lot of features. Among which are email attachment encryption (see the sede_divide_run flag for encryption, and rundir for decryption). The ballots are created from the master/source ballot, by expanding variables on it. After one time expanding variables, it can do it again and again. If-Then-Else on voter data is possible (see ^-ifelse), as is command expansion (see ^-execute), file inclusion (see ^-file) and other things. To avoid clashing with `$', used by many shell languages, the otherwise little used `^' character initiates active text in the master ballot (`^^' is literal `^'). Short (`^?') and long (`^-...') versions of variables are present (`^-' is the short variable which initiates a long variable name, to be precise).
As an exception, addmore uses a file in the input directory: ${SEDE_ROOT_IN}/c_voters.addmore_save, to save the original (and final) ${SEDE_ROOT_IN}/c_voters temporarily.
See also sendlastmail and addvoter.
With argument `givename' runs `givename cutname' on previously givename formatted results, and `givename' on raw results, after applying the changes. This brings HTML formatted result files back in sync. Running `addvote_compact' without argument makes it possible to first inspect the changed result-files, before putting the changes under the primary HTML links in the results.
See `${SEDE_ROOT_IN}/c_compact' for more details.
Usage is almost the same as for makes (see above), but instead of making a new batch of ballots/records etc, it adds a ballot and records (etc) for one additional voter, whose registration has been appended to ${SEDE_ROOT_IN}/c_voters. If zero generated ballots are found, makes is called regardless of the number of voters in the voter registration file. When makes is called, the arguments test and one of the *step arguments are passed on to makes.
The argument fake generates a "wild" ballot under ${SEDE_ROOT_TMP}/fake.ballot. This ballot is created with as voter registration data `fake,field-2,field-3,field-4,...,field-50'. Creating it doesn't affect any other files (except those in ${SEDE_ROOT_TMP}). The argument faken N creates a "wild" ballot for voter number N (the voter registered on line N of ${SEDE_ROOT_IN}/c_voters), the votercodes are purely random and useless, but the ballot should look similar (unless you were doing an if-then-else on vote codes :-) ). This ballot gets stored under ${SEDE_ROOT_TMP}/fake.ballot_N. N has to follow immediately on the faken argument.
See also sendlastmail and addmore.
Shortcut: `a'.
VOTECODELENGTH is the length of the vote code to be used, default 10.
PASSES is the number of passes it runs over the ${SEDE_ROOT_IN}/c_template, default 1.
CODE_UNIQUENESS signals vote code uniqueness (bitmask):
`0' per poll case sensitive unique
`1' all vote codes case insensitive unique
`2' per poll case sensitive unique,
`3' is all vote codes case insensitive unique.
STEPPING defines stepping:
`0' is no stepping,
`1' is per ballot stepping,
`2' is per pass stepping,
`3' is per line stepping,
`4' is per character stepping,
`5' is per line stepping with echo-mode on,
`6' is per character stepping with echo-mode on,
`7' is per character stepping with echo-mode on and jumping to the
first occurence of `^'.
`:BALLOT:PASS:LINE:CHARACTER'
is start stepping as if `^-step' had been encountered on the given
coordinates (ballot BALLOT, pass PASS, line LINE, and
character CHARACTER).
CHARACTER value `0' is magic and stands for the end of line.
TEMPLATE_FILE is the template ballot file used, default ${SEDE_ROOT_IN}/c_template.
VOTERS_FILE is the voters registration file used, default ${SEDE_ROOT_IN}/c_voters.
SERIALSTART makes sede start from another serial number for the first ballot other then default 1.
CODEMODE defines how the template ballot code in ${SEDE_ROOT_IN}/c_template is treated during the first
pass:
`0' means: all plain text outside variables is copied into the next
pass and/or the end ballot.
`1' means: all plain text outside variables is ignored during the first
pass (so you can indent and comment your template ballot code).
PASSWD_LENGTH defines the length of the password, default 9.
ballots ignores all ${SEDE_ROOT_IN}/c_* configuration files. This command is called in appropriate ways by the makes command, normally you should never need to operate it. See below at RETURN VALUES for the return values of the ballots command.
shortcut: `e'.
shortcut: `f'.
This command is meant for higher level code, to have easy access to items without having to compute such things themselves.
`givename' creates three directories under ${SEDE_ROOT_VOUT}: `./c/', `./o/', `./s/'. Under `./c/' ("configuration") the configuration files are placed, excluding ${SEDE_ROOT_IN}/c_voters - the voter registration file -, but including ${SEDE_ROOT_OUT}/codespervoter - votecode records - if votes in abstention are published anyway (see ${SEDE_ROOT_IN}/c_abstention). Under `./o/' ("open") the result-files under their new names (see below), without an index file: voters get the system listing with important information like creation time and file sizes. Under `./s/' ("sede") the result-files again (hard linked) under their original hard-coded names (for a remote sede to recognize). The directory ${SEDE_ROOT_VOUT} contains the HTML-link documents, and the graphics-theme chosen for those HTML-link documents.
Renaming result files: `givename' renames result files in
${SEDE_ROOT_VOUT} with the name of the poll (as described in
${SEDE_ROOT_IN}/c_pnames) into the filename before a dash
`-', and a ~/.sederc defined element for that file after
that dash. The ~/.sederc variables defining the second filename
element are:
${SEDE_INDEX_BROWSE} for ${SEDE_ROOT_VOUT}/browseN,
${SEDE_INDEX_COMPACT} for ${SEDE_ROOT_VOUT}/compactN,
${SEDE_INDEX_DOUBLE_VOTES} for ${SEDE_ROOT_VOUT}/doublevotesN,
${SEDE_INDEX_EXPLAIN} for ${SEDE_ROOT_VOUT}/c_explainN,
${SEDE_INDEX_INVALID_VOTES} for ${SEDE_ROOT_VOUT}/invalid_votesN,
${SEDE_INDEX_NOT_VOTED_CODES} for ${SEDE_ROOT_VOUT}/notvotedcodesN,
${SEDE_INDEX_PERVOTER} for ${SEDE_ROOT_VOUT}/pervoter,
${SEDE_INDEX_RESULT} for ${SEDE_ROOT_VOUT}/resultN,
${SEDE_INDEX_VOTERS} for ${SEDE_ROOT_VOUT}/votersN,
${SEDE_INDEX_VOTES} for ${SEDE_ROOT_VOUT}/votesN,
${SEDE_INDEX_VOTING_PATTERNS} for ${SEDE_ROOT_VOUT}/votingpatterns,
${SEDE_INDEX_WEIGHTED_COMPACT} for ${SEDE_ROOT_VOUT}/weighted_compactN,
${SEDE_INDEX_WEIGHTED_RESULT} for ${SEDE_ROOT_VOUT}/weighted_resultN,
Example: the file
${SEDE_ROOT_VOUT}/votes3, containing the votes for poll number
3, would become: ${SEDE_ROOT_VOUT}/$( head -3 ${SEDE_ROOT_IN}/c_pnames | tail -1 )-${SEDE_INDEX_VOTES},
which might be ${SEDE_ROOT_VOUT}/TeaOrCoffee-TheVotes, if
the poll-name is "TeaOrCoffee" (line 3 of
${SEDE_ROOT_IN}/c_pnames), and
${SEDE_INDEX_VOTES} is "TheVotes" (variable defined in
~/.sederc).
`givename' generates `${SEDE_ROOT_VOUT}/defvote', containing only the search-patterns needed to re-count votes in an identifier="CONTENT" format.
Generating HTML: givename generates ${SEDE_ROOT_VOUT}/${SEDE_INDEX}: providing HTML link access to the result files and ${SEDE_ROOT_VOUT}/setup.html: providing HTML link access to the copied poll configuration files in ${SEDE_ROOT_VOUT}/c/. The following rules apply to this HTML generating process:
- All links point into `./', which is ${SEDE_ROOT_VOUT}.
- Only result files that are present in ${SEDE_ROOT_VOUT} when `givename' is running will be mentioned in ${SEDE_ROOT_VOUT}/${SEDE_INDEX}.
- If ${SEDE_ROOT_IN}/c_explainPOLL-NUMBER files are present, the heading above each consecutive poll chapter within ${SEDE_ROOT_VOUT}/${SEDE_INDEX} will itself be a link to a copy of ${SEDE_ROOT_IN}/c_explainPOLL-NUMBER in ${SEDE_ROOT_VOUT}. The ${SEDE_ROOT_IN}/c_explainPOLL-NUMBER files will be copied toward a ${SEDE_ROOT_VOUT}/POLLNAME-${SEDE_INDEX_EXPLAIN} name (see also above ${SEDE_INDEX_EXPLAIN}). This gives voters a chance to read what the vote was about (see ${SEDE_ROOT_IN}/c_explainPOLL_NUMBER).
- If a result file contains no data, a notice (not as a link, as normal text) will be put into ${SEDE_ROOT_VOUT}/${SEDE_INDEX}. This notice contains the ${SEDE_INDEX_...} filename part, with the content of ${SEDE_INDEX_NONE} following it immediately (see ~/.sederc). These notices are collected at the end of each poll chapter within ${SEDE_ROOT_VOUT}/${SEDE_INDEX}.
- ${SEDE_INDEX_UNWEIGHTED} is used as a signal that an addition is a simple addition of votes, ignoring the optional weight element of a vote. (See ~/.sederc).
- The first line of ${SEDE_ROOT_IN}/c_theme specifies
the icons theme used:
* If the first line is
empty, then there are no icon links (<img src=...>)
included in
${SEDE_ROOT_VOUT}/${SEDE_INDEX} or
${SEDE_ROOT_VOUT}/setup.html.
* If not empty, the first line is subjected to shell variable expansion
within a sede environment. Example: a first line containing
`${SEDE_LIB}/extras/icons.flower.tar.gz' might be expanded
into `/usr/local/lib/sede/extras/icons.flower.tar.gz',
`${SEDE_ROOT_IN}/icons.flower.tar.gz' into
`/home/me/.sede/in/icons.flower.tar.gz', and
~/archive.tar.gz into /home/me/archive.tar.gz. Environment
variables are also expanded.
* The following icon-archives are (by default in
${SEDE_LIB}/extras/) available to provide
the graphics. Some icon archives contain
small icons, others may be very large and perhaps use up significant
bandwidth (sizes excluding background images):
* icons.null.tar.gz (4k bytes; small);
* icons.color.tar.gz (7k bytes; colored beams);
* icons.blocks.tar.gz (10k bytes; symbolic black/white);
* icons.command.tar.gz (15k bytes; sede command used);
* icons.office.tar.gz (17k bytes; desktop);
* icons.orig.tar.gz (20k bytes; slightly off drawings);
* icons.button.tar.gz (35k bytes; round buttons);
* icons.bee.tar.gz (173k bytes; mathematical buzz);
* icons.flower.tar.gz (393k bytes; flower power);
The icons theme is also copied to
${SEDE_ROOT_VOUT}/icons.tar${SEDE_X_ZIP_EXT}.
- The second line in ${SEDE_ROOT_IN}/c_theme is expected to contain a HTML <body> (or <BODY>) tag for ${SEDE_ROOT_VOUT}/${SEDE_INDEX} and ${SEDE_ROOT_VOUT}/setup.html, with any arguments desired. For instance: `<body background="./background.jpg">' would set a background image.
- The third line in ${SEDE_ROOT_IN}/c_theme is used for the HTML title content. The data there is put between the HTML <title> and </title> tags. Variables are expanded according to Z-shell rules ($MYVAR, ${MYVAR}, $( MYCOMMAND )), in a sede environment. The special title `default-title' causes a combination of the overall poll name (as defined in ${SEDE_ROOT_IN}/c_name) and the present date/time to be used.
- The fourth line in ${SEDE_ROOT_IN}/c_theme is used for the opening tag of the pollname header, for instance <h1>. The content of this line is copied, it may contain more or less. For instance <hr> <h1 align="center">.
- The fifth line in ${SEDE_ROOT_IN}/c_theme is used for the closing tag of the pollname header, for instance </h1>. The content of this line is copied, it may contain more or less. This is therefore the place to define properties of the next paragraph: </h1> <p align="center"> for instance.
- The sixth line in ${SEDE_ROOT_IN}/c_theme is used for the tag that will be between poll item links. Basically: use <br> here if you want the links above each other, and leave empty to make them appear horizontally next to each other.
- The variable ${SEDE_INDEX_ALT} is used for the alt="..." option for all graphics tags <img ...> in ${SEDE_ROOT_VOUT}/${SEDE_INDEX}. Exceptions: the variable ${SEDE_INDEX_ALT_CONFIG} is used for the alt="..." option to the graphics tag <img ...> that points in ${SEDE_ROOT_VOUT}/${SEDE_INDEX} to ${SEDE_ROOT_VOUT}/setup.html, and as content for that link if no graphics theme is being used. The variable ${SEDE_INDEX_ALT_CONFIGBACK} is used for the alt="..." option to the graphics tag <img ...> that points in ${SEDE_ROOT_VOUT}/setup.html to ${SEDE_ROOT_VOUT}/${SEDE_INDEX}, and as content for that link if no graphics theme is being used.
- The variable ${SEDE_INDEX_CONFIG_TITLE} is put at the start of the body of ${SEDE_ROOT_VOUT}/setup.html. For example: SEDE_INDEX_CONFIG_TITLE='<h4 align="center">poll configuration</h4>'
- `givename' creates a copy of the addition result files in HTML format.
(See also: pollsconf.)
Shortcut: `h'.
Generate ballots, related records and ballot flag files, in short: everything to create ballots and records ready to be send to voters from the input files in ${SEDE_ROOT_IN}.
Without `test' or `t', a lockfile is created to prohibit overwriting or erasing the poll with subsequent calls to makes, or by other potentially damaging sede commands. With `unlock' or `u' does nothing but remove the lockfile, with `lock' does nothing but create the lockfile. The lockfile is simply the existance of a file `call_lock' in ${SEDE_ROOT_IN}, signalling the lock.
When you give `old' as an argument, vote-codes and passwords are not created new, but read from the flag-files: ${SEDE_ROOT_OUT}/flags_N. The flag used is sede_codes;POLLNUMBER;VOTECODE,PASSWORD. See ^-flag() for how to put flags in the flags-files.
With one of the *step arguments, goes into interactive stepping mode for debugging your ${SEDE_ROOT_IN}/c_template ballot: `ballotstep' steps per ballot, `passstep' steps per run (and re-run) over the ${SEDE_ROOT_IN}/c_template, `linestep' steps per line over the (current) ${SEDE_ROOT_IN}/c_template, `unitstep' steps per character over the (current) ${SEDE_ROOT_IN}/c_template. `echolinestep' is `linestep' while echoing input/output data, `echounitstep' is `unitstep' while echoing input/output data. `jumpstep' Is `echounitstep' and jump to the first occurence of ^, then become `echounitstep'.
`step' follows ${SEDE_BALLOTS_STEPMODE} defined in ~/.sederc (if it contains `ignore' or is unset/zero-length, `step' defaults to `echounitstep'). You can switch between stepping modes, and no stepping while stepping. Online help is available during stepping, see there on how to exactly operate stepping interactively (start a stepping mode and give `h'<enter> to see online help).
With the postfix :BALLOT:PASS:LINE:CHARACTER to a stepping argument, stepping begins at the given coordinates as if the ballot variable `^-step' had been encountered there (at ballot BALLOT, pass PASS, line LINE, and character CHARACTER (all numbers). CHARACTER value `0' is magic and stands for the end of line. If the coordinates are missed (because they didn't exist), then stepping starts immediately after where the coordinate would have been.
Shortcut: `m'.
Several shortcut arguments: v is equivalent to c_voters, p is equivalent to c_pnames, t is equivalent to c_template, v_t is equivalent to c_voters_fieldnames.
Shortcut: `pc'.
Example:
> sede pollsconf c_n_passes
> sede pc passes
these are identical commands (configure ${SEDE_ROOT_IN}/c_n_passes).
pollsconf automatically recognizes locally added theme archives (see c_theme) stored under ${SEDE_LIB}/extras/, with filenames starting with "icons".
When returned ballots are saved in ${SEDE_ROOT_VIN}, this command processes them into publishable results in ${SEDE_ROOT_VOUT}. With `-v' or `--verbose' it is more verbose. When you give as an argument a sede COMMAND which is called by processall, then processall aborts before running that sede command. If you give as an argument `-c' or `--continue', processall will start with the given command. Processall is a meta script, calling these sede commands in this order: rmprocessall, setup, getvotes, invalidvotes, putweight, get_voters, notvotedcodes, correlate, doublevotes, addvote, addvote_weight, addvote_compact, doti, givename.
Shortcut: `p'.
Shortcut: `rmp'.
Example:
> sede run 'ls $SEDE_ROOT_POLLS'
see what poll archives are stored.
run returns with the error value of the executed command.
When specifying multiple COMMANDFIELDs, it is possible the file can no longer be found because its name was changed. Unzipping usually removes a suffix, encryption adds one, etc. If a file moved, a new filename can be defined by having the command in COMMANDFIELD put a filename in ${SEDE_ROOT_TMP}/newname. If that filename is not fully qualified, it is assumed to be local to ${SEDE_ROOT_VIN}, unless [.]/DIRECTORY was given as an argument, in which case it will be assumed local to that directory instead.
If the file was moved by the commands, but no new name was defined in
${SEDE_ROOT_TMP}/newname, then rundir tries to guess
a name for use with the next COMMANDFIELD. First rundir
will look if the filename stripped of its latest postfix exists, if so
that file will be used for the next COMMANDFIELD as `^FILE'
(see runfield). If no file without latest postfix is found,
the original filename is stripped of all postfixes, but not including
the latest occurence of `_N_' which is left intact
even if present in a postfix. That reduced filename is then matched
against all files that have the same beginning as the thus reduced
name, and the one with the latest ctime (see file system) is used.
Example:
Original name: ./filename._8_.a.b.c.gz
New name: ./filename._8_.a
Match name against: ./filename._8_*
Found name: ./filename._8_.a
With "steprundir", rundir halts before executing commands (calls runfield without its `go' argument).
Note: if you plan on using rundir, don't scramble the lines in the voter registration between the moment the files are being generated, and have been processed by rundir, otherwise the "voter serial numbers" won't match with the file names anymore.
Every occurrence of the literal string ^FILE in the command line found in ${SEDE_ROOT_IN}/c_voters, is replaced by the argument INFILE to runfield. Similarly every occurence of the literal string ^SERIAL is replaced by the `voter serial number' (the line number on which the "current voter" is registered in ${SEDE_ROOT_IN}/c_voters, which is assumed to be defined in the filename by the latest occurence of `_NUMBER_' in that filename). The commands may contain redirections, and multiple commands can be concatenated by using `;' etc.
With `go' (after INFILE), runfield prints the command found and asks for confirmation.
Warning: be sure the commands in the voter-registration are really what you want them to be, `rm ~/*' will be executed without hesitation and with serious consequences.
runfield serves (also) as a back-end to rundir, and the flag sede_divide_run;. Typical usage would be to encrypt/decrypt ballots using password type encryption tools. runfield uses run to execute commands.
Example:
voter registration:
${SEDE_ROOT_IN}/c_voters:
,user@somedomain.net,,,export SECRET="mY Very s0cret cey"; ccrypt --encrypt
--envvar SECRET ^FILE,,,,,,
field names definitions:
${SEDE_ROOT_IN}/c_voters_fieldnames:
,email,,,encrypt,,,,
or:
,user@somedomain.net,,gzip ^FILE,echo "another secret" > ${SEDE_ROOT_TMP}/key,
ccrypt --encrypt -k ${SEDE_ROOT_TMP}/key ^FILE,
sede scramble ${SEDE_ROOT_TMP}/key;rm ${SEDE_ROOT_TMP}/key,
ccrypt --decrypt -k ${SEDE_ROOT_TMP}/key ^FILE,,,,
field names definitions:
${SEDE_ROOT_IN}/c_voters_fieldnames:
,email,,zip,storekey,encrypt,erasekey,decrypt,
Adding the flag (with ^-flag[...] in the template
${SEDE_ROOT_IN}/c_template):
sede_divide_run;PATTERN;ATTACHMENT_NAME;encrypt
would then encrypt that attachment according to the specified commands.
For each voter, other encryption commands can be registered. For
decryption, see rundir.
runfield returns with the error value of the executed command, unless an error was encountered before the command(s) could be executed, in which case it returns false.
Note: using MIME (/etc/mime.types, /etc/mailcap) might make usage of attachments much easier for voters, and would set the appropriate MIME flags in the e-mail for voter software to recognize.
Shortcut: `s'.
mail agent:
sendmail uses by default as mail agent mailx (mail), in which case the ballot is send out in one piece ignoring flags specifying attachments.
If it is non-empty, the executable in ${SEDE_EXEC_MAILSEND} is called for each ballot, with pointers in the environment to the current ballot: ${ADDRESS} ${SUBJECT} ${BODY} ${FLAGS} ${NUMBER}. ${ADDRESS}: the email address of the recipient, ${BODY}: the filename pointing to the ballot, ${SUBJECT}: the email subject, ${FLAGS}: the filename of the ballot flags file (see ^-flag, ${SEDE_ROOT_IN}/c_template), and ${NUMBER}: the serial number of the ballot.
As a special case, if ${SEDE_EXEC_MAILSEND} points to a file named `mutt', the ballot is cut up into attachments (according to the flags if any), and mutt arguments are given to ${SEDE_EXEC_MAILSEND}. Note: mutt is executed and given two linebreaks, to break through its startup user dialog.
A second special case: if ${SEDE_EXEC_MAILSEND} starts with `self ' (`self' + SPACE), then the command immediately following `self ' is executed for each ballot, with an environment set as with non-empty, non-mutt ${SEDE_EXEC_MAILSEND} (${ADDRESS} ${SUBJECT} ${BODY} ${FLAGS} ${NUMBER}), and with the base email and all subsequent attachments (if any) in the positional argument list (${BODY} points to the original uncut ballot). You are then able to use ballot-cutting, but process the parts according to your own design, without being troubled by mutt formatted arguments/linebreaks.
sendmail Reacts to several flags in ${SEDE_ROOT_OUT}/flags_BALLOT_NUMBER:
sede_subject;YOUR_SUBJECT
YOUR_SUBJECT will be the subject of the email, this header
overrides all other subject definitions. The latest occurence of
this flag will be used.
sede_subject_file;SUBJECT_FILE
SUBJECT_FILE is opened as a file under ${SEDE_ROOT_IN}, and
its first line used as the subject. The latest occurence
of this flag will be used. It has a lower precedence than
sede_subject;, but it overrides the poll-wide subject definition
in ${SEDE_ROOT_IN}/c_address (line 2).
sede_header;YOURHEADER
YOURHEADER is put into the header area of the message (user defined
header).
(This flag is only effective when ${SEDE_EXEC_MAILSEND} in ~/.sederc is pointing to mutt.)
sede_attachment;YOUR_FILE
YOUR_FILE is made an attachment to the message, it will if not
containing a full path be sought within ${SEDE_ROOT_IN}.
(This flag is only effective when ${SEDE_EXEC_MAILSEND} in ~/.sederc is pointing to mutt, or starting with `self '.)
sede_divide;PATTERN;ATTACHMENT_NAME
The ballot is cut in two sections from the first occurence of (grep -E)
pattern PATTERN, the above section remains the primary email,
the second section becomes an attachment as ATTACHMENT_NAME.
ATTACHMENT_NAME defaults to attachment-N, where N
is the serial number of the attachment.
Repeat occurences of this flag in ${SEDE_ROOT_OUT}/flags_BALLOT_NUMBER will operate on the newly shortened primary email, so the ballot can effectively be cut up into many attachments. You can write the flags in the natural order though, they are processed latest to first (bottom to top of the flags file), the attachments are attached like their order on the original ballot. The line matched by PATTERN is deleted altogether. It is important to get this flag into the flags file in the correct order.
(This flag is only effective when ${SEDE_EXEC_MAILSEND} in ~/.sederc is pointing to mutt, or starting with `self '.)
sede_divide_run;PATTERN;ATTACHMENT_NAME;COMMAND TITLE[;COMMAND TITLE[;...]]
The same as sede_divide, except it also operates
commands on the attachment. COMMANDTITLE is passed
to runfield (as its FIELDNAME argument), along with
the current voter number (the line the current voter is registered
on in ${SEDE_ROOT_IN}/c_voters_fieldnames, as
VOTERNUMBER) and the current attachment (as INFILE). This causes
the commandline that is registered for the current voter under
the field COMMANDTITLE (field-names are defined in
${SEDE_ROOT_IN}/c_voters_fieldnames) to be executed.
Every occurrence of ^FILE within the command line
found there is replaced by the name of the current attachment file.
If the name of the attachment is lengthened by the commands but retains its former base, and only one matching file is found, that file is assumed to be the attachment file. So, if a command adds a postfix, the attachment should be found without trouble. If the file ${SEDE_ROOT_TMP}/newname contains a filename, that filename will be used instead. ${SEDE_ROOT_TMP}/newname is deleted before the command-line is executed, and after its content has been examined if it has been created (by you).
An unlimited number of COMMANDTITLEs can be used, each commandline found in ${SEDE_ROOT_IN}/c_voters can contain any number of commands and redirections (including no command at all). sendmail catches errors occuring with executing these commands, and will promt the user.
(This flag is only effective when ${SEDE_EXEC_MAILSEND} in ~/.sederc is pointing to mutt, or starting with `self '.)
sede_attachment;YOUR_FILE And sede_divide;PATTERN;ATTACHMENT_NAME can be used intermixed, causing the attachments to become ordered like these flags are. These flags are processed bottom-up, so the latest flag is processed first, then the attachments are added in the natural order: the order of their location on the original ballot, and the order of the flags that describe the attachments. For both hold that if the filename (YOUR_FILE or ATTACHMENT_NAME) is identical to `sede_delete_this_attachment', the attachment is not added, but ignored. It is important to get this flag into the flags file in the correct order.
(This flag is only effective when ${SEDE_EXEC_MAILSEND} in ~/.sederc is pointing to mutt, or starting with `self '.)
Note: all flags starting with sede_ are reserved for future expansion, use them at your own risk of namespace collision with future versions of sede.
sendmail returns `30' as error value after a user-abort.
This command has to run in the current shell: `. sede set.path [ARGUMENT]', to be effective. Doing that leaves the environment augmented with sede variables that the sede commands need. Changing the value of these variables changes the behaviour of subsequent sede commands (also if you go through the sede "shell wrapper" as in `sede nop').
After running . sede set.path with `first' or `last', and then with `never', nothing is changed (except the history record of your system shell).
Some additional commands are interpreted
by shell:
abort-on,
abort-off,
buf-all,
buf-some,
buf-off,
buf-out[:FILE],
bye, exit, quit,
cd:DIR,
echo-on,
echo-off,
exec-on,
exec-off,
get-prompt,
get-use,
halt-on,
halt-off,
lock-input[:|;]|[::|;;][SYSTEMCOMMAND|^]
path-on,
path-off,
p:exec,
p:[default],
p:none,
p:user,
P:PROMPT,
push-hist[:COMMAND],
scroll-hist[:BUFFER], -,
search-on,
search-off,
sede-first,
sede-last,
sede-never,
silent-on,
silent-off,
stamp-log[IGNORED],
verbose-on,
verbose-off,
which COMMAND,
?,
??,
CTRL-L, `,'
-[1|2|3|...16][ POSTFIX],
^[^[^]][ POSTFIX],
`,COMMAND',
`;COMMAND',
`?COMMAND',
`. COMMAND',
`#COMMENTS',
`!MATCH'.
ARGUMENTS:
--zsh [COMMANDSFILE],
--bash [COMMANDSFILE],
--csh [COMMANDSFILE],
--sh [COMMANDSFILE],
--ksh [COMMANDSFILE]
Starts --SHELL (zsh, bash, csh, sh, ksh) with an
environment that sede commands understand, and the
${PATH} variable pointing to sede commands according to
the setting of ${SEDE_SHELL_ORDER}. With --csh does
the same but if COMMANDSFILE is present,
${SEDE_SHELL_LOGINSHELL}=on is ignored.
You'll have to make
sure not to (completely) reset variables in your shell init process,
otherwise it doesn't work. ${SEDE_SHELL_USE} can be used
to test for sede during shell init. All other
arguments to sede shell are ignored if --SHELL
is given (see set.path for a similar effect in the current shell,
which probably also works for other shells than directly supported by
shell). If it doesn't work (commands are not found), setting
SEDE_SHELL_LOGINSHELL=off in ~/.sederc might help (bash,
ksh, sh).
Without `--SHELL', `sede shell' presents its own (Zsh adapted) interface, with some features potentially usefull to a sede user. sede shell has no job-control, or multi-lined commands.
--noprompt
With --noprompt doesn't print a prompt, and the startup
notice is suppressed.
--log [LOGFILE]
With --log
writes a logfile of executed commands into
/tmp/.PID.sede_x.log,
or into LOGFILE if it is given. If
${SEDE_SHELL_ABS_LOG} is `on', the log is "absolute" (see
${SEDE_SHELL_ABS_LOG}) log file name.
INITFILE
With INITFILE, runs
INITFILE in the shell process itself (interpreted as
sede shell commands), then
waits for user input (unless exit, bye or quit were
executed, in which case sede shell exits).
EXECUTION:
The sede shell build-in commands are executed first. If none matched the input given, sede commands and system commands are searched in the order ${SEDE_SHELL_ORDER} defines. System commands are only searched if ${SEDE_SHELL_PATH} doesn't block it. ${SEDE_SHELL_EXEC} can block all normal execution of all commands except build-ins. Three build-ins control these variables interactively (`path-[on|off]', `sede-[first|last|never]' and `exec-[on|off]'. System commands are executed in the current environment (though you can execute them in a subshell, see `;').
VARIABLES:
Since it is possible to execute commands in the shell process itself, sede shell variables can be adjusted directly (using Z-shell syntax), causing changes in behaviour of subsequent sede commands.
The most important variables are the ${SEDE_ROOT_*} variables, and the ${SEDE_SHELL_*} variables (which are all explained at ~/.sederc). Only in sede shell are shortcut-versions for the ${SEDE_ROOT_*} variables in the environment. These shortcuts (to processing directories) have a name consisting of the trailing part of the long name in lower case: ${SEDE_ROOT_IN} -> ${in}, ${SEDE_ROOT_OUT} -> ${out}, same for: ${vin}, ${vinread}, ${vout}, ${polls}, ${tmp}. These short-cut variables are continues copies of the longer versions, you can read them but not change them. Change the long versions instead.
The internal sede shell variables start with `SEDE_S_'.
MISCELANEOUS:
When a command is executed in sede shell, it can find the content `yes' in ${SEDE_SHELL_USE} in the environment.
Sede shell saves its history buffers in ~/.sede_history when it is exitted (not killed), and reads them back in at startup. If sede shell is killed, the history is not written to ~/.sede_history. The history buffers are not a proper record of what was executed, use the log file for this purpose.
Some commands work on ~/.sederc (`silent'). Such and other changes to ~/.sederc do not become effective within sede shell, unless the ~/.sederc is executed within sede shell (`. ~/.sederc', or start a new instance of sede shell from a clean environment).
BUILT-IN COMMANDS: on error these return 1 (false), otherwise 0 (true).
`abort-on', `abort-off'
Abort on error, or don't, respectively.
Default: ${SEDE_SHELL_ABORT} in ~/.sederc
(`on' or `off').
`buf-all', `buf-some', `buf-off'
Puts the print-history-buffers tag into the prompt-string:
for buf-all the tag for all buffers, buf-some the tag
for some buffers, buf-off removes these print-history-buffers tags
from the prompt (%B and %b).
Default: defined in ~/.sederc (${SEDE_SHELL_PROMPT})
(see special characters).
buf-out[:FILE]
Prints the (non-empty) history buffers into the logfile
or to FILE if it is given. If no logfile is in use, uses the
default /tmp/.PID.sede_x.log.
`bye', `exit', `quit
End shell.
`cd:DIRECTORY'
Alters working directory.
Default: directory into which sede shell started.
`echo-on', `echo-off'
Print the to be executed command to the screen before executing it.
Default at startup:
${SEDE_SHELL_ECHO} in ~/.sederc
(`on' or `off').
`exec-on', `exec-off'
Set executing commands, or not executing commands (except built-ins).
Default: ${SEDE_SHELL_EXEC} in ~/.sederc (`on' or
`off').
`get-prompt'
Print the user-prompt string.
`get-use'
Print the current
setting of
verbose-[on|off],
abort-[on|off],
path-[on|off]
sede-[first|last|never]
exec-[on|off]
search-[on|off]
echo-[on|off].
`halt-on', `halt-off'
Halts before executing the command for user confirmation.
Default at startup:
${SEDE_SHELL_HALT} in ~/.sederc
(`on' or `off').
`lock-input[:|;]|[::|;;][SYSTEMCOMMAND|^]'
Asks for an alpha-numerical password, then clears the screen and
locks the input stream until the correct password is given.
When no trailing arguments are present, or
when `;' is used, it prints its own prompt. With
`:' (`lock-input:[:]'), prints the user prompt (p:user)
instead of its own prompt.
With `SYSTEMCOMMAND' after a single `:' or `;'
(`lock-input:SYSTEMCOMMAND',
`lock-input;SYSTEMCOMMAND'),
runs SYSTEMCOMMAND once, before printing a prompt.
When `:' or `;'
are doubled `::', `;;', runs SYSTEMCOMMAND before
every new prompt that is printed.
With `^' instead of `SYSTEMCOMMAND',
substitutes the content of the latest history buffer for `SYSTEMCOMMAND'.
A leading `;', if present, is first stripped from the history buffer.
Commands are executed and logged in the
logfile (if any) as "subshell system commands" (like shell
builtin `;COMMAND').
Reports on breaking in attempts. Does only protect the current
process, not other instances of sede shell. Reacts to
${SEDE_SHELL_VERBOSE}.
3 seconds timeout after false input.
`path-on', `path-off'
If a command is given, try the wider system beyond sede (according to
${SEDE_SHELL_ORDER}), or don't try the wider system, respectively.
Default: ${SEDE_SHELL_PATH} in ~/.sederc
(`on' or `off').
`p:none', `p:[default]', `p:user', `p:reset'
Giving `p:none' removes printing of any prompt string.
Giving `p:' or `p:default' gives you the default prompt
(`^ ').
Giving `p:user' gives you the "user prompt", which can be configured.
At startup, the user prompt is set from ${SEDE_SHELL_PROMPT}
(see ~/.sederc), but it can be changed by calling `P:PROMPT'
(see elsewhere).
Giving `p:reset' resets the value of the user prompt to the value of
${SEDE_SHELL_PROMPT} (see ~/.sederc).
`p:none' can be set at startup with the argument --noprompt to shell. p:default, p:user, and p:none override (alter) the --noprompt argument and ~/.sederc settings from the moment they are called.
`P:PROMPT'
Set the user-prompt string.
Some special sequences are recognized for the user prompt. The prompt
is echoed using echo(1) -en "...", so some C escape
sequences are also expanded (\a, \n). The prompt is also set to the
user prompt if it was the default prompt.
%- : only `%-' is erased, no other `%...' are
expanded, has to be postfixed to the prompt, otherwise it is ignored
(much faster prompt)
%P : current overall pollname (${SEDE_ROOT_IN}/c_name)
%X : `lock' if poll is locked, `OPEN' if not
%x : `X' if poll is locked, `O' if not
%a : bell
%B : all history buffers are printed, has to be pre-pended to
the prompt otherwise it is ignored
%b : some history buffers are printed, has to be pre-pended to
the prompt otherwise it is ignored
%D : complete time/date
%d : current working directory
%% : a literal %
%! : command serial number
%? : latest exit code
%^ : the latest command
%. : trailing part of current working directory
%~ : working directory with ${HOME} replaced by ~.
%H : current hour
%h : hostname
%l : current tty line
%L : shell nesting level (starting from 0)
%M : current minute
%n : a line break
%s : a space (` ')
%S : current second
%u : program user
Default: defined in ~/.sederc.
`push-hist[:COMMAND]'
Pushes COMMAND on the history stack.
`scroll-hist[:BUFFER]', `-',
Scroll back the history buffers one step. If BUFFER (a number)
is present, delete that buffer and scroll the older buffers back in
its place.
`search-on', `search-off'
Print information updates on how the command-search is progressing
past the built-in searching.
Default: search-off.
`sede-first', `sede-last', `sede-never'
If a command is given, search for a sede command first before trying
${PATH}, search sede last, or never search for a sede command,
respectively.
Default: ${SEDE_SHELL_ORDER} in ~/.sederc (`first',
`last' or `never').
`silent-on', `silent-off'
Set/unset ${SEDE_SILENT} in the environment, setting the verbosity
level of sede
commands. This built-in doesn't affect
~/.sederc like sede silent does.
Default defined in ${SEDE_SILENT}, in ~/.sederc
(`yes' or `no').
`stamp-log[IGNORED]'
Prints a comment containing the present date/time in the logfile. If
no log file was being used, then also start log recording. Content
trailing `stamp-log' is ignored, but will be present in the log.
`verbose-on', `verbose-off'
Alters verbose level of shell.
Default: for interactive use defined in ${SEDE_SHELL_VERBOSE}
in ~/.sederc (`on' or `off'); for
non-interactive use follows ${SEDE_SILENT}.
`which' COMMAND
See which COMMAND would get executed.
`?', `??'
Give overview of sede shell built-ins (which are explained now),
`??' explains each command shortly.
`CTRL-L', `,'
(^L, or a lone comma): clear screen.
`^[ POSTFIX]', `-1[ POSTFIX]',
`^^[ POSTFIX]', `-2[ POSTFIX]',
`^^^[ POSTFIX]', `-3[ POSTFIX]',
`-4[ POSTFIX]',
`-5[ POSTFIX]',
`-6[ POSTFIX]',
`-7[ POSTFIX]',
`-8[ POSTFIX]',
`-9[ POSTFIX]',
`-10[ POSTFIX]'
`-11[ POSTFIX]'
`-12[ POSTFIX]'
`-13[ POSTFIX]'
`-14[ POSTFIX]'
`-15[ POSTFIX]'
`-16[ POSTFIX]'
Re-run older commands.
For the form `^[^[...]]', the buffer number equal to the
number of ^'s is re-executed.
For the form `-N', the Nth buffer is re-executed.
If SPACE + POSTFIX is appended, it is appended to
the command when it is executed.
The command prefixes: `,', `;', and `. ' affect the history buffers, the prefix `?' only puts COMMAND in the history buffers. Other sede shell built-ins don't affect these buffers.
`,COMMAND'
Force COMMAND as a sede command.
`;COMMAND'
Force COMMAND as a system (${PATH}) command.
`?COMMAND'
Sets exec-off echo-on search-on for COMMAND.
COMMAND is recorded into the history buffers.
`. COMMAND'
(dot space) Force COMMAND as a system (${PATH}) command,
within the sede shell process.
`#COMMENTS'
Ignored up to end-of-line, # is only recognized if it is the
first character in the input.
`!MATCH'
Bang expansion, search in the history buffers for the first command
to match MATCH. MATCH is a literal pattern matched with
the leading edge of the history buffers: `e' and `ech' match `echo'.
`COMMAND'
Run COMMAND according to the settings of
sede-[first|last|never]
and path-[on|off].
This command doesn't seem to work properly if the environment is preset, but it does. It just alters the value in ~/.sederc, it cannot touch the local environment because it is executing in a subshell. In a preset environment (set.path, shell --SHELL), flip the value of ${SEDE_SILENT} yourself, in sede shell use the built-ins silent-on and silent-off.
Shortcut: `u'.
With --see (or -s), marks each field `,CONTENT,' with its field number and field name as defined in ${SEDE_ROOT_IN}/c_voters_fieldnames: `,CONTENT(FIELD-NUMBER=FIELD-NAME),'.
With --designate (or -d) marks only FIELD with its field number and name. Giving optional `--extra FIELD2' marks all fields from FIELD to and including FIELD2 with their field number and field name.
--get (or -g): echoes FIELD to standard output.
--cut (or -c): echoes all but FIELD to standard output.
--put (or -p): integrating PUT_FILE and FILE in FIELD in FILE, and echoes the result to standard output. If FIELD does not exist on a line it is created. If FIELD equals 0, then the content of PUT_FILE is not echoed to standard output.
votersfield returns 1 if nothing happened, for instance if the --get field did not exist in the input. If no other error occurred it returns 0. See also `fieldpipe'.
All variable names starting with `SEDE_' may be used for future expansion.
Ways to execute a script:
sede COMMAND [PARAMETER[S]]
Use the sede executable in the path, and call it from a script with suitable arguments. The downside to this is that you cannot alter the variables defined in ~/.sederc and have them in an altered state for the next call to sede.
sede shell FILE
cat FILE | sede [shell]
Using sede shell, the script can be equal to sede shell interactive commands. The commands-file can be piped, or be given as an argument. Since sede starts by default shell, you can run `echo COMMANDS | sede'. FILE has to end on an exit command (exit, bye, or ^D), otherwise after the end, sede shell is waiting for user input. Commands have to be delimited by line breaks.
sede shell --zsh|--bash|--csh|--sh|--ksh FILE
cat FILE | sede shell --zsh|--bash|--csh|--sh|--ksh
Puts sede commands in the search path of a regular shell. The commands file can be piped, or given as the second argument. Where the sede commands are in the ${PATH} is controlled by ${SEDE_SHELL_ORDER}. After the shell starts, sede commands will be using the local environment which has been suitably augmented for sede commands. If the environment set by sede is changed, results change for subsequent commands (see sede_env).
./FILE ## using sede shell [ARGS] `interpreter'
./FILE ## using . sede set.path
Stand-alone sede script. The first possibility is to put:
#!/PATH/sede shell
#!/PATH/sede shell --noprompt
or
#!/PATH/sede shell --SHELL
on top of your sede script, choose for SHELL one of
zsh, bash, csh, sh, or ksh.
(Between the first and second argument only one space.)
The second form is to set your shell environment/path with the system command `. sede set.path [ARGUMENT]', somewhere before you want to use sede commands.
If non-empty, use a different emailing command than the default (mailx, mail). If a user command is supplied, it has access to the to be send ballot through variables in the environment.
${SEDE_EXEC_MAILSEND} has two special contents that behave differently: pointing to an instance of `mutt', or starting with `email ' (`email' + SPACE).
(Warning: do not point this variable - or any variable in the SEDE_ROOT_* group - to data not relating to sede. Sede commands operate on these directories with impunity!)
(Warning: do not point this variable - or any variable in the SEDE_ROOT_* group - to data not relating to sede. Sede commands operate on these directories with impunity.)
(Warning: do not point this variable - or any variable in the SEDE_ROOT_* group - to data not relating to sede. Sede commands operate on these directories with impunity.)
(Warning: do not point this variable - or any variable in the SEDE_ROOT_* group - to data not relating to sede. Sede commands operate on these directories with impunity.)
If all ballots are saved in the same file, the command getvotes
runs about 10 times quicker than if you store each ballot in a seperate
file. A caveat with this is that if a long comment space is chosen, and
the voter removes the end marker for a voting area (see
${SEDE_ROOT_IN}/c_find_votearea),
characters from the next returned ballot might be swallowed into the
voting area.
~/.sederc: SEDE_ROOT_VIN="/YOURDIR"
(Warning: do not point this variable - or any variable in the SEDE_ROOT_* group - to data not relating to sede. Sede commands operate on these directories with impunity.)
(Warning: do not point this variable - or any variable in the SEDE_ROOT_* group - to data not relating to sede. Sede commands operate on these directories with impunity.)
(Warning: do not point this variable - or any variable in the SEDE_ROOT_* group - to data not relating to sede. Sede commands operate on these directories with impunity.)
If at startup of sede shell it is empty, the default prompt is used instead (`^ ', which is fast). If it has content, its content is taken to be the "user prompt": expanding `%...' sequences and expanding variables which is relatively slow (see shell, P:PROMPT for the `%...' sequences).
Variable expansion within the ${SEDE_SHELL_PROMPT} variable ($MYVAR, ${MYVAR}, $( MYCOMMAND ), etc), has two possible moments for expansion. The first is at startup of sede shell, this happens when the variable is not escaped, and the right hand side is not between single quotes: SEDE_SHELL_PROMPT="$( date )^%s". This prompt string will reflect the date/time of startup, and never change. The second expansion moment is for each new prompt, this happens when the variable is escaped `\', or the right hand side is between single quotes: SEDE_SHELL_PROMPT="\$( date )^%s", SEDE_SHELL_PROMPT='$( date )^%s'.
POLL CONFIGURATION FILES (${SEDE_ROOT_IN}/c_*)
The format of this file below its firts line is: on each line, one vote-condensing under a name can be defined, each line is expected to have this form:
POLL_NUMBER,ANSWER_TITLE,PATTERN,PATTERN,PATTERN,... PATTERN will be augmented with `^' before it and `$' behind it automatically. If you want to match an empty vote, try `B'.
POLL_NUMBER is the number of the poll to which this condensing relates
to, the number corresponds to the poll name under the same line number in
${SEDE_ROOT_IN}/c_pnames.
ANSWER_TITLE is the title under which the results will be grouped, it
can contain spaces (and comma's, see shortly below).
PATTERN,... are an unlimited number of grep -E patterns to which
the created raw results are matched.
The field separator in this file is the comma in the same way as in the
voter registration file: to use a literal comma, write `\,', to write
a literal `\', double it, a `\ followed by a non-comma and non
slash is left unchanged.
When votes are counted multiple times because they are matched by multiple patterns from different lines, the total doesn't match the raw vote results total anymore, an error message is printed in the compacted results.
The password can be used to authenticate something (a voter for instance) after the results have been published, because after the results publication all vote codes become public record.
Note: this can be augmented by a second password which has been agreed upon during voter registration, ideally this password would never pass over an insecure channel (but through snail mail for instance).
The by `yes:browse' generated directory files have the following name: POLLNAME-${SEDE_INDEX_BROWSE}/VOTECODE. With the `:together' modifier, these filenames point to the same file containing all votes for that voter.
Without the `:together' modifier, the file ${SEDE_ROOT_VOUT}/pervoter is alphabetically sorted, to eliminate the information of which votes all belonged to the same voter. With the `:together' modifier, the first first vote for any vote-code found in the ${SEDE_ROOT_VIN}/* files (or file) will be displayed above the other votes for that poll and vote-code. This first vote is the chosen vote which is going to be counted. All other rogue or accidental votes are discarded from the tally, but are still displayed in the per-voter results (below the chosen vote for each vote code), and in the POLLNAME-${SEDE_INDEX_BROWSE}/VOTECODE files (if present).
The poll-names come back into the ballot in most voting areas (see ${SEDE_ROOT_IN}/c_find_votearea, and ^-title(N)), and it comes back on the end-results page and in filenames of result lists.
Processing the ${SEDE_ROOT_IN}/c_template:
The ${SEDE_ROOT_IN}/c_template is processed into ballots by passing over the ${SEDE_ROOT_IN}/c_template one or multiple times by the `makes' (and/or `addvoter') command. During each pass, encountered variables (see below) are expanded. There are two stages: the optional "pre-processing" stage passes over the ${SEDE_ROOT_IN}/c_template and creates a secundary ${SEDE_ROOT_IN}/c_template. If pre-processing was requested (see ${SEDE_ROOT_IN}/c_preprocess), the secundary ${SEDE_ROOT_IN}/c_template is used for the subsequent voter-specific stage, otherwise the original ${SEDE_ROOT_IN}/c_template is used directly. During the pre-processing stage the "voter data" used is dummy data. By default pre-processing constitutes one pass, but it can be reset by the appropriate ${SEDE_ROOT_IN}/c_template variable (see below).
After the optional pre-processing, the actual ballots are being generated by passing over the ${SEDE_ROOT_IN}/c_template with as "voter data" each line in the voter registration in turn. By default it passes as many times as ${SEDE_ROOT_IN}/c_n_passes defines, but as with pre-processing this can be reset by the appropriate ${SEDE_ROOT_IN}/c_template variable.
If ${SEDE_ROOT_IN}/c_codemode is `ignore', then the first pass made over the original ${SEDE_ROOT_IN}/c_template (as you wrote it) ignores all data outside any variable. If ${SEDE_ROOT_IN}/c_codemode is `copy', then all data outside variables is copied into the next pass (which is normal behaviour for all subsequent passes, regardless of the setting of ${SEDE_ROOT_IN}/c_codemode).
Unusual variables:
Most variables result in text in the ballot, but not all. Some exceptions exist, notably the flags variable: writing to the corresponding flags file for the ballot being generated, and the vote-weight variable, which (ultimately) writes data in ${SEDE_ROOT_OUT}/codespervoter.
All variable names are case insensitive, only the lower case forms are listed.
^-allstep or
^a
^-ballot or
^#
^-break or
^b
^-execute(SYSTEMCOMMAND) or
^!(SYSTEMCOMMAND)
^-execute[SYSTEMCOMMAND] or
^![SYSTEMCOMMAND] (second form, plus logfile)
^-execute{SYSTEMCOMMAND [[>]FILE]} or
^!{SYSTEMCOMMAND [[>]> FILE]} (third form, no forced re-direction)
^-file(FILE) or
^x(FILE)
^-file[FILE|LINE_NUMBER] or
^x[FILE|LINENUMBER] (second form, line number)
^-flag(yourflag) or
^f(yourflag)
^-flag[yourflag] or
^f[yourflag] (second form, plus line break)
^-getenv(VARIABLE) or
^e(VARIABLE)
^-get_loop or
^g
^-ifelse?TEXT1?TEXT2?MATCH?NO_MATCH? or
^?TEXT1?TEXT2?MATCH?NO_MATCH?
^-loop(PASS) or
^l(PASS)
^-mark_at(PASS) or
^:(PASS)
^-mark_at[PASS] or
^:[PASS] (second form, count-up)
^-mark_end or
^;
^-mark_now or
^^
^-password(POLL_NUMBER) or
^p(POLL_NUMBER)
^-password<POLL_NUMBER> or
^p<POLL_NUMBER> (second form, less ambiguous)
^-password[POLL_NUMBER] or
^p[POLL_NUMBER] (third form, optical machine)
^-print"TEXT" or
^."TEXT"
^-print'TEXT' or
^.'TEXT' (second form, different delimiters)
^-question(FILE1|FILE2) or
^q(FILE1|FILE2)
^-question[HEADFILE|OPTIONSFILE] or
^q[HEADFILE|OPTIONSFILE] (second form, multiple options)
^-roguecode
^r
^-step or
^s
^-title(POLL_NUMBER) or
^t(POLL_NUMBER)
^-votecode(POLL_NUMBER) or
^c(POLL_NUMBER)
^-votecode<POLL_NUMBER> or
^c<POLL_NUMBER> (second form, less ambiguous)
^-votecode[POLL_NUMBER] or
^c[POLL_NUMBER] (third form, optical machine)
^-voter(FIELD_NUMBER) or
^v(FIELD_NUMBER)
^-voter[NAME] or
^v[NAME] (second form, voter field names)
^-weight(POLL_NUMBER|WEIGHT) or
^w(POLL_NUMBER|WEIGHT)
Template variables details:
---------------------------
If you want to use a literal `?', escape it
with `\', if you want to use a literal `\': double it
(single `\' without trailing `?' is treated as a normal
character). The maximum length that can be tested is 100 characters.
Example: ^^?male?^v(10)?Mister?Lady?
Example: ^^?^!(date +%w)?6?today free\???
Example: ^^?^v(25)?henry.*template.*?^x(henry/template)??
Note that if you use the ^l(n) variable with n = 0, you can change the ballot to its final expansion in the middle of ballot expansion, and this would start expanding `^;' from that point onward, but not above it (if sede was not yet on the final pass).
If the variable is found before the latest pass, the short form is put back into the output-stream for later examination.
Example: ^-mark_end-question(questionA|optionsA)
If preprocessing 1 pass, postpones expansion of ^-question until
after pre-processing.
Example options file:
red
# this is ignored
green
#
blue
##
See givename for more explicit information.
When you allow (large) comment spaces, it becomes possible for one vote-area to `eat' the next vote-area if the voter has removed the ending tag in case of multi-lined voting-area's (see ${SEDE_ROOT_IN}/c_template, spread* voting area types). You can defend against this to either save every vote to its own file in ${SEDE_ROOT_VIN}/, or have some kind of buffer between ballots: a block of text (for instance mail-headers), the vote-ending tag, a block spaces, etc. Ofcourse you could place a vote-ending tag in the leading text of the ballot above all vote-areas, if a voter doesn't remove this defence he is save from ballot-eating from another voter if all votes are saved into the same file.
By writing `case_insensitive' on the second line, all codes are created in such a way that they are unique regardless of their (upper/lower) case for their alphabetic component. `case_sensitive' causes upper and lower case to be regarded as different during ballot generating.
Neither do alter the way the vote codes are processed, or which voter codes can occur. It is meant to not run into trouble on (file-) systems or web servers (or whatever), which use case insensitive filenames, should the vote code be used as a filename (see ${SEDE_ROOT_IN}/c_pervoter). The World Wide Web features case sensitive filenames, though.
The data in this file is used throughout SEDE, it is at the core of running polls/referenda. It is used to identify your voters, for which you can then proceed to write a template ballot (${SEDE_ROOT_IN}/c_template). It is used to find addressing data (e-mail addresses for instance) for the ballots, for encrypting and decrypting commands (or other commands operating on ballots) if you want to (see runfield). You can call fields into the ballot (see ^-voter), even modify the ballot using the if-then structure switching on the content of fields, see ^-ifelse?. You can store in it anything you wish to remember about your voters.
The line-number a voter is registered on is known as its voter number or serial number, but after ballot creation you can choose to randomize the line positions, to erase that link between voters and polls: ballots will be stored under names containing this serial number for instance (see randomvoters).
As a security improvement, you might want to register voters under some kind of alias (number) in this file, and keep the alias-voter correlation file in a different location. Notice that ${SEDE_ROOT_IN}/c_voters is part of poll archives, and would be duplicated many times in the process of storing polls in archives (see allsave).
Using field-names that consist of only decimal digits (,,,8,77,007,,,) makes it impossible to use that name with `sede votersfield'.
The second line contains which fields from the ${SEDE_ROOT_OUT}/secret_master_N files (excluding the stored vote codes and passwords) are to be present in the voted voters list in the end results (in ${SEDE_ROOT_VOUT}). The chosen fields are expected as a range, written delimited by a `-': FIELDSTART-FIELDEND. The fields (defined like they are defined in the voters registration file) are numbered most left 1 and counting to the right, restarting this count on each new line. For instance: 3-5 means that fields 3, 4 and 5 in all ${SEDE_ROOT_OUT}/secret_master_N files will be in the end results. It is impossible to select the vote code or password present in ${SEDE_ROOT_OUT}/secret_master_N.
It has the vote-codes for each voter on the same line. The line consists of a comma-delimited list of vote-code definitions. A vote-code definition in codespervoter has this format: `POLL-NUMBER:VOTE-CODE;WEIGHT,'. The poll numbers increase to the end of the line. If a voter does not participate in a vote, that definition is absent.
Flags beginning with `sede_' are reserved for future expansions of sede.
${SEDE_LIB}
This variable points to the location of the sede library directory,
which contain commands that can be called through the shell-wrapper
(sede), and some other things in ${SEDE_LIB}/extras/.
${SEDE_VERSION}
This variable holds the current version number.
See also `sede upgrade'.
${SEDE_ENVIRONMENT_SET}
This variable signals that the sede environment has been set. Sede
library commands abort if it doesn't have the correct magic content:
`Sre9:D8pkeM'. This is a safeguard. Running sede commands
outside a proper sede environment may result in the recursive deleting
of all files in your home directory. (See also the
${SEDE_ROOT_*} group of variables.)
SEDE_ENVIRONMENT_SET="Sre9:D8pkeM"
${SEDE_USERCHECK_LICENSE}
If this variable has the value "no", then new users who are
using `sede checkout` to install their initial installation,
which is required to using most sede commands, are not asked
to interactively approve of the license and no-warranty situation for
the program. If it is anything but "no", they'll be asked to
agree before user defaults are installed. This variable is not
present in the environment as most are.
${SEDE_X_CAT}
${SEDE_X_CHMOD}
${SEDE_X_CP}
${SEDE_X_DATE}
${SEDE_X_DC}
${SEDE_X_ECHO}
${SEDE_X_ED}
${SEDE_X_FALSE}
${SEDE_X_FILE}
${SEDE_X_GREP}
${SEDE_X_HEAD}
${SEDE_X_LN}
${SEDE_X_LS}
${SEDE_X_LYNX}
${SEDE_X_MAIL}
${SEDE_X_MKDIR}
${SEDE_X_MV}
${SEDE_X_READ}
${SEDE_X_RM}
${SEDE_X_SED}
${SEDE_X_SORT}
${SEDE_X_TAIL}
${SEDE_X_TAR}
${SEDE_X_TEE}
${SEDE_X_TEST}
${SEDE_X_TRUE}
${SEDE_X_UNIQ}
${SEDE_X_WC}
${SEDE_X_ZIP}
The $PATH programs sede needs.
The latest part of the variable name after the latest underscore `_',
contains the name under which the service is normally known.
The exception is: ${SEDE_X_ZIP_EXT}, it contains the extension the
in ${SEDE_X_ZIP} defined program uses, for instance ".gz" for
gzip.
Sede commands written in shell-language (almost) never directly access system programs (system commands like ls, cat, chmod), but go through the above variables to find the needed service. This abstraction gives the system administrator the power to use a different program for the wider system, but point /etc/sede to a version that works with sede if there is a mismatch between system and sede needs.
Example: suppose the version of dc on a system has a different output format then where sede is developed for. Hence sede won't work properly. Installing a version of dc that does work, in some directory (doesn't have to be in the $path ofcourse) and pointing SEDE_X_DC=/usr/local/somedir/somewhere/dc should cause that version to be used instead, while not affecting the whole system.
Commands return `false` (1) on error, 30 if ${SEDE_ENVIRONMENT_SET} was unequal to its magic string, or the return value of the final command it executed. The ballots command (which generates ballots for makes) has more return values. makes will report these return values if non-zero. Some commands may also produce other return values (notably continue), see documentation there.
ballots return values:
"sede shell" When giving a command containing a double quoted newline `\\n', the command is incorrectly absorbed by the history buffers and log file.
"sede shell --SHELL" is dodgy. Sometimes the PATH of the original environment isn't copied by the new shell process, causing sede commands to not be in the path. Users may want to use "% . sede set.path" instead, which accomplishes the same as "sede shell --SHELL".
See `sede show [c|w]', or the file `Licence' in the source package for the complete text.
BECAUSE THIS PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. THE COPYRIGHT HOLDERS PROVIDES THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.