Check-in [0d7a0b3376]

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Added a "gethostname()" replacement Added "backuppcd_notify()" and related code. No authentication is currently present. Created a small example "notify-server" in Tcl. This server just manipulates the "/etc/hosts" file.
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 0d7a0b337693e371b8a98bff0b120cc2e44e0d54
User & Date: rkeene 2006-03-12 02:10:44
Context
2006-03-12
09:21
Updated the "notify-server" to run in the foreground if Tclx is not available. check-in: 5a2587b0a6 user: rkeene tags: trunk
02:10
Added a "gethostname()" replacement Added "backuppcd_notify()" and related code. No authentication is currently present. Created a small example "notify-server" in Tcl. This server just manipulates the "/etc/hosts" file. check-in: 0d7a0b3376 user: rkeene tags: trunk
2006-03-11
22:02
Changed file_sync to only lseek() when needed Added strsep() replacement code Modified build process to create Win32 binaries on release Added some comments to the sample configuration file Added stub for new configuration option "NotifyServer" Made backuppcd-passwd prompt for a password to be read froms stdin check-in: 33d0a0970f user: rkeene tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to Makefile.in.

21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36


BINS = backuppcd$(EXEEXT) backuppcd-client$(EXEEXT) backuppcd-tar$(EXEEXT) backuppcd-passwd$(EXEEXT) tools/file_sync$(EXEEXT)
LIBS = libbackuppcd$(AREXT) libbackuppc$(AREXT)

all: $(BINS) $(LIBS)

backuppcd$(EXEEXT): Makefile.dep backuppcd.o net.o backuppcd-common.o sha1.o md4.o md5.o backuppcd-auth.o @LIBOBJS@
	$(CC) $(CPPFLAGS) $(CFLAGS) -o backuppcd$(EXEEXT) backuppcd.o net.o backuppcd-common.o sha1.o md4.o md5.o backuppcd-auth.o @LIBOBJS@ $(LDFLAGS)

backuppcd-client$(EXEEXT): Makefile.dep libbackuppcd$(AREXT) libbackuppc$(AREXT) backuppcd-client.o
	$(CC) $(CPPFLAGS) $(CFLAGS) -o backuppcd-client$(EXEEXT) backuppcd-client.o -L. -lbackuppcd -lbackuppc $(LDFLAGS)

backuppcd-tar$(EXEEXT): Makefile.dep backuppcd-tar.o net.o backuppcd-common.o sha1.o @LIBOBJS@
	$(CC) $(CPPFLAGS) $(CFLAGS) -o backuppcd-tar$(EXEEXT) backuppcd-tar.o net.o backuppcd-common.o sha1.o @LIBOBJS@ $(LDFLAGS)








|
|







21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36


BINS = backuppcd$(EXEEXT) backuppcd-client$(EXEEXT) backuppcd-tar$(EXEEXT) backuppcd-passwd$(EXEEXT) tools/file_sync$(EXEEXT)
LIBS = libbackuppcd$(AREXT) libbackuppc$(AREXT)

all: $(BINS) $(LIBS)

backuppcd$(EXEEXT): Makefile.dep backuppcd.o net.o backuppcd-common.o sha1.o md4.o md5.o backuppcd-auth.o backuppcd-notify.o @LIBOBJS@
	$(CC) $(CPPFLAGS) $(CFLAGS) -o backuppcd$(EXEEXT) backuppcd.o net.o backuppcd-common.o sha1.o md4.o md5.o backuppcd-auth.o backuppcd-notify.o @LIBOBJS@ $(LDFLAGS)

backuppcd-client$(EXEEXT): Makefile.dep libbackuppcd$(AREXT) libbackuppc$(AREXT) backuppcd-client.o
	$(CC) $(CPPFLAGS) $(CFLAGS) -o backuppcd-client$(EXEEXT) backuppcd-client.o -L. -lbackuppcd -lbackuppc $(LDFLAGS)

backuppcd-tar$(EXEEXT): Makefile.dep backuppcd-tar.o net.o backuppcd-common.o sha1.o @LIBOBJS@
	$(CC) $(CPPFLAGS) $(CFLAGS) -o backuppcd-tar$(EXEEXT) backuppcd-tar.o net.o backuppcd-common.o sha1.o @LIBOBJS@ $(LDFLAGS)

