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