Deleted Added
full compact
tftpd.c (86765) tftpd.c (90333)
1/*
2 * Copyright (c) 1983, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 28 unchanged lines hidden (view full) ---

37 The Regents of the University of California. All rights reserved.\n";
38#endif /* not lint */
39
40#ifndef lint
41#if 0
42static char sccsid[] = "@(#)tftpd.c 8.1 (Berkeley) 6/4/93";
43#endif
44static const char rcsid[] =
1/*
2 * Copyright (c) 1983, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 28 unchanged lines hidden (view full) ---

37 The Regents of the University of California. All rights reserved.\n";
38#endif /* not lint */
39
40#ifndef lint
41#if 0
42static char sccsid[] = "@(#)tftpd.c 8.1 (Berkeley) 6/4/93";
43#endif
44static const char rcsid[] =
45 "$FreeBSD: head/libexec/tftpd/tftpd.c 86765 2001-11-22 05:08:35Z benno $";
45 "$FreeBSD: head/libexec/tftpd/tftpd.c 90333 2002-02-07 04:49:34Z imp $";
46#endif /* not lint */
47
48/*
49 * Trivial file transfer protocol server.
50 *
51 * This version includes many modifications by Jim Guyton
52 * <guyton@rand-unix>.
53 */

--- 32 unchanged lines hidden (view full) ---

86int max_rexmtval = 2*TIMEOUT;
87
88#define PKTSIZE SEGSIZE+4
89char buf[PKTSIZE];
90char ackbuf[PKTSIZE];
91struct sockaddr_in from;
92int fromlen;
93
46#endif /* not lint */
47
48/*
49 * Trivial file transfer protocol server.
50 *
51 * This version includes many modifications by Jim Guyton
52 * <guyton@rand-unix>.
53 */

--- 32 unchanged lines hidden (view full) ---

