| 1 | This script patches an Exim binary in order to change the compiled-in |
| 2 | configuration file name. See FAQ 0065 for a situation in which this might |
| 3 | be a useful thing to do. |
| 4 | |
| 5 | ============================================================ |
| 6 | #!/usr/local/bin/perl |
| 7 | # |
| 8 | # Patch the config file location in exim so as to avoid using |
| 9 | # exim -C and thus having problems with vacation messages etc. |
| 10 | # |
| 11 | # Placed in the public domain. |
| 12 | |
| 13 | # This is the default in exim RPMS. |
| 14 | my $oldconf = "/etc/exim/exim4.conf"; |
| 15 | |
| 16 | die "Usage: $0 infile outfile configfile\n" unless (@ARGV == 3); |
| 17 | my ($in, $out, $newconf) = @ARGV; |
| 18 | |
| 19 | # We mustn't make our string longer than the original! |
| 20 | die "configfile location must be ".length($oldconf)." chars long or less\n" |
| 21 | if (length($newconf) > length($oldconf)); |
| 22 | |
| 23 | # Get original details. |
| 24 | my @stat = (stat($in)); |
| 25 | die "stat($in): $!\n" if (@stat == 0); |
| 26 | |
| 27 | # Get original binary. |
| 28 | open(F, "<$in") || die "Can't read $in\n"; |
| 29 | read(F, $exim, $stat[7]) || die "Can't read $in\n"; |
| 30 | die "Didn't read full data\n" unless (length($exim) == $stat[7]); |
| 31 | close(F); |
| 32 | |
| 33 | # Find the old config location. |
| 34 | my $pos = 0; |
| 35 | my @positions = (); |
| 36 | while (($pos = index($exim, $oldconf."\0", $pos)) >= 0) |
| 37 | { |
| 38 | print "Config file name found at byte offset $pos\n"; |
| 39 | push(@positions, $pos); |
| 40 | $pos++; |
| 41 | } |
| 42 | |
| 43 | die "Old config location ($oldconf) not found\n" if (@positions == 0); |
| 44 | |
| 45 | # We could be clever here and try to isolate the correct instance, |
| 46 | # but for now I'm going to assume it's the only instance. |
| 47 | die "Too many possible config locations found\n" if (@positions > 1); |
| 48 | |
| 49 | # Patch in the new config location |
| 50 | substr($exim, $positions[0], length($newconf)+1) = $newconf."\0"; |
| 51 | |
| 52 | # Write out the patched version. |
| 53 | open(F, ">$out") || die "Can't write $out\n"; |
| 54 | print F $exim; |
| 55 | close(F); |
| 56 | |
| 57 | # Set permissions on new copy to match old. |
| 58 | chmod($stat[2] & 07777, $out); |
| 59 | |
| 60 | # Print the config file path. |
| 61 | $out = "./".$out unless ($out =~ m#/#); |
| 62 | print <<EOF; |
| 63 | |
| 64 | Trying to run '$out -bP configure_file'. If it has worked |
| 65 | either it will be printed below or you will get a LOG: MAIN PANIC |
| 66 | about it (if the config file doesn't already exist) |
| 67 | |
| 68 | EOF |
| 69 | system($out, "-bP", "configure_file"); |
| 70 | ============================================================ |