Changes to backuppcd-common.h.

119
120
121
122
123
124
125




126
127
128
129
#include <fnmatch.h>
#endif
#endif

#ifndef BPC_TCP_PORT
#define BPC_TCP_PORT 874
#endif





int backuppc_mkdir(const char *dir);

#endif







>
>
>
>




119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#include <fnmatch.h>
#endif
#endif

#ifndef BPC_TCP_PORT
#define BPC_TCP_PORT 874
#endif

#ifndef BPC_TCP_NOTIFYPORT
#define BPC_TCP_NOTIFYPORT 899
#endif

int backuppc_mkdir(const char *dir);

#endif

Added backuppcd-notify.c.

























































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#include "compat.h"
#include "net.h"

#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif

#ifndef HOST_NAME_MAX
#define HOST_NAME_MAX 255
#endif

void backuppc_notify(const char *host, const int port, const char *overridehostname) {
	static char *hostname = NULL;
	char cmdbuf[8192], *cmdbuf_p;
	size_t hostname_len;
	ssize_t send_ret;
	int chk_ret;
	int sockfd;

	if (!host || port <= 0) {
		return;
	}

	if (overridehostname) {
		hostname = (char *) overridehostname;
	}

	if (!hostname) {
		hostname_len = HOST_NAME_MAX + 1;
		hostname = malloc(hostname_len);
		if (hostname) {
			chk_ret = gethostname(hostname, hostname_len);
			if (chk_ret < 0) {
				free(hostname);
				hostname = NULL;
			}
		}
	}

	if (!hostname) {
		return;
	}

	sockfd = net_connect_tcp(host, port);
	if (sockfd >= 0) {
		/* XXX: Authentiation ? */

		/* Send hostname */
		chk_ret = snprintf(cmdbuf, sizeof(cmdbuf), "HOST %s\n", hostname);
		if (chk_ret < sizeof(cmdbuf)) {
			cmdbuf_p = cmdbuf;

			while (chk_ret) {
				send_ret = send(sockfd, cmdbuf_p, chk_ret, 0);

				if (send_ret < 0) {
					break;
				}

				cmdbuf_p += send_ret;
				chk_ret -= send_ret;
			}
		}

		net_close(sockfd);
	}

	if (overridehostname) {
		hostname = NULL;
	}

	return;
}

Added backuppcd-notify.h.













>
>
>
>
>
>
1
2
3
4
5
6
#ifndef _BACKUPPCD_NOTIFY_H
#define _BACKUPPCD_NOTIFY_H 1

void backuppc_notify(const char *host, const int port, const char *overridehostname);

#endif

Changes to backuppcd.c.

22
23
24
25
26
27
28

29
30
31
32
33
34
35
 *      backuppcd-bugs@psislidell.com
 */

#include "compat.h"
#include "backuppcd.h"
#include "backuppcd-common.h"
#include "backuppcd-auth.h"

#include "net.h"
#include "sha1.h"
#include "md4.h"
#include "md5.h"

#define DAEMON_RET_SUCCESS 0
#define DAEMON_RET_FAILURE 1







>







22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
 *      backuppcd-bugs@psislidell.com
 */

#include "compat.h"
#include "backuppcd.h"
#include "backuppcd-common.h"
#include "backuppcd-auth.h"
#include "backuppcd-notify.h"
#include "net.h"
#include "sha1.h"
#include "md4.h"
#include "md5.h"

#define DAEMON_RET_SUCCESS 0
#define DAEMON_RET_FAILURE 1
97
98
99
100
101
102
103

104
105
106
107
108
109
110
 * function.
 */
static int backuppc_port = BPC_TCP_PORT;
static uint32_t backuppc_writeblock_size = 32000;
static char *backuppc_updateurl = NULL;
static char *backuppc_binfile = NULL;
static char *backuppc_notifyserv = NULL;


#ifdef _USE_WIN32_
/*
 * Win32 service stuff.
 */
static SC_HANDLE manager = NULL;
static SC_HANDLE service = NULL;







>







98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
 * function.
 */
