]> git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/binpatch.cc
Initial revision
[thirdparty/pdns.git] / pdns / binpatch.cc
1 /*
2 PowerDNS Versatile Database Driven Nameserver
3 Copyright (C) 2002 PowerDNS.COM BV
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19 #include <iostream>
20 #include <cstdio>
21 #include <cstring>
22 #include <cstdlib>
23 #include <unistd.h>
24 #include <errno.h>
25 #include <climits>
26 #include <string>
27 #include <map>
28 #include <sys/mman.h>
29 #include <fcntl.h>
30 #include <sys/types.h>
31
32 #include <sys/stat.h>
33
34
35 using namespace std;
36
37 static void imbue(char *pname, const char *search, const string &replace);
38 static string stringerror();
39 static off_t filesize(int fd);
40
41 int main(int argc, char **argv)
42 {
43 if(argc!=3) {
44 cerr<<"Syntax: binpatch binary configuration-directory"<<endl;
45 exit(0);
46 }
47
48 imbue(argv[1],"!@@SYSCONFDIR@@:",argv[2]);
49 }
50
51 static void imbue(char *pname, const char *search, const string &replace)
52 {
53 int fd=open(pname, O_RDWR);
54 if(fd<0) {
55 cerr<<"Unable to open executable read/write for imbuing: "<<stringerror()<<endl;
56 exit(1);
57 }
58 int fs=filesize(fd);
59 void *ptr=mmap(0,fs,PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
60 if(ptr==(caddr_t)-1) {
61 cerr<<"Unable to mmap executable read/write for imbuing: "<<stringerror()<<endl;
62 exit(1);
63 }
64
65 char *p=(char *)ptr;
66 char *end=p+fs;
67 for(;p<end;++p)
68 if(*p==*search && *(p+1)==*(search+1) && !memcmp(p,search,strlen(search)))
69 break;
70
71 if(p==end) {
72 cerr<<"Cannot find marker in binary, not imbueing"<<endl;
73 exit(1);
74 }
75 strcpy(p+strlen(search),replace.c_str());
76 munmap(ptr,filesize(fd));
77 close(fd);
78 cerr<<"Imbued configuration location '"<<replace<<"'"<<endl;
79 return;
80 }
81
82 static off_t filesize(int fd)
83 {
84 struct stat buf;
85 fstat(fd, &buf);
86 return buf.st_size;
87 }
88 static string stringerror()
89 {
90 return strerror(errno);
91 }