Compare commits

...
3 Commits
8 changed files with 216 additions and 51 deletions

No files matched your search

+18
View File
@@ -24,6 +24,24 @@ version 2.61
Add --host-record. Thanks to Rob Zwissler for the Add --host-record. Thanks to Rob Zwissler for the
suggestion. suggestion.
Invoke the DHCP script with action "tftp" when a TFTP file
transfer completes. The size of the file, address to which
it was sent and complete pathname are supplied. Note that
version 2.60 introduced some script incompatibilties
associated with DHCPv6, and this is a further change. To
be safe, scripts should ignore unknown actions, and if
not IPv6-aware, should exit if the environment
variable DNSMASQ_IAID is set. The use-case for this is
to track netboot/install. Suggestion from Shantanu
Gadgil.
Update contrib/port-forward/dnsmasq-portforward to reflect
the above.
Set the environment variable DNSMASQ_LOG_DHCP when running
the script id --log-dhcp is in effect, so that script can
taylor their logging verbosity. Suggestion from Malte Forkel.
version 2.60 version 2.60
Fix compilation problem in Mac OS X Lion. Thanks to Olaf Fix compilation problem in Mac OS X Lion. Thanks to Olaf
+10
View File
@@ -34,11 +34,21 @@ if [ ${DNSMASQ_OLD_HOSTNAME} ] && [ ${action} = old ] ; then
hostname=${DNSMASQ_OLD_HOSTNAME} hostname=${DNSMASQ_OLD_HOSTNAME}
fi fi
# IPv6 leases are not our concern. no NAT there!
if [ ${DNSMASQ_IAID} ] ; then
exit 0
fi
# action init is not relevant, and will only be seen when leasefile-ro is set. # action init is not relevant, and will only be seen when leasefile-ro is set.
if [ ${action} = init ] ; then if [ ${action} = init ] ; then
exit 0 exit 0
fi fi
# action tftp is not relevant.
if [ ${action} = tftp ] ; then
exit 0
fi
if [ ${hostname} ]; then if [ ${hostname} ]; then
ports=$(sed -n -e "/^${hostname}\ .*/ s/^.* //p" ${PORTSFILE}) ports=$(sed -n -e "/^${hostname}\ .*/ s/^.* //p" ${PORTSFILE})
+44 -13
View File
@@ -576,14 +576,14 @@ for details. Instead, the keyword
.B ra-names .B ra-names
may be used. This does the same at ra-only, but also enables a mode may be used. This does the same at ra-only, but also enables a mode
which gives DNS names to dual-stack hosts which do SLAAC for which gives DNS names to dual-stack hosts which do SLAAC for
IPv6. Dnsmasq uses the hosts IPv4 lease to derive the name, network IPv6. Dnsmasq uses the host's IPv4 lease to derive the name, network
segment and MAC address and assumes that the host will also have an segment and MAC address and assumes that the host will also have an
IPv6 address calculated using the SLAAC alogrithm, on the same network IPv6 address calculated using the SLAAC alogrithm, on the same network
segment. An AAAA record is added to the DNS for this IPv6 segment. The address is pinged, and if a reply is received, an AAAA
record is added to the DNS for this IPv6
address. Note that this is only happens for directly-connected address. Note that this is only happens for directly-connected
networks, (not one doing DHCP via a relay) and it will generate an networks, (not one doing DHCP via a relay) and it will not work
erroneous AAAA record if a host is using privacy extensions or does if a host is using privacy extensions.
not support IPv6. Use with care.
The interface:<interface name> section is not normally used. See the The interface:<interface name> section is not normally used. See the
NOTES section for details of this. NOTES section for details of this.
@@ -1069,7 +1069,8 @@ re-intialised. The enterprise-id is assigned by IANA, and the uid is a
string of hex octets unique to a particular device. string of hex octets unique to a particular device.
.TP .TP
.B \-6 --dhcp-script=<path> .B \-6 --dhcp-script=<path>
Whenever a new DHCP lease is created, or an old one destroyed, the Whenever a new DHCP lease is created, or an old one destroyed, or a
TFTP file transfer completes, the
executable specified by this option is run. <path> executable specified by this option is run. <path>
must be an absolute pathname, no PATH search occurs. must be an absolute pathname, no PATH search occurs.
The arguments to the process The arguments to the process
@@ -1119,6 +1120,8 @@ is known.
DNSMASQ_TAGS contains all the tags set during the DNSMASQ_TAGS contains all the tags set during the
DHCP transaction, separated by spaces. DHCP transaction, separated by spaces.
DNSMASQ_LOG_DHCP is set if --log-dhcp is in effect.
For IPv4 only: For IPv4 only:
DNSMASQ_CLIENT_ID if the host provided a client-id. DNSMASQ_CLIENT_ID if the host provided a client-id.
@@ -1145,6 +1148,8 @@ only supplied for
since these data are not held in dnsmasq's lease since these data are not held in dnsmasq's lease
database. database.
All file descriptors are All file descriptors are
closed except stdin, stdout and stderr which are open to /dev/null closed except stdin, stdout and stderr which are open to /dev/null
(except in debug mode). (except in debug mode).
@@ -1163,6 +1168,17 @@ all existing leases as they are read from the lease file. Expired
leases will be called with "del" and others with "old". When dnsmasq leases will be called with "del" and others with "old". When dnsmasq
receives a HUP signal, the script will be invoked for existing leases receives a HUP signal, the script will be invoked for existing leases
with an "old " event. with an "old " event.
There are two further actions which may appear as the first argument
to the script, "init" and "tftp". More may be added in the future, so
scripts should be written to ignore unknown actions. "init" is
decsribed below in
.B --leasefile-ro
The "tftp" action is invoked when a TFTP file transfer completes: the
arguments are the file size in bytes, the address to which the file
was sent, and the complete pathname of the file.
.TP .TP
.B --dhcp-luascript=<path> .B --dhcp-luascript=<path>
Specify a script written in Lua, to be run when leases are created, Specify a script written in Lua, to be run when leases are created,
@@ -1176,11 +1192,13 @@ function, and may provide
and and
.B shutdown .B shutdown
functions, which are called, without arguments when dnsmasq starts up functions, which are called, without arguments when dnsmasq starts up
and terminates. and terminates. It may also provide a
.B tftp
function.
The The
.B lease .B lease
method receives the information detailed in function receives the information detailed in
.B --dhcp-script. .B --dhcp-script.
It gets two arguments, firstly the action, which is a string It gets two arguments, firstly the action, which is a string
containing, "add", "old" or "del", and secondly a table of tag value containing, "add", "old" or "del", and secondly a table of tag value
@@ -1198,6 +1216,15 @@ for IPv4, and
and and
.B hostname .B hostname
for IPv6. for IPv6.
The
.B tftp
function is called in the same way as the lease function, and the
table holds the tags
.B destination_address,
.B file_name
and
.B file_size.
.TP .TP
.B --dhcp-scriptuser .B --dhcp-scriptuser
Specify the user as which to run the lease-change script or Lua script. This defaults to root, but can be changed to another user using this flag. Specify the user as which to run the lease-change script or Lua script. This defaults to root, but can be changed to another user using this flag.
@@ -1292,13 +1319,17 @@ only a subset of this is needed, and dnsmasq can handle it, using
existing DHCP configuration to provide most data. When RA is enabled, existing DHCP configuration to provide most data. When RA is enabled,
dnsmasq will advertise a prefix for each dhcp-range, with default dnsmasq will advertise a prefix for each dhcp-range, with default
router and recursive DNS server as the relevant link-local address on router and recursive DNS server as the relevant link-local address on
the machine running dnsmasq. The "managed address" bits are set, the machine running dnsmasq. The "managed address" bits are set, and
except for a dhcp-range which is marked as "ra-only", in which case RA the "use SLAAC" bit is reset, except for a dhcp-range which is
is provided but no DHCPv6 service and the managed address bits are marked as "ra-only" or "ra-names", in which case RA is provided but no
cleared. DHCPv6 service and the managed address bits are
cleared and the "use SLAAC" bit set. If the same subnet appears in a
normal dhcp-range and an "ra-only" dhcp-range, then the "managed
address" bits and the "use SLAAC" bits are all set, allowing SLAAC and
DHCP address to co-exist on the same subnet.
.B enable-ra .B enable-ra
enables router advertisement for prefixes where dnsmasq is doing enables router advertisement for prefixes where dnsmasq is doing
DHCPv6. It is not needed to "ra-only" prefixes. Creating an "ra-only" DHCPv6. It is not needed for "ra-only" prefixes. Creating an "ra-only"
prefix and not setting prefix and not setting
.B enable-ra .B enable-ra
sends advertisements only to "ra-only" prefixes. sends advertisements only to "ra-only" prefixes.
+13 -12
View File
@@ -23,7 +23,6 @@ struct daemon *daemon;
static volatile pid_t pid = 0; static volatile pid_t pid = 0;
static volatile int pipewrite; static volatile int pipewrite;
static int alarm_queued = 0;
static int set_dns_listeners(time_t now, fd_set *set, int *maxfdp); static int set_dns_listeners(time_t now, fd_set *set, int *maxfdp);
static void check_dns_listeners(fd_set *set, time_t now); static void check_dns_listeners(fd_set *set, time_t now);
@@ -722,6 +721,10 @@ int main (int argc, char **argv)
# ifdef HAVE_SCRIPT # ifdef HAVE_SCRIPT
while (helper_buf_empty() && do_script_run(now)); while (helper_buf_empty() && do_script_run(now));
# ifdef HAVE_TFTP
while (helper_buf_empty() && do_tftp_script_run());
# endif
if (!helper_buf_empty()) if (!helper_buf_empty())
{ {
FD_SET(daemon->helperfd, &wset); FD_SET(daemon->helperfd, &wset);
@@ -730,6 +733,11 @@ int main (int argc, char **argv)
# else # else
/* need this for other side-effects */ /* need this for other side-effects */
while (do_script_run(now)); while (do_script_run(now));
# ifdef HAVE_TFTP
while (do_tftp_script_run());
# endif
# endif # endif
#endif #endif
@@ -868,20 +876,14 @@ static void sig_handler(int sig)
/* now == 0 -> queue immediate callback */ /* now == 0 -> queue immediate callback */
void send_alarm(time_t event, time_t now) void send_alarm(time_t event, time_t now)
{ {
if (now == 0 || event != 0)
if (now != 0 && event == 0) {
return; /* alarm(0) or alarm(-ve) doesn't do what we want.... */
if ((now == 0 || difftime(event, now) <= 0.0)) if ((now == 0 || difftime(event, now) <= 0.0))
{
if (!alarm_queued)
{
send_event(pipewrite, EVENT_ALARM, 0, NULL); send_event(pipewrite, EVENT_ALARM, 0, NULL);
alarm_queued = 1;
}
}
else else
alarm((unsigned)difftime(event, now)); alarm((unsigned)difftime(event, now));
}
} }
void send_event(int fd, int event, int data, char *msg) void send_event(int fd, int event, int data, char *msg)
@@ -995,7 +997,6 @@ static void async_event(int pipe, time_t now)
break; break;
case EVENT_ALARM: case EVENT_ALARM:
alarm_queued = 0;
#ifdef HAVE_DHCP #ifdef HAVE_DHCP
if (daemon->dhcp || daemon->dhcp6) if (daemon->dhcp || daemon->dhcp6)
{ {
+7 -2
View File
@@ -458,6 +458,7 @@ struct frec {
#define ACTION_OLD_HOSTNAME 2 #define ACTION_OLD_HOSTNAME 2
#define ACTION_OLD 3 #define ACTION_OLD 3
#define ACTION_ADD 4 #define ACTION_ADD 4
#define ACTION_TFTP 5
#define LEASE_NEW 1 /* newly created */ #define LEASE_NEW 1 /* newly created */
#define LEASE_CHANGED 2 /* modified */ #define LEASE_CHANGED 2 /* modified */
@@ -803,7 +804,7 @@ extern struct daemon {
#endif #endif
/* TFTP stuff */ /* TFTP stuff */
struct tftp_transfer *tftp_trans; struct tftp_transfer *tftp_trans, *tftp_done_trans;
/* utility string buffer, hold max sized IP address as string */ /* utility string buffer, hold max sized IP address as string */
char *addrbuff; char *addrbuff;
@@ -1035,11 +1036,14 @@ void emit_dbus_signal(int action, struct dhcp_lease *lease, char *hostname);
#endif #endif
/* helper.c */ /* helper.c */
#if defined(HAVE_DHCP) && !defined(NO_FORK) #if defined(HAVE_SCRIPT)
int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd); int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd);
void helper_write(void); void helper_write(void);
void queue_script(int action, struct dhcp_lease *lease, void queue_script(int action, struct dhcp_lease *lease,
char *hostname, time_t now); char *hostname, time_t now);
#ifdef HAVE_TFTP
void queue_tftp(off_t file_len, char *filename, union mysockaddr *peer);
#endif
int helper_buf_empty(void); int helper_buf_empty(void);
#endif #endif
@@ -1047,6 +1051,7 @@ int helper_buf_empty(void);
#ifdef HAVE_TFTP #ifdef HAVE_TFTP
void tftp_request(struct listener *listen, time_t now); void tftp_request(struct listener *listen, time_t now);
void check_tftp_listeners(fd_set *rset, time_t now); void check_tftp_listeners(fd_set *rset, time_t now);
int do_tftp_script_run(void);
#endif #endif
/* conntrack.c */ /* conntrack.c */
+92 -19
View File
@@ -193,16 +193,22 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
_exit(0); _exit(0);
} }
is6 = !!(data.flags & (LEASE_TA | LEASE_NA));
if (data.action == ACTION_DEL) if (data.action == ACTION_DEL)
action_str = "del"; action_str = "del";
else if (data.action == ACTION_ADD) else if (data.action == ACTION_ADD)
action_str = "add"; action_str = "add";
else if (data.action == ACTION_OLD || data.action == ACTION_OLD_HOSTNAME) else if (data.action == ACTION_OLD || data.action == ACTION_OLD_HOSTNAME)
action_str = "old"; action_str = "old";
else if (data.action == ACTION_TFTP)
{
action_str = "tftp";
is6 = (data.flags != AF_INET);
}
else else
continue; continue;
is6 = !!(data.flags & (LEASE_TA | LEASE_NA));
if (!is6) if (!is6)
{ {
@@ -271,6 +277,8 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
char *dot; char *dot;
hostname = (char *)buf; hostname = (char *)buf;
hostname[data.hostname_len - 1] = 0; hostname[data.hostname_len - 1] = 0;
if (data.action != ACTION_TFTP)
{
if (!legal_hostname(hostname)) if (!legal_hostname(hostname))
hostname = NULL; hostname = NULL;
else if ((dot = strchr(hostname, '.'))) else if ((dot = strchr(hostname, '.')))
@@ -279,6 +287,7 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
*dot = 0; *dot = 0;
} }
} }
}
extradata = buf + data.hostname_len; extradata = buf + data.hostname_len;
@@ -289,8 +298,32 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
inet_ntop(AF_INET6, &data.hwaddr, daemon->addrbuff, ADDRSTRLEN); inet_ntop(AF_INET6, &data.hwaddr, daemon->addrbuff, ADDRSTRLEN);
#endif #endif
/* file length */
if (data.action == ACTION_TFTP)
sprintf(daemon->dhcp_buff, "%u", data.hwaddr_len);
#ifdef HAVE_LUASCRIPT #ifdef HAVE_LUASCRIPT
if (daemon->luascript) if (daemon->luascript)
{
if (data.action == ACTION_TFTP)
{
lua_getglobal(lua, "tftp");
if (lua_type(lua, -1) != LUA_TFUNCTION)
lua_pop(lua, 1); /* tftp function optional */
else
{
lua_pushstring(lua, action_str); /* arg1 - action */
lua_newtable(lua); /* arg2 - data table */
lua_pushstring(lua, daemon->addrbuff);
lua_setfield(lua, -2, "destination_address");
lua_pushstring(lua, hostname);
lua_setfield(lua, -2, "file_name");
lua_pushstring(lua, daemon->dhcp_buff);
lua_setfield(lua, -2, "file_size");
lua_call(lua, 2, 0); /* pass 2 values, expect 0 */
}
}
else
{ {
lua_getglobal(lua, "lease"); /* function to call */ lua_getglobal(lua, "lease"); /* function to call */
lua_pushstring(lua, action_str); /* arg1 - action */ lua_pushstring(lua, action_str); /* arg1 - action */
@@ -400,6 +433,7 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
lua_call(lua, 2, 0); /* pass 2 values, expect 0 */ lua_call(lua, 2, 0); /* pass 2 values, expect 0 */
} }
}
#endif #endif
/* no script, just lua */ /* no script, just lua */
@@ -439,6 +473,8 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
continue; continue;
} }
if (data.action != ACTION_TFTP)
{
if (is6) if (is6)
{ {
my_setenv("DNSMASQ_IAID", daemon->dhcp_buff3, &err); my_setenv("DNSMASQ_IAID", daemon->dhcp_buff3, &err);
@@ -513,6 +549,10 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
my_setenv("DNSMASQ_OLD_HOSTNAME", hostname, &err); my_setenv("DNSMASQ_OLD_HOSTNAME", hostname, &err);
hostname = NULL; hostname = NULL;
} }
}
if (option_bool(OPT_LOG_OPTS))
my_setenv("DNSMASQ_LOG_DHCP", "1", &err);
/* we need to have the event_fd around if exec fails */ /* we need to have the event_fd around if exec fails */
if ((i = fcntl(event_fd, F_GETFD)) != -1) if ((i = fcntl(event_fd, F_GETFD)) != -1)
@@ -584,11 +624,29 @@ static unsigned char *grab_extradata_lua(unsigned char *buf, unsigned char *end,
} }
#endif #endif
static void buff_alloc(size_t size)
{
if (size > buf_size)
{
struct script_data *new;
/* start with reasonable size, will almost never need extending. */
if (size < sizeof(struct script_data) + 200)
size = sizeof(struct script_data) + 200;
if (!(new = whine_malloc(size)))
return;
if (buf)
free(buf);
buf = new;
buf_size = size;
}
}
/* pack up lease data into a buffer */ /* pack up lease data into a buffer */
void queue_script(int action, struct dhcp_lease *lease, char *hostname, time_t now) void queue_script(int action, struct dhcp_lease *lease, char *hostname, time_t now)
{ {
unsigned char *p; unsigned char *p;
size_t size;
unsigned int hostname_len = 0, clid_len = 0, ed_len = 0; unsigned int hostname_len = 0, clid_len = 0, ed_len = 0;
int fd = daemon->dhcpfd; int fd = daemon->dhcpfd;
@@ -608,23 +666,7 @@ void queue_script(int action, struct dhcp_lease *lease, char *hostname, time_t n
if (hostname) if (hostname)
hostname_len = strlen(hostname) + 1; hostname_len = strlen(hostname) + 1;
size = sizeof(struct script_data) + clid_len + ed_len + hostname_len; buff_alloc(sizeof(struct script_data) + clid_len + ed_len + hostname_len);
if (size > buf_size)
{
struct script_data *new;
/* start with reasonable size, will almost never need extending. */
if (size < sizeof(struct script_data) + 200)
size = sizeof(struct script_data) + 200;
if (!(new = whine_malloc(size)))
return;
if (buf)
free(buf);
buf = new;
buf_size = size;
}
buf->action = action; buf->action = action;
buf->flags = lease->flags; buf->flags = lease->flags;
@@ -669,6 +711,37 @@ void queue_script(int action, struct dhcp_lease *lease, char *hostname, time_t n
bytes_in_buf = p - (unsigned char *)buf; bytes_in_buf = p - (unsigned char *)buf;
} }
#ifdef HAVE_TFTP
/* This nastily re-uses DHCP-fields for TFTP stuff */
void queue_tftp(off_t file_len, char *filename, union mysockaddr *peer)
{
unsigned int filename_len;
/* no script */
if (daemon->helperfd == -1)
return;
filename_len = strlen(filename) + 1;
buff_alloc(sizeof(struct script_data) + filename_len);
memset(buf, 0, sizeof(struct script_data));
buf->action = ACTION_TFTP;
buf->hostname_len = filename_len;
buf->hwaddr_len = file_len;
if ((buf->flags = peer->sa.sa_family) == AF_INET)
buf->addr = peer->in.sin_addr;
#ifdef HAVE_IPV6
else
memcpy(buf->hwaddr, &peer->in6.sin6_addr, IN6ADDRSZ);
#endif
memcpy((unsigned char *)(buf+1), filename, filename_len);
bytes_in_buf = sizeof(struct script_data) + filename_len;
}
#endif
int helper_buf_empty(void) int helper_buf_empty(void)
{ {
return bytes_in_buf == 0; return bytes_in_buf == 0;
+12 -4
View File
@@ -206,7 +206,7 @@ static void send_ra(int iface, char *iface_name, struct in6_addr *dest)
ra->type = ND_ROUTER_ADVERT; ra->type = ND_ROUTER_ADVERT;
ra->code = 0; ra->code = 0;
ra->hop_limit = hop_limit; ra->hop_limit = hop_limit;
ra->flags = 0; ra->flags = 0x00;
ra->lifetime = htons(1800); /* AdvDefaultLifetime*/ ra->lifetime = htons(1800); /* AdvDefaultLifetime*/
ra->reachable_time = 0; ra->reachable_time = 0;
ra->retrans_time = 0; ra->retrans_time = 0;
@@ -246,7 +246,7 @@ static void send_ra(int iface, char *iface_name, struct in6_addr *dest)
/* set managed bits unless we're providing only RA on this link */ /* set managed bits unless we're providing only RA on this link */
if (parm.managed) if (parm.managed)
ra->flags = 0xc0; ra->flags = 0xc0; /* M flag, managed, O flag, other */
/* decide where we're sending */ /* decide where we're sending */
memset(&addr, 0, sizeof(addr)); memset(&addr, 0, sizeof(addr));
@@ -293,7 +293,11 @@ static int add_prefixes(struct in6_addr *local, int prefix,
is_same_net6(local, &context->start6, prefix) && is_same_net6(local, &context->start6, prefix) &&
is_same_net6(local, &context->end6, prefix)) is_same_net6(local, &context->end6, prefix))
{ {
if (!(context->flags & CONTEXT_RA_ONLY)) int do_slaac = 0;
if (context->flags & CONTEXT_RA_ONLY)
do_slaac = 1;
else
{ {
/* don't do RA for non-ra-only unless --enable-ra is set */ /* don't do RA for non-ra-only unless --enable-ra is set */
if (!option_bool(OPT_RA)) if (!option_bool(OPT_RA))
@@ -317,6 +321,10 @@ static int add_prefixes(struct in6_addr *local, int prefix,
is_same_net6(local, &tmp->start6, prefix) && is_same_net6(local, &tmp->start6, prefix) &&
is_same_net6(local, &tmp->end6, prefix)) is_same_net6(local, &tmp->end6, prefix))
{ {
/* if any dhcp-range with ra-only on this subnet
set the "do_slaac" bit */
if (tmp->flags & CONTEXT_RA_ONLY)
do_slaac = 1;
tmp->flags |= CONTEXT_RA_DONE; tmp->flags |= CONTEXT_RA_DONE;
context->ra_time = 0; context->ra_time = 0;
} }
@@ -335,7 +343,7 @@ static int add_prefixes(struct in6_addr *local, int prefix,
opt->len = 4; opt->len = 4;
opt->prefix_len = prefix; opt->prefix_len = prefix;
/* autonomous only is we're not doing dhcp */ /* autonomous only is we're not doing dhcp */
opt->flags = (context->flags & CONTEXT_RA_ONLY) ? 0xc0 : 0x00; opt->flags = do_slaac ? 0x40 : 0x00;
opt->valid_lifetime = opt->preferred_lifetime = htonl(time); opt->valid_lifetime = opt->preferred_lifetime = htonl(time);
opt->reserved = 0; opt->reserved = 0;
+20 -1
View File
@@ -571,7 +571,9 @@ void check_tftp_listeners(fd_set *rset, time_t now)
my_syslog(MS_TFTP | LOG_INFO, _("sent %s to %s"), transfer->file->filename, daemon->addrbuff); my_syslog(MS_TFTP | LOG_INFO, _("sent %s to %s"), transfer->file->filename, daemon->addrbuff);
/* unlink */ /* unlink */
*up = tmp; *up = tmp;
free_transfer(transfer); /* put on queue to be sent to script and deleted */
transfer->next = daemon->tftp_done_trans;
daemon->tftp_done_trans = transfer;
continue; continue;
} }
} }
@@ -709,4 +711,21 @@ static ssize_t get_block(char *packet, struct tftp_transfer *transfer)
} }
} }
int do_tftp_script_run(void)
{
struct tftp_transfer *transfer;
if ((transfer = daemon->tftp_done_trans))
{
daemon->tftp_done_trans = transfer->next;
#ifdef HAVE_SCRIPT
queue_tftp(transfer->file->size, transfer->file->filename, &transfer->peer);
#endif
free_transfer(transfer);
return 1;
}
return 0;
}
#endif #endif