static int backuppc_port = BPC_TCP_PORT;
static uint32_t backuppc_writeblock_size = 32000;
static char *backuppc_updateurl = NULL;
static char *backuppc_binfile = NULL;
static char *backuppc_notifyserv = NULL;
static int backuppc_notifyport = BPC_TCP_NOTIFYPORT;

#ifdef _USE_WIN32_
/*
 * Win32 service stuff.
 */
static SC_HANDLE manager = NULL;
static SC_HANDLE service = NULL;
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822

2823




2824
2825
2826
2827
2828
2829
2830
		 * Time-out section.  Handle maintenance taks when there is
		 * idle time.
		 */
		if (select_ret == 0) {
			/*
			 * Perform automatic update if available.
			 */
			if (backuppc_updateurl) {
				curr_time = time(NULL);
				if (curr_time >= next_update) {

					backuppc_update(backuppc_updateurl, argc, argv);




					next_update = curr_time + BPC_UPDATE_INTERVAL;
				}
			}

			/*
			 * If clean-up has been requested, perform it now.
			 */







|


>
|
>
>
>
>







2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
		 * Time-out section.  Handle maintenance taks when there is
		 * idle time.
		 */
		if (select_ret == 0) {
			/*
			 * Perform automatic update if available.
			 */
			if (backuppc_updateurl || backuppc_notifyserv) {
				curr_time = time(NULL);
				if (curr_time >= next_update) {
					if (backuppc_updateurl) {
						backuppc_update(backuppc_updateurl, argc, argv);
					}
					if (backuppc_notifyserv) {
						backuppc_notify(backuppc_notifyserv, backuppc_notifyport, NULL);
					}
					next_update = curr_time + BPC_UPDATE_INTERVAL;
				}
			}

			/*
			 * If clean-up has been requested, perform it now.
			 */
3831
3832
3833
3834
3835
3836
3837




3838
3839
3840
3841
3842
3843
3844
	 * We cannot check for a new version at start-up on Windows because it
	 * really messes with the "Services" stuff.  Bummer, man.
	 */
	if (backuppc_updateurl) {
		backuppc_update(backuppc_updateurl, argc, argv);
	}
#endif





#ifndef DEBUG
	/*
	 * If daemon initialization went well, we're no longer needed.
	 */
	if (daemon_init() == DAEMON_RET_SUCCESS) {
		return(EXIT_SUCCESS);







>
>
>
>







3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
	 * We cannot check for a new version at start-up on Windows because it
	 * really messes with the "Services" stuff.  Bummer, man.
	 */
	if (backuppc_updateurl) {
		backuppc_update(backuppc_updateurl, argc, argv);
	}
#endif

	if (backuppc_notifyserv) {
		backuppc_notify(backuppc_notifyserv, backuppc_notifyport, NULL);
	}

#ifndef DEBUG
	/*
	 * If daemon initialization went well, we're no longer needed.
	 */
	if (daemon_init() == DAEMON_RET_SUCCESS) {
		return(EXIT_SUCCESS);

Changes to compat.h.

116
117
118
119
120
121
122



123
124
125
126
127
128
129
#include "ntohll.h"
#endif

#ifndef HAVE_STRSEP
#include "strsep.h"
#endif





#ifdef HAVE_STATFS
/*
 * These constants are used to determine the filesystem type from statfs().
 * Only used under Linux as other statfs() implementations return ftype == 0.
 */
#ifndef NFS_SUPER_MAGIC







>
>
>







116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#include "ntohll.h"
#endif

#ifndef HAVE_STRSEP
#include "strsep.h"
#endif

#ifndef HAVE_GETHOSTNAME
#include "gethostname.h"
#endif

#ifdef HAVE_STATFS
/*
 * These constants are used to determine the filesystem type from statfs().
 * Only used under Linux as other statfs() implementations return ftype == 0.
 */
#ifndef NFS_SUPER_MAGIC

Changes to configure.ac.

13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
AC_AIX
AC_GNU_SOURCE
AC_CHECK_TOOL(AR, ar, true)

AC_CHECK_HEADERS(stdlib.h string.h unistd.h time.h sys/time.h sys/types.h signal.h syslog.h sys/select.h netinet/in.h arpa/inet.h sys/socket.h ssl.h openssl/ssl.h ssl/ssl.h fcntl.h dirent.h ctype.h assert.h endian.h stdarg.h utime.h fnmatch.h sys/vfs.h sys/statfs.h sys/param.h sys/mount.h sys/resource.h limits.h)
AC_HEADER_TIME
AC_CHECK_FUNCS(sysinfo openlog syslog setsid fork fcntl stat lstat lchown symlink readlink signal getenv utime statfs getmntinfo setpriority)
AC_REPLACE_FUNCS(htonll ntohll chown link fnmatch strsep)

DC_DO_NETWORK

dnl Check for various types we use
DC_DO_TYPE(uint64_t, unsigned, 8)
DC_DO_TYPE(int64_t, signed, 8)
DC_DO_TYPE(uint32_t, unsigned, 4)







|







13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
AC_AIX
AC_GNU_SOURCE
AC_CHECK_TOOL(AR, ar, true)

AC_CHECK_HEADERS(stdlib.h string.h unistd.h time.h sys/time.h sys/types.h signal.h syslog.h sys/select.h netinet/in.h arpa/inet.h sys/socket.h ssl.h openssl/ssl.h ssl/ssl.h fcntl.h dirent.h ctype.h assert.h endian.h stdarg.h utime.h fnmatch.h sys/vfs.h sys/statfs.h sys/param.h sys/mount.h sys/resource.h limits.h)
AC_HEADER_TIME
AC_CHECK_FUNCS(sysinfo openlog syslog setsid fork fcntl stat lstat lchown symlink readlink signal getenv utime statfs getmntinfo setpriority)
AC_REPLACE_FUNCS(htonll ntohll chown link fnmatch strsep gethostname)

DC_DO_NETWORK

dnl Check for various types we use
DC_DO_TYPE(uint64_t, unsigned, 8)
DC_DO_TYPE(int64_t, signed, 8)
DC_DO_TYPE(uint32_t, unsigned, 4)

Added gethostname.c.

































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include "compat.h"

/*
 * We may be compiled even if a gethostname() function exists, therefore
 * if we detect that it does exist we should not do anything.
 */
#ifndef HAVE_GETHOSTNAME

#include "gethostname.h"

int gethostname(char *name, size_t len) {
	int retval = -1;
#ifdef _USE_WIN32_
	BOOL gcn_ret;
	char *tmpname;

	tmpname = malloc(len);

	gcn_ret = GetComputerName(tmpname, &len);
	if (gcn_ret) {
		memcpy(name, tmpname, len);
		name[len] = '\0';

		retval = 0;
	}

	free(tmpname);
#endif
	return(retval);
}

#endif

Added gethostname.h.





































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#ifndef _REPL_GETHOSTBYNAME_H
#define _REPL_GETHOSTBYNAME_H

#include "compat.h"

#ifndef HOST_NAME_MAX
#  ifdef _USE_WIN32_
#    ifdef MAX_COMPUTERNAME_LENGTH
#      define HOST_NAME_MAX MAX_COMPUTERNAME_LENGTH
#    endif
#  else
#    define HOST_NAME_MAX 255
#  endif
#endif

int gethostname(char *name, size_t len);

#endif

Added tools/notify-server.











































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
#! /usr/bin/tclsh

package require Tclx

set BackupPCdNotifyServerPort 1899
set Hostfile "/etc/hosts"

proc handle_connection {sock addr port} {
	fileevent $sock readable [list handle_data $sock $addr $port]

	return
}

proc handle_data {sock addr port} {
	if {[eof $sock]} {
		close $sock
		return
	}

	gets $sock line
	set work [split [string trim $line]]
	set cmd [string toupper [lindex $line 0]]
	set arg [join [lrange $line 1 end]]

	switch -- $cmd {
		"HOST" {
			update_host_record $arg $addr
			close $sock
		}
	}

	return
}

proc update_host_record {host addr} {
	set host [string tolower [lindex [split [string trim $host] .] 0]]

	set tmpfile "/tmp/notifyserv-[pid][clock seconds][expr abs([clock clicks])].tmp"
	set bakfile "$::Hostfile.bak"

	set hostsfmtstr {%-23s %s}

	if {$host == ""} {
		return
	}

	catch {
		set fd [open $::Hostfile "r"]
	}
	if {![info exists fd]} {
		return
	}

	catch {
		set ofd [open $tmpfile "w"]
	}
	if {![info exists ofd]} {
		close $fd
		return
	}

	set HostChanged 0
	set FoundHost 0
	while 1 {
		gets $fd line
		if {[eof $fd]} {
			break
		}

		set work [split [string trim [regsub {#.*$} $line {}]] " \t"]
		if {[llength $work] == 0} {
			puts $ofd $line
			continue
		}

		set hf_addr [lindex $work 0]
		set hf_hosts [list]
		foreach hf_host [lrange $work 1 end] {
			set hf_host [string trim $hf_host]
			if {$hf_host == ""} {
				continue
			}

			lappend hf_hosts $hf_host
		}

		if {$hf_addr == $addr} {
			foreach chk_host $hf_hosts {
				if {[string tolower $chk_host] == [string tolower $host]} {
					set FoundHost 1
					break
				}
			}
			if {!$FoundHost} {
				set line [format $hostsfmtstr $addr $host]
				set HostChanged 1
			}
		} else {
			set new_hf_hosts [list]
			foreach chk_host $hf_hosts {
				if {[string tolower $chk_host] == [string tolower $host]} {
					continue
				}
				lappend new_hf_hosts $chk_host
			}

			if {$new_hf_hosts != $hf_hosts} {
				if {[llength $new_hf_hosts] == 0} {
					continue
				}

				set line [format $hostsfmtstr $addr [join $new_hf_hosts]]
				set HostChanged 1
			}
		}

		puts $ofd $line
	}

	if {!$FoundHost} {
		if {!$HostChanged} {
			puts $ofd [format $hostsfmtstr $addr $host]
		}
	}

	close $fd
	close $ofd

	if {$FoundHost} {
		catch {
			file delete -force -- $tmpfile
		}

		return
	}

	catch {
		set hf_attrs [file attributes $::Hostfile]
	}
	catch {
		file delete -force -- $bakfile
	}

	if {[catch {
		file rename -force -- $::Hostfile $bakfile
		file rename -force -- $tmpfile $::Hostfile

		if {[info exists hf_attrs]} {
			eval [list file attributes $::Hostfile] $hf_attrs
		}
	}]} {
		catch {
			file delete -force -- $tmpfile
		}
	}

	return
}

for {set i 0} {$i < 10} {incr i} {
	if {![catch {
		set servfd [socket -server handle_connection $BackupPCdNotifyServerPort]
	} err]} {
		break
	}

	after 1000
}

if {![info exists servfd]} {
	puts $err
	exit 1
}

# Become a daemon
if {[fork] == 0} {
	if {[fork] == 0} {
		cd /
		vwait forever
	}
}

Changes to win32.h.

37
38
39
40
41
42
43

44
45
46
47
48
49
50
#  if defined(HAVE_WINSOCK2_H) && defined(HAVE_LIBWSOCK32)
     /* We have to override the detected configuration
        because it can't detect the network libraries. */
#    define HAVE_GETHOSTBYNAME 1
#    define HAVE_INET_ADDR 1
#    define HAVE_SOCKET 1
#    define HAVE_CONNECT 1

#  endif
#  define sleep(x) Sleep((x) * 1000)
#else
   /* MSVC++ configuration follows (untested) */
#  undef HAVE_UNISTD_H
#  define HAVE_STDLIB_H 1
#  define HAVE_WINDOWS_H 1







>







37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#  if defined(HAVE_WINSOCK2_H) && defined(HAVE_LIBWSOCK32)
     /* We have to override the detected configuration
        because it can't detect the network libraries. */
#    define HAVE_GETHOSTBYNAME 1
#    define HAVE_INET_ADDR 1
#    define HAVE_SOCKET 1
#    define HAVE_CONNECT 1
#    define HAVE_GETHOSTNAME 1
#  endif
#  define sleep(x) Sleep((x) * 1000)
#else
   /* MSVC++ configuration follows (untested) */
#  undef HAVE_UNISTD_H
#  define HAVE_STDLIB_H 1
#  define HAVE_WINDOWS_H 1