chiark-utils.git/0000755000000000000000000000000012246177227011137 5ustar chiark-utils.git/scripts/0000775000000000000000000000000012246176602012624 5ustar chiark-utils.git/scripts/palm-datebook-reminders0000775000000000000000000000770011663220254017256 0ustar #!/usr/bin/perl # Copyright 2003 Ian Jackson # # This script and its documentation (if any) are free software; you # can redistribute it and/or modify them under the terms of the GNU # General Public License as published by the Free Software Foundation; # either version 3, or (at your option) any later version. # # chiark-named-conf and its manpage are distributed in the hope that # it will be useful, but WITHOUT ANY WARRANTY; without even the # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR # PURPOSE. See the GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, consult the Free Software Foundation's # website at www.fsf.org, or the GNU Project website at www.gnu.org. use Palm::PDB; use Palm::Datebook; use Time::Local; use POSIX; $us= $0 =~ m,[^/]+$, ? $& : $0; $detail= 86400*2; $lookforward= 86400*(7*4+1); # run at 15:00 daily sub setfilename($) { die "$us: only one filename at a time please\n" if defined $filename; $filename= $_[0]; } while (@ARGV) { $_= shift @ARGV; if (m,^(?:\-t)?(\d+)/(\d+)$,) { ($detail,$lookforward)=($1+0,$2+0); } elsif (m,^[./],) { setfilename($_); } elsif (m/^\-f/) { setfilename($'); } else { die "$us: unknown argument/option \`$_'\n"; } } $filename= "DatebookDB.pdb" if !defined $filename; defined($now= time) or die $!; stat $filename or die "$us: $filename: $!\n"; $backuptime= (stat _)[10]; $pdb = new Palm::PDB or die $!; $pdb->Load($filename) or die $!; foreach $record (@{ $pdb->{records} }) { if ($record->{start_hour} != 255) { $timestr= sprintf("%02d:%02d-%02d:%02d", $record->{start_hour}, $record->{start_minute}, $record->{end_hour}, $record->{end_minute}); @lt=(0, $record->{start_minute}, $record->{start_hour}); } else { @lt=(0, 0, 9); $timestr= " "; } if ($record->{repeat}{type}) { $timestr= "onwards "; } push @lt, $record->{day}, $record->{month}-1, $record->{year}-1900; defined($ettt= timelocal @lt) or die $!; next if ($ettt < $now - 86400 || $ettt > $now + $lookforward); @lt2= localtime($ettt) or die $!; defined($dowstr= strftime "%a", @lt2) or die $!; $datestr= sprintf("%04d-%02d-%02d", $record->{year}, $record->{month}, $record->{day}); $timesortkey= "$datestr $timestr"; $evhead= "$datestr $dowstr $timestr"; $desc= $record->{description}; $desc =~ s/\x93/\~/g; $desc =~ s/\xa3/L/g; $desc =~ s/[^\n -\176]/ sprintf "\\x%02x", ord $& /eg; $desc =~ s/^ +//; $desc =~ s/\n+$//; $desc .= "\n"; if ($desc =~ m/^(.{0,51})\n/) { $descsumm= $1; } elsif ($desc =~ m/^.{48}/) { $descsumm= $&.'...'; } else { $descsumm= " --- no description ?! ---"; } $kind= $ettt < $now + $detail ? 'detail' : 'forward'; push @{ $events{$kind} }, { TSK => $timesortkey, Headline => sprintf("%s %s", $evhead, $descsumm), Desc => $desc }; } sub sectline_detail(){ return "Imminent events"; } sub sectline_forward(){ return "Forthcoming events"; } sub headline(){ printf("%s\n", $ev->{Headline}) or die $!; } sub print_forward(){ headline(); } sub print_detail(){ print "\n" or die $!; headline(); $_= $ev->{Desc}; s/^/ /gm; print $_ or die $!; } foreach $kind (qw(detail forward)) { $sectline= &{"sectline_$kind"}; printf("%s\n%s\n", $sectline, '-'x(length $sectline)) or die $!; if (!@{ $events{$kind} }) { printf("None scheduled.\n") or die $!; } foreach $ev (sort { $a->{TSK} cmp $b->{TSK} } @{ $events{$kind} }) { &{"print_$kind"}; } print "\n" or die $!; } @lt2= localtime $backuptime or die $!; defined ($syncstr= strftime "%Y-%m-%d %a %H:%M", @lt2) or die $!; print("Date of last synch: $syncstr\n". "Events entered on PDA after this date are omitted.\n") or die $!; close STDOUT or die $!; chiark-utils.git/scripts/named-conf.80000664000000000000000000005337211663220254014731 0ustar .\" Hey, Emacs! This is an -*- nroff -*- source file. .TH CHIARK\-NAMED\-CONF 8 "12th January 2002" "Greenend" "chiark utilities" .SH NAME chiark\-named\-conf \- check and generate nameserver configuration .SH SYNOPSIS .BR chiark\-named\-conf " [\fIoptions\fP] " \-n | \-y | \-f .br \fBchiark\-named\-conf\fP [\fIoptions\fP] \fIzone ...\fP .SH DESCRIPTION .B chiark\-named\-conf is a tool for managing nameserver configurations and checking for suspected DNS problems. Its main functions are to check that delegations are appropriate and working, that secondary zones are slaved from the right places, and to generate a configuration for .BR BIND , from its own input file. By default, for each zone, in addition to any warnings, the output lists the zone's configuration type. If the zone is checked, the serial number at each of the nameservers is shown, with any unpublished primary having .B * after the serial number. .SH OPTIONS .SS MODE OPTIONS If one of the options .BR -n ", " -y ", or " -f is supplied then chiark-named-conf will read its main configuration file for the list of relevant zones. It will then check the configuration and delegation for each zone and/or generate and install a new configuration file for the nameserver: .TP .BR \-y | \-\-yes Generate and install new nameserver config, as well as checking configuration, for all listed zones. .TP .BR \-n | \-\-no Check configuration, for all listed zones, but do not generate new nameserver config. .TP .BR \-f | \-\-force Generate and install new nameserver config, without doing any configuration cross-checking. (Syntax errors in our input configuration will still abort this operation.) .TP .BR \-\-nothing Do nothing: do no checks, and don't write a new config. This can be used to get a list of the zones being processed. .TP .BR \-\-mail\-first " | " \-\-mail\-middle " | " \-\-mail\-final Send mails to zone SOA MNAMEs reporting zones with problems. You must call chiark\-named\-conf at least twice, once with \-\-mail\-first, and later with \-\-mail\-final, and preferably with one or more calls to \-\-mail\-middle in between. All three options carry out a check and store the results; \-\-mail\-final also sends a mail to the zone SOA MNAME or local administrator, if too many of the calls had errors or warnings (calls before the most recent \-\-mail\-first being ignored). .TP .B \-mail\-final\-test just like \-\-mail\-final except that it always sends mail to the local server admin and never to remote zone contacts, adding .B (testing!) to the start of the To: field. .LP Alternatively, one or more zone names may be supplied as arguments, in which case their delegations will be checked, and compared with the data for that zone in the main configuration (if any). In this case no new configuration file for the nameserver will be made. .SS ADDITIONAL OPTIONS .TP .BR \-A | \-\-all Checks even zones known to be broken. Ie, ignores the .B ? zone style modifier in the configuration. .TP .BR \-C | \-\-config " \fIconfig\-file\fP" Use .I config\-file instead of .BR /etc/bind/chiark-conf-gen.zones . Also changes the default directory. .TP .BR \-D Enables debugging. Useful for debugging chiark\-named\-conf, but probably not useful for debugging your DNS configuration. Repeat to increase the debugging level. (Maximum is .BR -DD .) .TP .BR \-g | \-\-glueless Do not warn about glueless referrals (strictly, makes the zone style modifier .B ~ the default). Not recommended - see the section GLUELESSNESS, below. .TP .BR \-l | \-\-local Only checks for mistakes which are the responsibility of the local administrator (to fix or get fixed). This means that for published and stealth zones we only check that we're slaving from the right place and that any names and addresses for ourself are right. For primary zones all checks are still done. It is a mistake to specify .B \-l with foreign zones (zones supplied explictly on the command line but not relevant to the local server); doing so produces a warning. .TP .BI \-m group !*$@~? Overrides a .B modifiers directive in the configuration file. The modifiers specified in the directive are completely replaced by those specified in this command line option. (Note that modifiers specified in per-zone directives still override these per-group settings.) If more than one .B modifiers directive specifies the same group, they are all affected. .B modifiers directives which don't specify a group cannot be affected. It is an error if the group does not appear in the config file. See ZONE STYLE MODIFIERS, below. .PP The special group .B foreign is used for zones which don't appear in the configuration file. .TP .BR \-q | \-\-quiet Suppress the usual report of the list of nameservers for each zone and the serial number from each. When specified twice, do not print any information except warnings. .TP .BR \-r | \-\-repeat When a problem is detected, warn for all sources of the same imperfect data, rather than only the first we come across .TP .BR \-v | \-\-verbose Print additional information about what is being checked, as we go along. .SH USAGE The file .B /etc/bind/chiark-conf-gen.zones (or other file specified with the .B \-C option) contains a sequence of directives, one per line. Blank lines are permitted. Leading and trailing whitespace on each line is ignored. Comments are lines starting with .BR # . Ending a line with a .BR \\ joins it to the next line, so that long directives can be split across several physical lines. .SS GENERAL DIRECTIVES These directives specify general configuration details. They should appear before directives specifying zones, as each will affect only later zone directives. Foreign zones (zones explicitly specified on the command line but not mentioned in the configuration) use the configuration settings prevailing at the end of the config file. .TP \fBadmin\fP \fIemail\-address\fP Specifies the email address of the local administrator. This is used in the From: line of mails sent out, and will also receive copies of the reports. There is no default. .TP \fBdefault\-dir\fP \fIdirectory\fP Makes .I directory be the default directory (which affects the interpretation of relative filenames). The default is the directory containing the main configuration file, ie .BR /etc/bind if no .B -C option is specified. .TP \fBforbid\-addr\fP [\fIip-address ...\fP] Specifies the list of addresses that are forbidden as any nameserver for any zone. The default is no such addresses. .TP \fBforbid\-addr\fP [\fIip-address ...\fP] Specifies the list of addresses that are forbidden as a nameserver for a zone for which we are the primary - ie, the list of our old or to-be-obsoleted slaves. The default is no such addresses. .TP \fBserverless\-glueless\fP \fIdomain ...\fP Specifies a list of domains under which we do not expect to find any nameservers without glue; for these zones it is OK to find glueless referrals. Each domain listed names a complete subtree of the DNS, starting at the named point. The default is .BR "in\-addr.arpa ip6.arpa ip6.int" . To avoid indefinitely long or even circularly glueless referrals (which delay or prevent lookups) it is necessary for all sites to effectively implement similar conventions; currently the author believes that only the reverse lookup namespaces are conventionally devoid of (glueless) nameservers, and therefore fine to provide glueless referrals for. See GLUELESSNESS below. .TP \fBallow-\-indirect\-glue\fP \fInameserver-superdomain ...\fP Specifies a list of domains under which we expect to find glueless nameservers, with up to one layer of indirection. For nameservers under these domains it is OK to to find glueless referrals, but only when listed as a nameserver for a zone which is not itself a subdomain of an \fBallow-indirect-glue\fR \fInameserver-superdomain\fR. This supports to common configuration style where DNS operator(s) set up all of their nameservers with names within a small subsection of the DNS (the portions under \fInameserver-superdomain\fRs), and provide glueless referrals naming these nameservers for all other zones. This provides at most one level of missing glue. Note that if the DNS administrators collectively able to influence the service for some zone (including the admins for its superzones, the zones containing its nameservers, and their superzones and so forth) are not in sufficiently close communication do not all agree on the proper set of \fInameserver-superdomain\fR then they might still set up circular glue and \fBchiark-named-conf\fR would not necessarily be able to detect this even if it was run on every relevant nameserver. .TP \fBmail\-state\-dir\fP \fIdirectory\fP Uses .I directory for storing information about recent failures for mailing to zone admins. See \-\-mail\-first et al. Old files in here should be cleaned up periodically out of cron. There is no default. .TP \fBmail\-max\-warnfreq\fP \fIpercentage\fP When \-\-mail\-final is used, a mail will be sent to all zones which had warnings or errors more than .IR percentage % of the times \-\-mail\-* was used (since the last \-\-mail\-first). The default is 50%. .TP .BR modifiers " " !*$@~? "] [\fIgroup\fP]" Applies the specified zone style modifiers (see below) to subsequently declared zones (until the next .B modifiers directive), as if the modifiers specified were written out for each zone. You must specify at least one character for the modifiers; if you want to reset everything to the default, just say .BR ! . If style modifiers specified in the zone directive conflict with the .B modifiers directive, those specified in the zone directive take effect. .I group may contain alphanumerics and underscores, and is used for the .B -m command-line option. .TP \fBself\-addr\fP \fIip-address ...\fP Specifies the list of addresses that this server may be known by in A records. There is no default. .TP \fBoutput\fP \fIformat\fP \fIfilename\fP [\fIformat\fP \fIfilename ...\fP] Arranges that each .I filename will be overwritten when .BR -y " or " -f are used; its new contents will be configuration directives for the zones which follow for the nameserver in question. Currently the only .I format supported is .B bind8 which indicates new-style BIND 8. If no zones follow, then each file will still be overwritten, by an effectively empty file. Default: if there is no .B output directive in the configuration then the default is to use .BR bind8 " " chiark-conf-gen.bind8 ; otherwise it is an error for there to be any zones in the configuration before the first .B output directive. .TP \fBself\-ns\fP \fIfqdn ...\fP Specifies the list of names that this server may be known by in NS records. There is no default. Any trailing * is replaced by the name of the zone being checked, so for example .B self\-ns isp.ns.* before the zone example.com would mean to expect us to be listed as isp.ns.example.com in the NS RRset. .TP \fBself\-soa\fP \fIfqdn ...\fP Specifies the list of names that this server may be known by in the ORIGIN field of SOA records. There is no default. Any trailing * is replaced by the name of the zone, as for .BR self\-ns . .TP .BI self " fqdn ..." Equivalent to both .B self\-ns " and " self\-soa with the same set of names. .TP \fBslave\-dir\fP \fIdirectory\fP [[\fIprefix\fP] \fIsuffix\fP] Specifies the directory in which slave (published and stealth) zonefiles should be placed. The default .I directory is .BR /var/cache/bind/chiark-slave . The default .IR suffix " and " prefix are empty; they also will be reset to these defaults by a .B slave\-dir directive which does not specify them. .SS ZONE DIRECTIVES These directives specify one or more zones. .TP .BR primary [ !*$@~? "] \fIzone filename\fP" Specifies that this server is supposed to be the primary nameserver for .I zone and that the zone data is to be found in .IR filename . .TP .BR primary\-dir [ !*$@~? "] \fIdirectory\fP[" / "\fIprefix\fP] [\fIsuffix\fP[" / \fIsubfile\fP]] Search .I directory for files whose names start with .I prefix and end with .IR suffix . Each such file is taken to represent a zone file for which this server is supposed to be the primary; the part of the filename between .IR prefix " and " suffix is the name of the zone. If .BI / subfile is specified, then instead of looking for files, we search for directories containing .IR subfile ; directories which do not contain the subfile are simply skipped. If .IR directory [\fB/\fP prefix ] exists as specified and is a directory then it is interpreted as .I directory with an empty prefix; otherwise the final path component is assumed to be the prefix. If no .IB suffix / subfile is specified then the default is .BR _db . .TP .BR published [ !*$@~? "] \fIzone origin\-addr\fP" Specifies that this server is supposed to be a published slave nameserver for the zone in question. .TP .BR stealth [ !*$@~? "] \fIzone server\-addr ...\fP" Specifies that this server is supposed to be an unpublished secondary (aka stealth secondary) for the zone in question. .SS ZONE STYLE MODIFIERS Each of the zone directives may optionally be followed by one or more of the following characters (each at most once): .TP .B ! Reverses the meaning of all style modifiers after the .BR ! . Only one .BR ! must appear in the modifier list. In this list, other modifiers which default to `enabled' are described by describing the effect of their inverse - see the description for .B !@ below. .TP .B * Indicates that the zone is unofficial, ie that it is not delegated as part of the global Internet DNS and that no attempt should be made to find the superzone and check delegations. Note that unofficial, local zones should be created with caution. They should be in parts of the namespace which are reserved for private use, or belong to the actual zone maintainer. .TP .B $ Indicates that any mails should be sent about the zone to the nameserver admin rather than to the zone SOA MNAME. This is the default unless we are supposedly a published server for the zone. .TP .B !@ Indicates that no mails should be sent about the zone to anyone. .TP .B ~ Indicates that the zone's delegation is known to be glueless, and that lack of glue should not be flagged. Not recommended - see the section GLUELESSNESS, below. .TP .B ? Indicates that the zone is known to be broken and no checks should be carried out on it, unless the .B \-A option is specified. .SS OTHER DIRECTIVES .TP \fBinclude\fP \fIfile\fP Reads .I file as if it were included here. .TP \fBend\fP Ends processing of this file; any data beyond this point is ignored. .SH CHECKS chiark\-named\-conf makes the following checks: Delegations: Each delegation from a server for the superzone should contain the same set of nameservers. None of the delegations should lack glue. The glue addresses should be the same in each delegation, and agree with the local default nameserver. Delegated servers: Each server mentioned in the delegation should have the same SOA record (and obviously, should be authoritative). All published nameservers - including delegated servers and servers named in the zone's nameserver set: All nameservers for the zone should supply the same list of nameservers for the zone, and none of this authority information should be glueless. All the glue should always give the same addresses. Origin server's data: The set of nameservers in the origin server's version of the zone should be a superset of those in the delegations. Our zone configuration: For primary zones, the SOA origin should be one of the names specified with .BR self\-soa " (or " self ). For published zones, the address should be that of the SOA origin. For stealth zones, the address should be that of the SOA origin or one of the published nameservers. .SH GLUELESSNESS Glue is the name given for the addresses of nameservers which are often supplied in a referral. In fact, it turns out that it is important for the reliability and performance of the DNS that referrals, in general, always come with glue. Firstly, glueless referrals usually cause extra delays looking up names. BIND 8, when it receives a completely glueless referral and does not have the nameservers' addresses in its cache, will start queries for the nameserver addresses; but it will throw the original client's question away, so that when these queries arrive, it won't restart the query from where it left off. This means that the client won't get its answer until it retries, typically at least 1 second later - longer if you have more than one nameserver listed. Worse, if the nameserver to which the glueless referral points is itself under another glueless referral, another retry will be required. Even for better resolvers than BIND 8, long chains of glueless referrals can cause performance and reliability problems, turning a simple two or three query exchange into something needing more than a dozen queries. Even worse, one might accidentally create a set of circularly glueless referrals such as .br .B example.com NS ns0.example.net.uk .br .B example.com NS ns1.example.net.uk .br .B example.net.uk NS ns0.example.com .br .B example.net.uk NS ns1.example.com .br Here it is impossible to look up anything in either example.com or example.net.uk. There are, as far as the author is aware, no generally agreed conventions or standards for avoiding unreasonably long glueless chains, or even circular glueless situations. The only way to guarantee that things will work properly is therefore to always supply glue. However, the situation is further complicated by the fact that many implementations (including BIND 8.2.3, and many registry systems), will refuse to accept glue RRs for delegations in a parent zonefile unless they are under the parent's zone apex. In these cases it can be necessary to create names for the child's nameservers which are underneath the child's apex, so that the glue records are both in the parent's bailiwick and obviously necessary. In the past, the `shared registry system' managing .com, .net and .org did not allow a single IPv4 address to be used for more than one nameserver name. However, at the time of writing (October 2002) this problem seems to have been fixed, and the workaround I previously recommended (creating a single name for your nameserver somewhere in .com, .net or .org, and using that for all the delegations from .com, .net and .org) should now be avoided. Finally, a note about `reverse' zones, such as those in in-addr.arpa: It does not seem at all common practice to create nameservers in in-addr.arpa zones (ie, no NS RRs seem to point into in-addr.arpa, even those for in-addr.arpa zones). Current practice seems to be to always use nameservers for in-addr.arpa which are in the normal, forward, address space. If everyone sticks to the rule of always publishing nameservers names in the `main' part of the namespace, and publishing glue for them, there is no chance of anything longer than a 1-step glueless chain might occur for a in-addr.arpa zone. It is probably best to maintain this as the status quo, despite the performance problem this implies for BIND 8 caches. This is what the serverless\-glueless directive is for. Dan Bernstein has some information and examples about this at .UR http://cr.yp.to/djbdns/notes.html#gluelessness http://cr.yp.to/djbdns/notes.html#gluelessness .UE but be warned that it is rather opinionated. .SS GLUELESSNESS SUMMARY I recommend that every nameserver should have its own name in every forward zone that it serves. For example: .br .B zone.example.com NS servus.ns.example.com .br .B servus.ns.example.com A 127.0.0.2 .br .B 2.0.0.127.in-addr.arpa PTR servus.example.net .br .B servus.example.net A 127.0.0.2 .LP Domain names in .B in-addr.arpa should not be used in the right hand side of NS records. .SH SECURITY chiark\-named\-conf is supposed to be resistant to malicious data in the DNS. It is not resistant to malicious data in its own options, configuration file or environment. It is not supposed to read its stdin, but is not guaranteed to be safe if stdin is dangerous. .LP Killing chiark-named-conf suddenly should be safe, even with .BR -y " or " -f (though of course it may not complete its task if killed), provided that only one invocation is made at once. .LP Slow remote nameservers will cause chiark-named-conf to take excessively long. .SH EXIT STATUS .TP .B 0 All went well and there were no warnings. .TP any other There were warnings or errors. .SH FILES .TP .B /etc/bind/chiark-conf-gen.zones Default input configuration file. (Override with .BR -C .) .TP .B /etc/bind Default directory. (Override with .BR -C " or " default\-dir .) .TP .IB dir /chiark-conf-gen.bind8 Default output file. .TP .B /var/cache/bind/chiark-slave Default location for slave zones. .SH ENVIRONMENT .LP Setting variables used by .BR dig (1) and .BR adnshost (1) will affect the operation of chiark\-named\-conf. Avoid messing with these if possible. .LP .B PATH is used to find subprograms such as .BR dig " and " adnshost . .SH BUGS The determination of the parent zone for each zone to be checked, and its nameservers, is done simply using the system default nameserver. The processing of output from .B dig is not very reliable or robust, but this is mainly the fault of dig. This can lead to somewhat unhelpful error reporting for lookup failures. .SH AUTHOR .B chiark\-named\-conf and this manpage were written by Ian Jackson . They are Copyright 2002 Ian Jackson. chiark\-named\-conf and this manpage are free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, consult the Free Software Foundation's website at www.fsf.org, or the GNU Project website at www.gnu.org. chiark-utils.git/scripts/hexterm0000775000000000000000000001544311663220254014230 0ustar #!/usr/bin/tclsh8.4 set comment { # Use of the screen: 0 1 2 3 4 5 6 7 xxxE hh hh hh hh hh hh hh hh hh hh hh hh hh hh hh hh_| abcd e_.. .... ...._| } # Display: # | is a vertical delimiter # E is either | to mean echo is on or ' to mean it is off # hh are hex digits of output: # 00-ff actual hex data (bold for stuff we entered) # 0-f under cursor: one digit entered, need the next # abcde_.... are ASCII output: # . things we can't print including SPC and _ # in both, we may see # space we haven't yet filled # _ cursor when in other tab # xxx number of bytes read/written so far # Keystrokes: # TAB switch between hex and literal mode # ^C, ^D quit # ^Z suspend # Keystrokes in hex mode only: # RET move to a new line; if already at start of line, # set count to 0 # DEL clear any entered hex digit # SPC send 00 # ' toggle echo # nyi: # G-Z record last bytes we transmitted and store in memory # if we were halfway through a hex byte, first digit # is length of string to record # g-z play back memory # Copyright 2005 Ian Jackson # # This script and its documentation (if any) are free software; you # can redistribute it and/or modify them under the terms of the GNU # General Public License as published by the Free Software Foundation; # either version 3, or (at your option) any later version. # # chiark-named-conf and its manpage are distributed in the hope that # it will be useful, but WITHOUT ANY WARRANTY; without even the # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR # PURPOSE. See the GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, consult the Free Software Foundation's # website at www.fsf.org, or the GNU Project website at www.gnu.org. if {[llength $argv] != 1} { error "need serial port arg" } set port [lindex $argv 0] set count 0 set lit 0 ;# 1 means literal (ASCII) entry mode set echo 1 proc p {s} { puts -nonewline $s } proc tput {args} { global tput if {[catch { set s $tput($args) }]} { set s [eval exec tput $args] set tput($args) $s } p $s } proc csr_pos {lit bytenum} { set x [expr { (!$lit ? (3*$bytenum) : 53+$bytenum) + ($bytenum>>2) - (2-$lit)*($bytenum==16) + 5 }] tput hpa $x } proc csr_this {} { global lit x; csr_pos $lit $x } proc csr_other {} { global lit x; csr_pos [expr {!$lit}] $x } proc csrs_erase {} { csr_this; p " "; csr_other; p " " } proc csr_this_show {} { global h1 csr_this; if {[info exists h1]} { p $h1; p "\b" } } proc csrs_show {} { csr_other; p _ csr_this_show } proc echop {} { global echo return [expr {$echo ? "|" : "'"}] } proc newline {} { global x echo count if {[info exists x]} { csrs_erase; p "\r\n" } set x 0 p [format "%3x%s%*s|%*s|" $count [echop] 52 "" 21 ""] csrs_show } proc p_ch_spaces {} { global x lit if {$x==15} return if {$lit} { p " " } if {($x & 3) != 3} return p " " } proc p_rmso {smso} { if {[string length $smso]} { tput sgr0 } } proc ch {d smso} { global lit x count if {$x == 16} newline if {[string length $smso]} { tput $smso } set h [format %02x [expr {$d & 0xff}]] set c [format %c [expr {($d > 33 && $d < 127 && $d != 95) ? $d : 46}]] if {$lit} { p $c; csr_other; p $h p_ch_spaces p_rmso $smso p _ } else { p $h; csr_other; p $c p_ch_spaces p_rmso $smso p _ } incr x set count [expr {($count+1) & 0xfff}] csr_this_show } proc onreadp {} { global p while 1 { set c [read $p 1] binary scan $c c* d if {![llength $d]} { if {[eof $p]} { error "eof on device" } return } ch $d {} } } proc transmit {d} { global p echo puts -nonewline $p [format %c $d] if {$echo} { ch $d bold } } proc k_echo {} { global echo set echo [expr {!$echo}] tput hpa 3 p [echop] csr_this } proc k_newline {} { global count x if {$x} { newline } else { set count 0 p "\r" p [format %3x $count] csr_this } } proc k_switch {} { global lit h1 csrs_erase catch { unset h1 } set lit [expr {!$lit}] csrs_show } proc k_stop {} { restore exit 0 } proc k_suspend {} { restore exec kill -TSTP [info pid] setup } proc k_noparthex {} { global h1 csrs_erase catch { unset h1 } csrs_show } proc k_hexdigit {c} { global h1 echo if {![info exists h1]} { set h1 $c; p $c; p "\b"; return } set d [expr 0x${h1}${c}] unset h1 transmit $d if {!$echo} { p " \b" } } proc onreadk {} { global lit while 1 { set c [read stdin 1] binary scan $c c* d if {![llength $d]} { if {[eof stdin]} { error "eof on stdin" } return } switch -exact $d { 9 { k_switch; continue } 3 - 4 { k_stop; continue } 26 { k_suspend; continue } } if {$lit} { transmit $d; continue } switch -exact $d { 13 { k_newline; continue } 32 { transmit 0; continue } 39 { k_echo; continue } 127 { k_noparthex; continue } } if {$d >= 48 && $d <= 57} { k_hexdigit $c; continue } set kl [expr {$d | 32}] if {$d >= 97 && $d <= 102} { k_hexdigit $c; continue } p "\a" } } proc try {script} { if {[catch { uplevel 1 $script } emsg]} { catch { puts stderr "(warning: $emsg)" } } } proc tryv {variable script} { upvar #0 $variable var if {![info exists var]} return uplevel 1 " global $variable $script " unset var } proc restore {} { tryv x { puts "\r\n" } try { fconfigure stdin -blocking true } try { fconfigure stdout -blocking true } tryv term_stty { exec stty $term_stty } tryv p { close $p } } proc setup {} { global term_stty port p set term_stty [exec stty -g] set p [open $port {RDWR NONBLOCK} 0] exec stty min 1 time 0 -istrip -ocrnl -onlcr -onocr -opost \ -ctlecho -echo -echoe -echok -echonl -iexten -isig \ -icanon -icrnl exec stty -F $port min 1 time 0 -istrip -ocrnl -onlcr -onocr -opost \ -ctlecho -echo -echoe -echok -echonl -iexten -isig \ -icanon -icrnl \ 9600 clocal cread -crtscts -hup -parenb cs8 -cstopb \ -ixoff bs0 cr0 ff0 nl0 -ofill -olcuc fconfigure $p -blocking false -buffering none -encoding binary \ -translation binary fconfigure stdin -blocking false -buffering none -translation binary fconfigure stdout -blocking false -buffering none -translation binary newline fileevent stdin readable onreadk fileevent $p readable onreadp } proc bgerror {m} { try { restore global errorInfo errorCode puts stderr "$m\n$errorCode\n$errorInfo" } exit 127 } if {[catch setup emsg]} { restore error $emsg $errorInfo $errorCode } vwait quit chiark-utils.git/scripts/cvs-adjustroot0000775000000000000000000000245611663220254015543 0ustar #!/bin/bash set -e usage () { echo >&2 'usage: cvs-adjustroot OLD NEW'; exit 1; } case "$#.$1" in 4.--reinvoke) reinvoke=true; shift ;; *.-*) usage ;; 2.*) reinvoke=false ;; 1.*) usage ;; 0.*) usage ;; *) usage ;; esac # Copyright 2004 Ian Jackson # # This script and its documentation (if any) are free software; you # can redistribute it and/or modify them under the terms of the GNU # General Public License as published by the Free Software Foundation; # either version 3, or (at your option) any later version. # # chiark-named-conf and its manpage are distributed in the hope that # it will be useful, but WITHOUT ANY WARRANTY; without even the # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR # PURPOSE. See the GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, consult the Free Software Foundation's # website at www.fsf.org, or the GNU Project website at www.gnu.org. old="$1"; shift new="$1"; shift if $reinvoke; then filename="$1"; cmp -- "$filename" <(printf "%s\n" "$old") printf "%s\n" "$new" >"$filename".new mv -f -- "$filename".new "$filename" exit 0 fi find -path '*/CVS/Root' -exec cvs-adjustroot --reinvoke "$old" "$new" '{}' ';' chiark-utils.git/scripts/git-cache-proxy0000775000000000000000000003073212246176602015562 0ustar #!/usr/bin/perl -w # # git caching proxy # Suitable only for exposing to semi-trusted clients: clients are not # supposed to be able to take over the server. However, clients can # probably deny service to each other because the current # implementation is not very good at handling various out-of-course # situations (notably, clients which are too slow). # usage: run it on some port, and then clone or fetch # "git://:/[ ]" # where is http:///... or git:///... # and is zero or more (whitespace-separated) of # [] will be ignored if not recognised # {} error if not recognised # options currently known: # fetch=must fail if the fetch/clone from upstream fails # fetch=no just use what is in the cache # fetch=try use what is in the cache if the fetch/clone fails # timeout= length of time to allow for fetch/clone # example inetd.conf line: # 9419 stream tcp nowait git-cache /usr/bin/git-cache-proxy git-cache-proxy # you'll need to # adduser git-cache # mkdir /var/cache/git-cache-proxy # chown git-cache /var/cache/git-cache-proxy # git-cache-proxy # Copyright 2010 Tony Finch # Copyright 2013 Ian Jackson # # git-cache-proxy is free software; you can redistribute it and/or # modify them under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 3, or (at # your option) any later version. # # git-cache-proxy is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, consult the Free Software Foundation's # website at www.fsf.org, or the GNU Project website at www.gnu.org. # # (Some code taken from userv-utils's git-daemon.in and git-service.in # which were written by Tony Finch and subsequently # heavily modified by Ian Jackson # and were released under CC0 1.0. The whole program is now GPLv3+.) use strict; use warnings; use POSIX; use Socket; use Sys::Syslog; use Fcntl qw(:flock SEEK_SET); use File::Path qw(remove_tree); our $us = 'git-cache-proxy'; our $debug = 0; our $housekeepingeverydays = 1; our $treeexpiredays = 21; our $fetchtimeout = 1800; our $maxfetchtimeout = 3600; our $cachedir = '/var/cache/git-cache-proxy'; our $housekeepingonly = 0; #---------- error handling and logging ---------- # This is a bit fiddly, because we want to catch errors sent to stderr # and dump them to syslog if we can, but only if we are running as an # inetd service. our $log; # filehandle (ref), or "1" meaning syslog sub ntoa { my $sockaddr = shift; return ('(local)') unless defined $sockaddr; my ($port,$addr) = sockaddr_in $sockaddr; $addr = inet_ntoa $addr; return ("[$addr]:$port",$addr,$port); } our ($client) = ntoa getpeername STDIN; our ($server) = ntoa getsockname STDIN; sub ensurelog () { return if $log; openlog $us, qw(pid), 'daemon'; $log = 1; } sub logm ($$) { my ($pri, $msg) = @_; return if $pri eq 'debug' && !$debug; if ($client eq '(local)') { print STDERR "$us: $pri: $msg\n" or die $!; return; } ensurelog(); my $mainmsg = sprintf "%s-%s: %s", $server, $client, $msg; if (ref $log) { my $wholemsg = sprintf("%s [%d] %s: %s\n", strftime("%Y-%m-%d %H:%M:%S Z", gmtime), $$, $pri eq 'err' ? 'error' : $pri, $mainmsg); print $log $wholemsg; } else { syslog $pri, "%s", "$pri $mainmsg"; } } if ($client ne '(local)') { open STDERR, ">/dev/null" or exit 255; open TEMPERR, "+>", undef or exit 255; open STDERR, ">&TEMPERR" or exit 255; } END { if ($client ne '(local)') { if ($?) { logm 'crit', "crashing ($?)"; } seek TEMPERR, 0, SEEK_SET; while () { chomp; logm 'crit', $_; } } exit $?; } sub fail ($) { my ($msg) = @_; logm 'err', $msg; exit 0; } sub gitfail ($) { my ($msg) = @_; close LOCK; alarm 60; logm 'notice', $msg; my $gitmsg = "ERR $us: $msg"; $gitmsg = substr($gitmsg,0,65535); # just in case printf "%04x%s", length($gitmsg)+4, $gitmsg; flush STDOUT; exit 0; } #---------- argument parsing ---------- for (;;) { last unless @ARGV; last unless $ARGV[0] =~ m/^-/; $_ = shift @ARGV; for (;;) { last unless m/^-./; if (s/^-H/-/) { $housekeepingonly++; } elsif (s/^-D/-/) { $debug++; } elsif (s/^-L(.*)$//) { my $logfile = $_; open STDERR, ">>", $logfile or fail "open $logfile: $!"; $log = \*STDERR; } elsif (s/^-d(.*)$//) { $cachedir = $1; } elsif (s/^--( max-fetch-timeout | fetch-timeout | tree-expire-days | housekeeping-interval-days )=(\d+)$//x) { my $vn = $1; $vn =~ y/-//d; die $vn unless defined ${ $::{$vn} }; ${ $::{$vn} } = $2; } else { fail "bad usage: unknown option `$_'"; } } } !@ARGV or fail "bad usage: no non-option arguments permitted"; #---------- utility functions ---------- sub lockfile ($$$) { my ($fh, $fn, $flockmode) = @_; my $what = $fn.(($flockmode & ~LOCK_NB) == LOCK_SH ? " (shared)" : ""); for (;;) { close $fh; open $fh, '+>', $fn or fail "open/create $fn for lock: $!"; logm 'debug', "lock $what: acquiring"; if (!flock $fh, $flockmode) { if ($flockmode & LOCK_NB && $! == EWOULDBLOCK) { return 0; # ok then } fail "lock $what: $!"; } stat $fh or fail "stat opened $fn: $!"; my $fh_ino = ((stat _)[1]); if (!stat $fn) { $! == ENOENT or fail "stat $fn: $!"; next; } my $fn_ino = ((stat _)[1]); if ($fn_ino == $fh_ino) { logm 'debug', "lock $what: acquired"; return 1; } logm 'debug', "lock $what: deleted, need to loop again"; # oh dear } } sub xread { my $length = shift; my $buffer = ""; while ($length > length $buffer) { my $ret = sysread STDIN, $buffer, $length, length $buffer; fail "expected $length bytes, got ".length $buffer if defined $ret and $ret == 0; fail "read: $!" if not defined $ret and $! != EINTR and $! != EAGAIN; } return $buffer; } #---------- main program ---------- chdir $cachedir or fail "chdir $cachedir: $!"; our ($service,$specpath,$spechost,$subdir); our ($tmpd,$gitd,$lock); our ($fetch,$url); sub servinfo ($) { my ($msg) = @_; logm 'info', "service `$specpath': $msg"; } sub readcommand () { $SIG{ALRM} = sub { fail "timeout" }; alarm 30; my $hex_len = xread 4; fail "Bad hex in packet length" unless $hex_len =~ m|^[0-9a-fA-F]{4}$|; my $line = xread -4 + hex $hex_len; unless (($service,$specpath,$spechost) = $line =~ m|^(git-[a-z-]+) /*([!-~ ]+)\0host=([!-~]+)\0$|) { $line =~ s|[^ -~]+| |g; gitfail "unknown/unsupported instruction `$line'" } alarm 0; $service eq 'git-upload-pack' or gitfail "unknown/unsupported service `$service'"; $fetch = 2; # 0:don't; 1:try; 2:force $url = $specpath; while ($url =~ s#\s+(\[)([^][{}]+)\]$## || $url =~ s#\s+(\{)([^][{}]+)\}$##) { $_ = $2; my $must = $1 eq '{'; if (m/^fetch=try$/) { $fetch = 1; } elsif (m/^fetch=no$/) { $fetch = 0; } elsif (m/^fetch=must$/) { $fetch = 2; # the default } elsif (m/^timeout=(\d+)$/ && $1 >= 1) { $fetchtimeout = $1 <= $maxfetchtimeout ? $1 : $maxfetchtimeout; } elsif ($must) { gitfail "unknown/unsupported option `$_'"; } } $url =~ m{^(?:https?|git)://[-.0-9a-z]+/} or gitfail "unknown/unsupported url scheme or format `$url'"; $subdir = $url; $subdir =~ s|\\|\\\\|g; $subdir =~ s|,|\\,|g; $subdir =~ s|/|,|g; $tmpd= "$subdir\\.tmp"; $gitd= "$subdir\\.git"; $lock = "$subdir\\.lock"; servinfo "locking"; } sub clonefetch () { lockfile \*LOCK, $lock, LOCK_EX; my $exists = lstat $gitd; $exists or $!==ENOENT or fail "lstat $gitd: $!"; our $fetchfail = ''; if ($fetch) { our @cmd; if (!$exists) { system qw(rm -rf --), $tmpd; @cmd = (qw(git clone -q --mirror), $url, $tmpd); servinfo "cloning"; } else { @cmd = (qw(git remote update --prune)); servinfo "fetching"; } my $cmd = "@cmd[0..1]"; my $child = open FETCHERR, "-|"; defined $child or fail "fork: $!"; if (!$child) { if ($exists) { chdir $gitd or fail "chdir $gitd: $!"; } setpgrp or fail "setpgrp: $!"; open STDERR, ">&STDOUT" or fail "redirect stderr: $!"; exec @cmd or fail "exec $cmd[0]: $!"; } my $fetcherr = ''; my $timedout = 0; { local $SIG{ALRM} = sub { servinfo "fetch/clone timeout"; $timedout=1; kill 9, -$child; }; alarm($fetchtimeout); $!=0; { local $/=undef; $fetcherr = ; } !FETCHERR->error or fail "read pipe from fetch/clone: $!"; alarm(10); } kill -9, $child or fail "kill fetch/clone: $!"; $!=0; $?=0; if (!close FETCHERR) { fail "reap fetch/clone: $!" if $!; my $fetchfail = !($? & 255) ? "$cmd died with error exit code ".($? >> 8) : $? != 9 ? "$cmd died due to fatal signa, status $?" : $timedout ? "$cmd timed out (${fetchtimeout}s)" : "$cmd died due to unexpected SIGKILL"; if (length $fetcherr) { $fetchfail .= "\n$fetcherr"; $fetchfail =~ s/\n$//; $fetchfail =~ s{\n}{ // }g; } if ($fetch >= 2) { gitfail $fetchfail; } else { servinfo "fetch/clone failed: $fetchfail"; } } if (!$exists) { rename $tmpd, $gitd or fail "rename fresh $tmpd to $gitd: $!"; $exists = 1; } } else { $fetchfail = 'not attempted'; } if (!$exists) { gitfail "no cached data, and not cloned: $fetchfail"; } servinfo "sharing"; lockfile \*LOCK, $lock, LOCK_SH; # NB releases and relocks if (stat $gitd) { return 1; } $!==ENOENT or fail "stat $gitd: $!"; # Well, err, someone must have taken the lock in between # and garbage collected it. How annoying. return 0; } sub hkfail ($) { my ($msg) = @_; fail "housekeeping: $msg"; } sub housekeeping () { logm 'info', "housekeeping started"; foreach $lock (<[a-z]*\\.lock>) { my $subdir = $lock; $subdir =~ s/\\.lock$//; if (!lstat $lock) { $! == ENOENT or hkfail "$lock: lstat: $!"; next; } if (-M _ <= $treeexpiredays) { logm 'debug', "housekeeping: subdirs $subdir: touched recently"; next; } if (!lockfile \*LOCK, $lock, LOCK_EX|LOCK_NB) { logm 'info', "housekeeping: subdirs $subdir: lock busy, skipping"; next; } logm 'info', "housekeeping: subdirs $subdir: cleaning"; my $ok = 1; foreach my $suffix (qw(tmp git)) { my $dir = "${subdir}\\.$suffix"; my $errs; remove_tree($dir, { safe=>1, error=>\$errs }); if (stat $dir) { $ok = 0; logm 'warning', "housekeeping: $dir: problems with". "deletion prevent cleanup:"; foreach my $err (@$errs) { logm 'info', "problem deleting: $err->[0]: $err->[1]"; } } } if ($ok) { unlink $lock or hkfail "remove $lock: $!"; } } open HS, ">", "Housekeeping.stamp" or hkfail "touch Housekeeping.stamp: $!"; close HS or hkfail "close Housekeeping.stamp: $!"; logm 'info', "housekeeping finished"; } sub housekeepingcheck ($$) { my ($dofork, $force) = @_; if (!$force) { if (!lockfile \*HLOCK, "Housekeeping.lock", LOCK_EX|LOCK_NB) { logm 'debug', "housekeeping lock taken, not running"; close HLOCK; return 0; } } if ($force) { logm 'info', "housekeeping forced"; } elsif (!lstat "Housekeeping.stamp") { $! == ENOENT or fail "lstat Housekeeping.stamp: $!"; logm 'info', "housekeeping not done yet, will run"; } elsif (-M _ <= $housekeepingeverydays) { logm 'debug', "housekeeping done recently"; close HLOCK; return 0; } if ($dofork) { my $child = fork; defined $child or hkfail "fork: $!"; if (!$child) { housekeeping(); exit 0; } } else { housekeeping(); } close HLOCK; return 1; } sub runcommand () { servinfo "serving"; chdir $gitd or fail "chdir $gitd: $!"; exec qw(git-upload-pack --strict --timeout=1000 .) or fail "exec git-upload-pack: $!"; } sub daemonservice () { readcommand(); while (!clonefetch()) { } housekeepingcheck(1,0); runcommand(); } if ($housekeepingonly) { housekeepingcheck(0, $housekeepingonly>=2); } else { daemonservice(); } chiark-utils.git/scripts/remountresizereiserfs0000775000000000000000000000207411663220254017226 0ustar #!/bin/bash # usage: # remountresizereiserfs /mountpoint set -e fail () { echo >&2 "$*"; exit 1; } case "$#.$1" in 1.[^-]*);; *) fail 'bad usage';; esac mp=$1 df=`df -P $mp` dfl2=`printf "%s" "$df" | sed 1d` case "$dfl2" in /dev/*" "[0-9]*" "[0-9]*" "[0-9]*" "[0-9]*"% "/*) dev=${dfl2%% *} mp2=${dfl2##* } if [ "x$mp2" != "x$mp" ]; then fail "mountpoint is $mp2 not $mp"; fi ;; *) fail "could not parse df output" ;; esac dm=/dev/mapper case "$dev" in $dm/*/*) fail "too many path segments in mapper device \`$dev'" ;; $dm/*) lv=${dev#$dm/} lv=${lv//--//} case "$lv" in *-*) ;; *) fail "no single hyphen in mapper device \`$lv'";; esac vg=${lv%%-*} lv=${lv#*-} vg=${vg//\//-} lv=${lv//\//-} devu=/dev/$vg/$lv ;; *) devu=$dev esac lvi=$(lvdisplay -c $devu) vg=${lvi#*:} vg=${vg%%:*} vgsz_kb=${lvi#*:*:*:*:*:*:} vgsz_kb=${vgsz_kb%%:*} dbrfs=$(debugreiserfs $dev) blksz_by=$(printf "%s" "$dbrfs" | egrep '^Blocksize: ' || fail "blocksize?") blksz_by=${blksz_by#*: } vgsz_blk=$(dc -e "$vgsz_kb 1024* $blksz_by /p") echo mount -o remount,resize=$vgsz_blk $mp chiark-utils.git/scripts/cvsweb-list0000775000000000000000000000443511663220254015015 0ustar #!/usr/bin/perl # cvsweb-list # This little program produces a web page listing the cvs repositories # available by ucgi cvsweb. It doesn't really separate code and # configuration, so it's not installed by default with chiark-utils. # This file is part of chiark-utils, a collection of useful programs # used on chiark.greenend.org.uk. # # This file is: # Copyright 2001 Ian Jackson # # This is free software; you can redistribute it and/or modify it under the # terms of the GNU General Public License as published by the Free Software # Foundation; either version 3, or (at your option) any later version. # # This is distributed in the hope that it will be useful, but WITHOUT ANY # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more # details. # # You should have received a copy of the GNU General Public License along # with this program; if not, consult the Free Software Foundation's # website at www.fsf.org, or the GNU Project website at www.gnu.org. print < chiark public CVS

chiark users' public CVS