1/* dnsmasq is Copyright (c) 2000-2015 Simon Kelley
2
3   This program is free software; you can redistribute it and/or modify
4   it under the terms of the GNU General Public License as published by
5   the Free Software Foundation; version 2 dated June, 1991, or
6   (at your option) version 3 dated 29 June, 2007.
7
8   This program is distributed in the hope that it will be useful,
9   but WITHOUT ANY WARRANTY; without even the implied warranty of
10   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11   GNU General Public License for more details.
12
13   You should have received a copy of the GNU General Public License
14   along with this program.  If not, see <http://www.gnu.org/licenses/>.
15*/
16
17#include "dnsmasq.h"
18
19#ifdef HAVE_TFTP
20
21static struct tftp_file *check_tftp_fileperm(ssize_t *len, char *prefix);
22static void free_transfer(struct tftp_transfer *transfer);
23static ssize_t tftp_err(int err, char *packet, char *mess, char *file);
24static ssize_t tftp_err_oops(char *packet, char *file);
25static ssize_t get_block(char *packet, struct tftp_transfer *transfer);
26static char *next(char **p, char *end);
27static void sanitise(char *buf);
28
29#define OP_RRQ  1
30#define OP_WRQ  2
31#define OP_DATA 3
32#define OP_ACK  4
33#define OP_ERR  5
34#define OP_OACK 6
35
36#define ERR_NOTDEF 0
37#define ERR_FNF    1
38#define ERR_PERM   2
39#define ERR_FULL   3
40#define ERR_ILL    4
41
42void tftp_request(struct listener *listen, time_t now)
43{
44  ssize_t len;
45  char *packet = daemon->packet;
46  char *filename, *mode, *p, *end, *opt;
47  union mysockaddr addr, peer;
48  struct msghdr msg;
49  struct iovec iov;
50  struct ifreq ifr;
51  int is_err = 1, if_index = 0, mtu = 0;
52  struct iname *tmp;
53  struct tftp_transfer *transfer;
54  int port = daemon->start_tftp_port; /* may be zero to use ephemeral port */
55#if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
56  int mtuflag = IP_PMTUDISC_DONT;
57#endif
58  char namebuff[IF_NAMESIZE];
59  char *name = NULL;
60  char *prefix = daemon->tftp_prefix;
61  struct tftp_prefix *pref;
62  struct all_addr addra;
63#ifdef HAVE_IPV6
64  /* Can always get recvd interface for IPv6 */
65  int check_dest = !option_bool(OPT_NOWILD) || listen->family == AF_INET6;
66#else
67  int check_dest = !option_bool(OPT_NOWILD);
68#endif
69  union {
70    struct cmsghdr align; /* this ensures alignment */
71#ifdef HAVE_IPV6
72    char control6[CMSG_SPACE(sizeof(struct in6_pktinfo))];
73#endif
74#if defined(HAVE_LINUX_NETWORK)
75    char control[CMSG_SPACE(sizeof(struct in_pktinfo))];
76#elif defined(HAVE_SOLARIS_NETWORK)
77    char control[CMSG_SPACE(sizeof(unsigned int))];
78#elif defined(IP_RECVDSTADDR) && defined(IP_RECVIF)
79    char control[CMSG_SPACE(sizeof(struct sockaddr_dl))];
80#endif
81  } control_u;
82
83  msg.msg_controllen = sizeof(control_u);
84  msg.msg_control = control_u.control;
85  msg.msg_flags = 0;
86  msg.msg_name = &peer;
87  msg.msg_namelen = sizeof(peer);
88  msg.msg_iov = &iov;
89  msg.msg_iovlen = 1;
90
91  iov.iov_base = packet;
92  iov.iov_len = daemon->packet_buff_sz;
93
94  /* we overwrote the buffer... */
95  daemon->srv_save = NULL;
96
97  if ((len = recvmsg(listen->tftpfd, &msg, 0)) < 2)
98    return;
99
100  /* Can always get recvd interface for IPv6 */
101  if (!check_dest)
102    {
103      if (listen->iface)
104	{
105	  addr = listen->iface->addr;
106	  mtu = listen->iface->mtu;
107	  name = listen->iface->name;
108	}
109      else
110	{
111	  /* we're listening on an address that doesn't appear on an interface,
112	     ask the kernel what the socket is bound to */
113	  socklen_t tcp_len = sizeof(union mysockaddr);
114	  if (getsockname(listen->tftpfd, (struct sockaddr *)&addr, &tcp_len) == -1)
115	    return;
116	}
117    }
118  else
119    {
120      struct cmsghdr *cmptr;
121
122      if (msg.msg_controllen < sizeof(struct cmsghdr))
123        return;
124
125      addr.sa.sa_family = listen->family;
126
127#if defined(HAVE_LINUX_NETWORK)
128      if (listen->family == AF_INET)
129	for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
130	  if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_PKTINFO)
131	    {
132	      union {
133		unsigned char *c;
134		struct in_pktinfo *p;
135	      } p;
136	      p.c = CMSG_DATA(cmptr);
137	      addr.in.sin_addr = p.p->ipi_spec_dst;
138	      if_index = p.p->ipi_ifindex;
139	    }
140
141#elif defined(HAVE_SOLARIS_NETWORK)
142      if (listen->family == AF_INET)
143	for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
144	  {
145	    union {
146	      unsigned char *c;
147	      struct in_addr *a;
148	      unsigned int *i;
149	    } p;
150	    p.c = CMSG_DATA(cmptr);
151	    if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RECVDSTADDR)
152	    addr.in.sin_addr = *(p.a);
153	    else if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RECVIF)
154	    if_index = *(p.i);
155	  }
156
157#elif defined(IP_RECVDSTADDR) && defined(IP_RECVIF)
158      if (listen->family == AF_INET)
159	for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
160	  {
161	    union {
162	      unsigned char *c;
163	      struct in_addr *a;
164	      struct sockaddr_dl *s;
165	    } p;
166	    p.c = CMSG_DATA(cmptr);
167	    if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RECVDSTADDR)
168	      addr.in.sin_addr = *(p.a);
169	    else if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RECVIF)
170	      if_index = p.s->sdl_index;
171	  }
172
173#endif
174
175#ifdef HAVE_IPV6
176      if (listen->family == AF_INET6)
177        {
178          for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
179            if (cmptr->cmsg_level == IPPROTO_IPV6 && cmptr->cmsg_type == daemon->v6pktinfo)
180              {
181                union {
182                  unsigned char *c;
183                  struct in6_pktinfo *p;
184                } p;
185                p.c = CMSG_DATA(cmptr);
186
187                addr.in6.sin6_addr = p.p->ipi6_addr;
188                if_index = p.p->ipi6_ifindex;
189              }
190        }
191#endif
192
193      if (!indextoname(listen->tftpfd, if_index, namebuff))
194	return;
195
196      name = namebuff;
197
198      addra.addr.addr4 = addr.in.sin_addr;
199
200#ifdef HAVE_IPV6
201      if (listen->family == AF_INET6)
202	addra.addr.addr6 = addr.in6.sin6_addr;
203#endif
204
205      if (daemon->tftp_interfaces)
206	{
207	  /* dedicated tftp interface list */
208	  for (tmp = daemon->tftp_interfaces; tmp; tmp = tmp->next)
209	    if (tmp->name && wildcard_match(tmp->name, name))
210	      break;
211
212	  if (!tmp)
213	    return;
214	}
215      else
216	{
217	  /* Do the same as DHCP */
218	  if (!iface_check(listen->family, &addra, name, NULL))
219	    {
220	      if (!option_bool(OPT_CLEVERBIND))
221		enumerate_interfaces(0);
222	      if (!loopback_exception(listen->tftpfd, listen->family, &addra, name) &&
223		  !label_exception(if_index, listen->family, &addra) )
224		return;
225	    }
226
227#ifdef HAVE_DHCP
228	  /* allowed interfaces are the same as for DHCP */
229	  for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
230	    if (tmp->name && wildcard_match(tmp->name, name))
231	      return;
232#endif
233	}
234
235      strncpy(ifr.ifr_name, name, IF_NAMESIZE);
236      if (ioctl(listen->tftpfd, SIOCGIFMTU, &ifr) != -1)
237	mtu = ifr.ifr_mtu;
238    }
239
240  if (name)
241    {
242      /* check for per-interface prefix */
243      for (pref = daemon->if_prefix; pref; pref = pref->next)
244	if (strcmp(pref->interface, name) == 0)
245	  prefix = pref->prefix;
246    }
247
248  if (listen->family == AF_INET)
249    {
250      addr.in.sin_port = htons(port);
251#ifdef HAVE_SOCKADDR_SA_LEN
252      addr.in.sin_len = sizeof(addr.in);
253#endif
254    }
255#ifdef HAVE_IPV6
256  else
257    {
258      addr.in6.sin6_port = htons(port);
259      addr.in6.sin6_flowinfo = 0;
260      addr.in6.sin6_scope_id = 0;
261#ifdef HAVE_SOCKADDR_SA_LEN
262      addr.in6.sin6_len = sizeof(addr.in6);
263#endif
264    }
265#endif
266
267  if (!(transfer = whine_malloc(sizeof(struct tftp_transfer))))
268    return;
269
270  if ((transfer->sockfd = socket(listen->family, SOCK_DGRAM, 0)) == -1)
271    {
272      free(transfer);
273      return;
274    }
275
276  transfer->peer = peer;
277  transfer->timeout = now + 2;
278  transfer->backoff = 1;
279  transfer->block = 1;
280  transfer->blocksize = 512;
281  transfer->offset = 0;
282  transfer->file = NULL;
283  transfer->opt_blocksize = transfer->opt_transize = 0;
284  transfer->netascii = transfer->carrylf = 0;
285
286  prettyprint_addr(&peer, daemon->addrbuff);
287
288  /* if we have a nailed-down range, iterate until we find a free one. */
289  while (1)
290    {
291      if (bind(transfer->sockfd, &addr.sa, sa_len(&addr)) == -1 ||
292#if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
293	  setsockopt(transfer->sockfd, IPPROTO_IP, IP_MTU_DISCOVER, &mtuflag, sizeof(mtuflag)) == -1 ||
294#endif
295	  !fix_fd(transfer->sockfd))
296	{
297	  if (errno == EADDRINUSE && daemon->start_tftp_port != 0)
298	    {
299	      if (++port <= daemon->end_tftp_port)
300		{
301		  if (listen->family == AF_INET)
302		    addr.in.sin_port = htons(port);
303#ifdef HAVE_IPV6
304		  else
305		     addr.in6.sin6_port = htons(port);
306#endif
307		  continue;
308		}
309	      my_syslog(MS_TFTP | LOG_ERR, _("unable to get free port for TFTP"));
310	    }
311	  free_transfer(transfer);
312	  return;
313	}
314      break;
315    }
316
317  p = packet + 2;
318  end = packet + len;
319
320  if (ntohs(*((unsigned short *)packet)) != OP_RRQ ||
321      !(filename = next(&p, end)) ||
322      !(mode = next(&p, end)) ||
323      (strcasecmp(mode, "octet") != 0 && strcasecmp(mode, "netascii") != 0))
324    {
325      len = tftp_err(ERR_ILL, packet, _("unsupported request from %s"), daemon->addrbuff);
326      is_err = 1;
327    }
328  else
329    {
330      if (strcasecmp(mode, "netascii") == 0)
331	transfer->netascii = 1;
332
333      while ((opt = next(&p, end)))
334	{
335	  if (strcasecmp(opt, "blksize") == 0)
336	    {
337	      if ((opt = next(&p, end)) && !option_bool(OPT_TFTP_NOBLOCK))
338		{
339		  transfer->blocksize = atoi(opt);
340		  if (transfer->blocksize < 1)
341		    transfer->blocksize = 1;
342		  if (transfer->blocksize > (unsigned)daemon->packet_buff_sz - 4)
343		    transfer->blocksize = (unsigned)daemon->packet_buff_sz - 4;
344		  /* 32 bytes for IP, UDP and TFTP headers */
345		  if (mtu != 0 && transfer->blocksize > (unsigned)mtu - 32)
346		    transfer->blocksize = (unsigned)mtu - 32;
347		  transfer->opt_blocksize = 1;
348		  transfer->block = 0;
349		}
350	    }
351	  else if (strcasecmp(opt, "tsize") == 0 && next(&p, end) && !transfer->netascii)
352	    {
353	      transfer->opt_transize = 1;
354	      transfer->block = 0;
355	    }
356	}
357
358      /* cope with backslashes from windows boxen. */
359      for (p = filename; *p; p++)
360	if (*p == '\\')
361	  *p = '/';
362	else if (option_bool(OPT_TFTP_LC))
363	  *p = tolower(*p);
364
365      strcpy(daemon->namebuff, "/");
366      if (prefix)
367	{
368	  if (prefix[0] == '/')
369	    daemon->namebuff[0] = 0;
370	  strncat(daemon->namebuff, prefix, (MAXDNAME-1) - strlen(daemon->namebuff));
371	  if (prefix[strlen(prefix)-1] != '/')
372	    strncat(daemon->namebuff, "/", (MAXDNAME-1) - strlen(daemon->namebuff));
373
374	  if (option_bool(OPT_TFTP_APREF))
375	    {
376	      size_t oldlen = strlen(daemon->namebuff);
377	      struct stat statbuf;
378
379	      strncat(daemon->namebuff, daemon->addrbuff, (MAXDNAME-1) - strlen(daemon->namebuff));
380	      strncat(daemon->namebuff, "/", (MAXDNAME-1) - strlen(daemon->namebuff));
381
382	      /* remove unique-directory if it doesn't exist */
383	      if (stat(daemon->namebuff, &statbuf) == -1 || !S_ISDIR(statbuf.st_mode))
384		daemon->namebuff[oldlen] = 0;
385	    }
386
387	  /* Absolute pathnames OK if they match prefix */
388	  if (filename[0] == '/')
389	    {
390	      if (strstr(filename, daemon->namebuff) == filename)
391		daemon->namebuff[0] = 0;
392	      else
393		filename++;
394	    }
395	}
396      else if (filename[0] == '/')
397	daemon->namebuff[0] = 0;
398      strncat(daemon->namebuff, filename, (MAXDNAME-1) - strlen(daemon->namebuff));
399
400      /* check permissions and open file */
401      if ((transfer->file = check_tftp_fileperm(&len, prefix)))
402	{
403	  if ((len = get_block(packet, transfer)) == -1)
404	    len = tftp_err_oops(packet, daemon->namebuff);
405	  else
406	    is_err = 0;
407	}
408    }
409
410  while (sendto(transfer->sockfd, packet, len, 0,
411		(struct sockaddr *)&peer, sa_len(&peer)) == -1 && errno == EINTR);
412
413  if (is_err)
414    free_transfer(transfer);
415  else
416    {
417      transfer->next = daemon->tftp_trans;
418      daemon->tftp_trans = transfer;
419    }
420}
421
422static struct tftp_file *check_tftp_fileperm(ssize_t *len, char *prefix)
423{
424  char *packet = daemon->packet, *namebuff = daemon->namebuff;
425  struct tftp_file *file;
426  struct tftp_transfer *t;
427  uid_t uid = geteuid();
428  struct stat statbuf;
429  int fd = -1;
430
431  /* trick to ban moving out of the subtree */
432  if (prefix && strstr(namebuff, "/../"))
433    goto perm;
434
435  if ((fd = open(namebuff, O_RDONLY)) == -1)
436    {
437      if (errno == ENOENT)
438	{
439	  *len = tftp_err(ERR_FNF, packet, _("file %s not found"), namebuff);
440	  return NULL;
441	}
442      else if (errno == EACCES)
443	goto perm;
444      else
445	goto oops;
446    }
447
448  /* stat the file descriptor to avoid stat->open races */
449  if (fstat(fd, &statbuf) == -1)
450    goto oops;
451
452  /* running as root, must be world-readable */
453  if (uid == 0)
454    {
455      if (!(statbuf.st_mode & S_IROTH))
456	goto perm;
457    }
458  /* in secure mode, must be owned by user running dnsmasq */
459  else if (option_bool(OPT_TFTP_SECURE) && uid != statbuf.st_uid)
460    goto perm;
461
462  /* If we're doing many tranfers from the same file, only
463     open it once this saves lots of file descriptors
464     when mass-booting a big cluster, for instance.
465     Be conservative and only share when inode and name match
466     this keeps error messages sane. */
467  for (t = daemon->tftp_trans; t; t = t->next)
468    if (t->file->dev == statbuf.st_dev &&
469	t->file->inode == statbuf.st_ino &&
470	strcmp(t->file->filename, namebuff) == 0)
471      {
472	close(fd);
473	t->file->refcount++;
474	return t->file;
475      }
476
477  if (!(file = whine_malloc(sizeof(struct tftp_file) + strlen(namebuff) + 1)))
478    {
479      errno = ENOMEM;
480      goto oops;
481    }
482
483  file->fd = fd;
484  file->size = statbuf.st_size;
485  file->dev = statbuf.st_dev;
486  file->inode = statbuf.st_ino;
487  file->refcount = 1;
488  strcpy(file->filename, namebuff);
489  return file;
490
491 perm:
492  errno = EACCES;
493  *len =  tftp_err(ERR_PERM, packet, _("cannot access %s: %s"), namebuff);
494  if (fd != -1)
495    close(fd);
496  return NULL;
497
498 oops:
499  *len =  tftp_err_oops(packet, namebuff);
500  if (fd != -1)
501    close(fd);
502  return NULL;
503}
504
505void check_tftp_listeners(time_t now)
506{
507  struct tftp_transfer *transfer, *tmp, **up;
508  ssize_t len;
509
510  struct ack {
511    unsigned short op, block;
512  } *mess = (struct ack *)daemon->packet;
513
514  /* Check for activity on any existing transfers */
515  for (transfer = daemon->tftp_trans, up = &daemon->tftp_trans; transfer; transfer = tmp)
516    {
517      tmp = transfer->next;
518
519      prettyprint_addr(&transfer->peer, daemon->addrbuff);
520
521      if (poll_check(transfer->sockfd, POLLIN))
522	{
523	  /* we overwrote the buffer... */
524	  daemon->srv_save = NULL;
525
526	  if ((len = recv(transfer->sockfd, daemon->packet, daemon->packet_buff_sz, 0)) >= (ssize_t)sizeof(struct ack))
527	    {
528	      if (ntohs(mess->op) == OP_ACK && ntohs(mess->block) == (unsigned short)transfer->block)
529		{
530		  /* Got ack, ensure we take the (re)transmit path */
531		  transfer->timeout = now;
532		  transfer->backoff = 0;
533		  if (transfer->block++ != 0)
534		    transfer->offset += transfer->blocksize - transfer->expansion;
535		}
536	      else if (ntohs(mess->op) == OP_ERR)
537		{
538		  char *p = daemon->packet + sizeof(struct ack);
539		  char *end = daemon->packet + len;
540		  char *err = next(&p, end);
541
542		  /* Sanitise error message */
543		  if (!err)
544		    err = "";
545		  else
546		    sanitise(err);
547
548		  my_syslog(MS_TFTP | LOG_ERR, _("error %d %s received from %s"),
549			    (int)ntohs(mess->block), err,
550			    daemon->addrbuff);
551
552		  /* Got err, ensure we take abort */
553		  transfer->timeout = now;
554		  transfer->backoff = 100;
555		}
556	    }
557	}
558
559      if (difftime(now, transfer->timeout) >= 0.0)
560	{
561	  int endcon = 0;
562
563	  /* timeout, retransmit */
564	  transfer->timeout += 1 + (1<<transfer->backoff);
565
566	  /* we overwrote the buffer... */
567	  daemon->srv_save = NULL;
568
569	  if ((len = get_block(daemon->packet, transfer)) == -1)
570	    {
571	      len = tftp_err_oops(daemon->packet, transfer->file->filename);
572	      endcon = 1;
573	    }
574	  /* don't complain about timeout when we're awaiting the last
575	     ACK, some clients never send it */
576	  else if (++transfer->backoff > 7 && len != 0)
577	    {
578	      endcon = 1;
579	      len = 0;
580	    }
581
582	  if (len != 0)
583	    while(sendto(transfer->sockfd, daemon->packet, len, 0,
584			 (struct sockaddr *)&transfer->peer, sa_len(&transfer->peer)) == -1 && errno == EINTR);
585
586	  if (endcon || len == 0)
587	    {
588	      strcpy(daemon->namebuff, transfer->file->filename);
589	      sanitise(daemon->namebuff);
590	      my_syslog(MS_TFTP | LOG_INFO, endcon ? _("failed sending %s to %s") : _("sent %s to %s"), daemon->namebuff, daemon->addrbuff);
591	      /* unlink */
592	      *up = tmp;
593	      if (endcon)
594		free_transfer(transfer);
595	      else
596		{
597		  /* put on queue to be sent to script and deleted */
598		  transfer->next = daemon->tftp_done_trans;
599		  daemon->tftp_done_trans = transfer;
600		}
601	      continue;
602	    }
603	}
604
605      up = &transfer->next;
606    }
607}
608
609static void free_transfer(struct tftp_transfer *transfer)
610{
611  close(transfer->sockfd);
612  if (transfer->file && (--transfer->file->refcount) == 0)
613    {
614      close(transfer->file->fd);
615      free(transfer->file);
616    }
617  free(transfer);
618}
619
620static char *next(char **p, char *end)
621{
622  char *ret = *p;
623  size_t len;
624
625  if (*(end-1) != 0 ||
626      *p == end ||
627      (len = strlen(ret)) == 0)
628    return NULL;
629
630  *p += len + 1;
631  return ret;
632}
633
634static void sanitise(char *buf)
635{
636  unsigned char *q, *r;
637  for (q = r = (unsigned char *)buf; *r; r++)
638    if (isprint((int)*r))
639      *(q++) = *r;
640  *q = 0;
641
642}
643
644static ssize_t tftp_err(int err, char *packet, char *message, char *file)
645{
646  struct errmess {
647    unsigned short op, err;
648    char message[];
649  } *mess = (struct errmess *)packet;
650  ssize_t ret = 4;
651  char *errstr = strerror(errno);
652
653  sanitise(file);
654
655  mess->op = htons(OP_ERR);
656  mess->err = htons(err);
657  ret += (snprintf(mess->message, 500,  message, file, errstr) + 1);
658  my_syslog(MS_TFTP | LOG_ERR, "%s", mess->message);
659
660  return  ret;
661}
662
663static ssize_t tftp_err_oops(char *packet, char *file)
664{
665  /* May have >1 refs to file, so potentially mangle a copy of the name */
666  strcpy(daemon->namebuff, file);
667  return tftp_err(ERR_NOTDEF, packet, _("cannot read %s: %s"), daemon->namebuff);
668}
669
670/* return -1 for error, zero for done. */
671static ssize_t get_block(char *packet, struct tftp_transfer *transfer)
672{
673  if (transfer->block == 0)
674    {
675      /* send OACK */
676      char *p;
677      struct oackmess {
678	unsigned short op;
679	char data[];
680      } *mess = (struct oackmess *)packet;
681
682      p = mess->data;
683      mess->op = htons(OP_OACK);
684      if (transfer->opt_blocksize)
685	{
686	  p += (sprintf(p, "blksize") + 1);
687	  p += (sprintf(p, "%d", transfer->blocksize) + 1);
688	}
689      if (transfer->opt_transize)
690	{
691	  p += (sprintf(p,"tsize") + 1);
692	  p += (sprintf(p, "%u", (unsigned int)transfer->file->size) + 1);
693	}
694
695      return p - packet;
696    }
697  else
698    {
699      /* send data packet */
700      struct datamess {
701	unsigned short op, block;
702	unsigned char data[];
703      } *mess = (struct datamess *)packet;
704
705      size_t size = transfer->file->size - transfer->offset;
706
707      if (transfer->offset > transfer->file->size)
708	return 0; /* finished */
709
710      if (size > transfer->blocksize)
711	size = transfer->blocksize;
712
713      mess->op = htons(OP_DATA);
714      mess->block = htons((unsigned short)(transfer->block));
715
716      if (lseek(transfer->file->fd, transfer->offset, SEEK_SET) == (off_t)-1 ||
717	  !read_write(transfer->file->fd, mess->data, size, 1))
718	return -1;
719
720      transfer->expansion = 0;
721
722      /* Map '\n' to CR-LF in netascii mode */
723      if (transfer->netascii)
724	{
725	  size_t i;
726	  int newcarrylf;
727
728	  for (i = 0, newcarrylf = 0; i < size; i++)
729	    if (mess->data[i] == '\n' && ( i != 0 || !transfer->carrylf))
730	      {
731		transfer->expansion++;
732
733		if (size != transfer->blocksize)
734		  size++; /* room in this block */
735		else  if (i == size - 1)
736		  newcarrylf = 1; /* don't expand LF again if it moves to the next block */
737
738		/* make space and insert CR */
739		memmove(&mess->data[i+1], &mess->data[i], size - (i + 1));
740		mess->data[i] = '\r';
741
742		i++;
743	      }
744	  transfer->carrylf = newcarrylf;
745
746	}
747
748      return size + 4;
749    }
750}
751
752
753int do_tftp_script_run(void)
754{
755  struct tftp_transfer *transfer;
756
757  if ((transfer = daemon->tftp_done_trans))
758    {
759      daemon->tftp_done_trans = transfer->next;
760#ifdef HAVE_SCRIPT
761      queue_tftp(transfer->file->size, transfer->file->filename, &transfer->peer);
762#endif
763      free_transfer(transfer);
764      return 1;
765    }
766
767  return 0;
768}
769#endif
770