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