86int max_rexmtval = 2*TIMEOUT;
87
88#define PKTSIZE SEGSIZE+4
89char buf[PKTSIZE];
90char ackbuf[PKTSIZE];
91struct sockaddr_in from;
92int fromlen;
93
94void tftp __P((struct tftphdr *, int));
94void tftp(struct tftphdr *, int);
95
96/*
97 * Null-terminated directory prefix list for absolute pathname requests and
98 * search list for relative pathname requests.
99 *
100 * MAXDIRS should be at least as large as the number of arguments that
101 * inetd allows (currently 20).
102 */
103#define MAXDIRS 20
104static struct dirlist {
105 char *name;
106 int len;
107} dirs[MAXDIRS+1];
108static int suppress_naks;
109static int logging;
110static int ipchroot;
111
95
96/*
97 * Null-terminated directory prefix list for absolute pathname requests and
98 * search list for relative pathname requests.
99 *
100 * MAXDIRS should be at least as large as the number of arguments that
101 * inetd allows (currently 20).
102 */
103#define MAXDIRS 20
104static struct dirlist {
105 char *name;
106 int len;
107} dirs[MAXDIRS+1];
108static int suppress_naks;
109static int logging;
110static int ipchroot;
111
112static char *errtomsg __P((int));
113static void nak __P((int));
114static void oack __P(());
112static char *errtomsg(int);
113static void nak(int);
114static void oack();
115
116int
115
116int
117main(argc, argv)
118 int argc;
119 char *argv[];
117main(int argc, char *argv[])
120{
118{
121 register struct tftphdr *tp;
122 register int n;
119 struct tftphdr *tp;
120 int n;
123 int ch, on;
124 struct sockaddr_in sin;
125 char *chroot_dir = NULL;
126 struct passwd *nobody;
127 char *chuser = "nobody";
128
129 openlog("tftpd", LOG_PID | LOG_NDELAY, LOG_FTP);
130 while ((ch = getopt(argc, argv, "cClns:u:")) != -1) {

--- 159 unchanged lines hidden (view full) ---

290 tp = (struct tftphdr *)buf;
291 tp->th_opcode = ntohs(tp->th_opcode);
292 if (tp->th_opcode == RRQ || tp->th_opcode == WRQ)
293 tftp(tp, n);
294 exit(1);
295}
296
297struct formats;
121 int ch, on;
122 struct sockaddr_in sin;
123 char *chroot_dir = NULL;
124 struct passwd *nobody;
125 char *chuser = "nobody";
126
127 openlog("tftpd", LOG_PID | LOG_NDELAY, LOG_FTP);
128 while ((ch = getopt(argc, argv, "cClns:u:")) != -1) {

--- 159 unchanged lines hidden (view full) ---

288 tp = (struct tftphdr *)buf;
289 tp->th_opcode = ntohs(tp->th_opcode);
290 if (tp->th_opcode == RRQ || tp->th_opcode == WRQ)
291 tftp(tp, n);
292 exit(1);
293}
294
295struct formats;
298int validate_access __P((char **, int));
299void xmitfile __P((struct formats *));
300void recvfile __P((struct formats *));
296int validate_access(char **, int);
297void xmitfile(struct formats *);
298void recvfile(struct formats *);
301
302struct formats {
303 char *f_mode;
299
300struct formats {
301 char *f_mode;
304 int (*f_validate) __P((char **, int));
305 void (*f_send) __P((struct formats *));
306 void (*f_recv) __P((struct formats *));
302 int (*f_validate)(char **, int);
303 void (*f_send)(struct formats *);
304 void (*f_recv)(struct formats *);
307 int f_convert;
308} formats[] = {
309 { "netascii", validate_access, xmitfile, recvfile, 1 },
310 { "octet", validate_access, xmitfile, recvfile, 0 },
311#ifdef notdef
312 { "mail", validate_user, sendmail, recvmail, 1 },
313#endif
314 { 0 }

--- 13 unchanged lines hidden (view full) ---

328 OPT_TSIZE = 0,
329 OPT_TIMEOUT,
330};
331
332/*
333 * Handle initial connection protocol.
334 */
335void
305 int f_convert;
306} formats[] = {
307 { "netascii", validate_access, xmitfile, recvfile, 1 },
308 { "octet", validate_access, xmitfile, recvfile, 0 },
309#ifdef notdef
310 { "mail", validate_user, sendmail, recvmail, 1 },
311#endif
312 { 0 }

--- 13 unchanged lines hidden (view full) ---

326 OPT_TSIZE = 0,
327 OPT_TIMEOUT,
328};
329
330/*
331 * Handle initial connection protocol.
332 */
333void
336tftp(tp, size)
337 struct tftphdr *tp;
338 int size;
334tftp(struct tftphdr *tp, int size)
339{
335{
340 register char *cp;
336 char *cp;
341 int i, first = 1, has_options = 0, ecode;
337 int i, first = 1, has_options = 0, ecode;
342 register struct formats *pf;
338 struct formats *pf;
343 char *filename, *mode, *option, *ccp;
344
345 filename = cp = tp->th_stuff;
346again:
347 while (cp < buf + size) {
348 if (*cp == '\0')
349 break;
350 cp++;

--- 94 unchanged lines hidden (view full) ---

445 * readable/writable.
446 * If we were invoked with arguments
447 * from inetd then the file must also be
448 * in one of the given directory prefixes.
449 * Note also, full path name must be
450 * given as we have no login directory.
451 */
452int
339 char *filename, *mode, *option, *ccp;
340
341 filename = cp = tp->th_stuff;
342again:
343 while (cp < buf + size) {
344 if (*cp == '\0')
345 break;
346 cp++;

--- 94 unchanged lines hidden (view full) ---

441 * readable/writable.
442 * If we were invoked with arguments
443 * from inetd then the file must also be
444 * in one of the given directory prefixes.
445 * Note also, full path name must be
446 * given as we have no login directory.
447 */
448int
453validate_access(filep, mode)
454 char **filep;
455 int mode;
449validate_access(char **filep, int mode)
456{
457 struct stat stbuf;
458 int fd;
459 struct dirlist *dirp;
460 static char pathname[MAXPATHLEN];
461 char *filename = *filep;
462
463 /*

--- 79 unchanged lines hidden (view full) ---

543 }
544 return (0);
545}
546
547int timeouts;
548jmp_buf timeoutbuf;
549
550void
450{
451 struct stat stbuf;
452 int fd;
453 struct dirlist *dirp;
454 static char pathname[MAXPATHLEN];
455 char *filename = *filep;
456
457 /*

--- 79 unchanged lines hidden (view full) ---

537 }
538 return (0);
539}
540
541int timeouts;
542jmp_buf timeoutbuf;
543
544void
551timer()
545timer(int sig __unused)
552{
553 if (++timeouts > MAX_TIMEOUTS)
554 exit(1);
555 longjmp(timeoutbuf, 1);
556}
557
558/*
559 * Send the requested file.
560 */
561void
546{
547 if (++timeouts > MAX_TIMEOUTS)
548 exit(1);
549 longjmp(timeoutbuf, 1);
550}
551
552/*
553 * Send the requested file.
554 */
555void
562xmitfile(pf)
563 struct formats *pf;
556xmitfile(struct formats *pf)
564{
565 struct tftphdr *dp, *r_init();
557{
558 struct tftphdr *dp, *r_init();
566 register struct tftphdr *ap; /* ack packet */
567 register int size, n;
559 struct tftphdr *ap; /* ack packet */
560 int size, n;
568 volatile unsigned short block;
569
570 signal(SIGALRM, timer);
571 dp = r_init();
572 ap = (struct tftphdr *)ackbuf;
573 block = 1;
574 do {
575 size = readit(file, &dp, pf->f_convert);

--- 38 unchanged lines hidden (view full) ---

614 }
615 block++;
616 } while (size == SEGSIZE);
617abort:
618 (void) fclose(file);
619}
620
621void
561 volatile unsigned short block;
562
563 signal(SIGALRM, timer);
564 dp = r_init();
565 ap = (struct tftphdr *)ackbuf;
566 block = 1;
567 do {
568 size = readit(file, &dp, pf->f_convert);

--- 38 unchanged lines hidden (view full) ---

607 }
608 block++;
609 } while (size == SEGSIZE);
610abort:
611 (void) fclose(file);
612}
613
614void
622justquit()
615justquit(int sig __unused)
623{
624 exit(0);
625}
626
627
628/*
629 * Receive a file.
630 */
631void
616{
617 exit(0);
618}
619
620
621/*
622 * Receive a file.
623 */
624void
632recvfile(pf)
633 struct formats *pf;
625recvfile(struct formats *pf)
634{
635 struct tftphdr *dp, *w_init();
626{
627 struct tftphdr *dp, *w_init();
636 register struct tftphdr *ap; /* ack buffer */
637 register int n, size;
628 struct tftphdr *ap; /* ack buffer */
629 int n, size;
638 volatile unsigned short block;
639
640 signal(SIGALRM, timer);
641 dp = w_init();
642 ap = (struct tftphdr *)ackbuf;
643 block = 0;
644 do {
645 timeouts = 0;

--- 69 unchanged lines hidden (view full) ---

715 { EBADID, "Unknown transfer ID" },
716 { EEXISTS, "File already exists" },
717 { ENOUSER, "No such user" },
718 { EOPTNEG, "Option negotiation" },
719 { -1, 0 }
720};
721
722static char *
630 volatile unsigned short block;
631
632 signal(SIGALRM, timer);
633 dp = w_init();
634 ap = (struct tftphdr *)ackbuf;
635 block = 0;
636 do {
637 timeouts = 0;

--- 69 unchanged lines hidden (view full) ---

707 { EBADID, "Unknown transfer ID" },
708 { EEXISTS, "File already exists" },
709 { ENOUSER, "No such user" },
710 { EOPTNEG, "Option negotiation" },
711 { -1, 0 }
712};
713
714static char *
723errtomsg(error)
724 int error;
715errtomsg(int error)
725{
726 static char buf[20];
716{
717 static char buf[20];
727 register struct errmsg *pe;
718 struct errmsg *pe;
728 if (error == 0)
729 return "success";
730 for (pe = errmsgs; pe->e_code >= 0; pe++)
731 if (pe->e_code == error)
732 return pe->e_msg;
733 snprintf(buf, sizeof(buf), "error %d", error);
734 return buf;
735}
736
737/*
738 * Send a nak packet (error message).
739 * Error code passed in is one of the
740 * standard TFTP codes, or a UNIX errno
741 * offset by 100.
742 */
743static void
719 if (error == 0)
720 return "success";
721 for (pe = errmsgs; pe->e_code >= 0; pe++)
722 if (pe->e_code == error)
723 return pe->e_msg;
724 snprintf(buf, sizeof(buf), "error %d", error);
725 return buf;
726}
727
728/*
729 * Send a nak packet (error message).
730 * Error code passed in is one of the
731 * standard TFTP codes, or a UNIX errno
732 * offset by 100.
733 */
734static void
744nak(error)
745 int error;
735nak(int error)
746{
736{
747 register struct tftphdr *tp;
737 struct tftphdr *tp;
748 int length;
738 int length;
749 register struct errmsg *pe;
739 struct errmsg *pe;
750
751 tp = (struct tftphdr *)buf;
752 tp->th_opcode = htons((u_short)ERROR);
753 tp->th_code = htons((u_short)error);
754 for (pe = errmsgs; pe->e_code >= 0; pe++)
755 if (pe->e_code == error)
756 break;
757 if (pe->e_code < 0) {

--- 7 unchanged lines hidden (view full) ---

765 if (send(peer, buf, length, 0) != length)
766 syslog(LOG_ERR, "nak: %m");
767}
768
769/*
770 * Send an oack packet (option acknowledgement).
771 */
772static void
740
741 tp = (struct tftphdr *)buf;
742 tp->th_opcode = htons((u_short)ERROR);
743 tp->th_code = htons((u_short)error);
744 for (pe = errmsgs; pe->e_code >= 0; pe++)
745 if (pe->e_code == error)
746 break;
747 if (pe->e_code < 0) {

--- 7 unchanged lines hidden (view full) ---

755 if (send(peer, buf, length, 0) != length)
756 syslog(LOG_ERR, "nak: %m");
757}
758
759/*
760 * Send an oack packet (option acknowledgement).
761 */
762static void
773oack()
763oack(void)
774{
775 struct tftphdr *tp, *ap;
776 int size, i, n;
777 char *bp;
778
779 tp = (struct tftphdr *)buf;
780 bp = buf + 2;
781 size = sizeof(buf) - 2;

--- 40 unchanged lines hidden ---
764{
765 struct tftphdr *tp, *ap;
766 int size, i, n;
767 char *bp;
768
769 tp = (struct tftphdr *)buf;
770 bp = buf + 2;
771 size = sizeof(buf) - 2;

--- 40 unchanged lines hidden ---