Mercurial > flash_v2
annotate packages/net/common/current/src/tftp_server.c @ 1777:c16341b1bac6 default tip
* Added execute permissions to files missed in conversion from CVS
| author | alexs |
|---|---|
| date | Mon, 12 Oct 2009 02:26:09 +0100 |
| parents | 42c0adb7b2fc |
| children |
| rev | line source |
|---|---|
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
1 //========================================================================== |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
2 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
3 // lib/tftp_server.c |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
4 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
5 // TFTP server support |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
6 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
7 //========================================================================== |
|
490
7c34839e7e97
* src/bootp_support.c: Fix licence which should always have been
jlarmour
parents:
270
diff
changeset
|
8 //####ECOSGPLCOPYRIGHTBEGIN#### |
|
7c34839e7e97
* src/bootp_support.c: Fix licence which should always have been
jlarmour
parents:
270
diff
changeset
|
9 // ------------------------------------------- |
|
7c34839e7e97
* src/bootp_support.c: Fix licence which should always have been
jlarmour
parents:
270
diff
changeset
|
10 // This file is part of eCos, the Embedded Configurable Operating System. |
|
7c34839e7e97
* src/bootp_support.c: Fix licence which should always have been
jlarmour
parents:
270
diff
changeset
|
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. |
| 957 | 12 // Copyright (C) 2003 Andrew Lunn |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
13 // |
|
490
7c34839e7e97
* src/bootp_support.c: Fix licence which should always have been
jlarmour
parents:
270
diff
changeset
|
14 // eCos is free software; you can redistribute it and/or modify it under |
|
7c34839e7e97
* src/bootp_support.c: Fix licence which should always have been
jlarmour
parents:
270
diff
changeset
|
15 // the terms of the GNU General Public License as published by the Free |
|
7c34839e7e97
* src/bootp_support.c: Fix licence which should always have been
jlarmour
parents:
270
diff
changeset
|
16 // Software Foundation; either version 2 or (at your option) any later version. |
|
7c34839e7e97
* src/bootp_support.c: Fix licence which should always have been
jlarmour
parents:
270
diff
changeset
|
17 // |
|
7c34839e7e97
* src/bootp_support.c: Fix licence which should always have been
jlarmour
parents:
270
diff
changeset
|
18 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY |
|
7c34839e7e97
* src/bootp_support.c: Fix licence which should always have been
jlarmour
parents:
270
diff
changeset
|
19 // WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
7c34839e7e97
* src/bootp_support.c: Fix licence which should always have been
jlarmour
parents:
270
diff
changeset
|
20 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
7c34839e7e97
* src/bootp_support.c: Fix licence which should always have been
jlarmour
parents:
270
diff
changeset
|
21 // for more details. |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
22 // |
|
490
7c34839e7e97
* src/bootp_support.c: Fix licence which should always have been
jlarmour
parents:
270
diff
changeset
|
23 // You should have received a copy of the GNU General Public License along |
|
7c34839e7e97
* src/bootp_support.c: Fix licence which should always have been
jlarmour
parents:
270
diff
changeset
|
24 // with eCos; if not, write to the Free Software Foundation, Inc., |
|
7c34839e7e97
* src/bootp_support.c: Fix licence which should always have been
jlarmour
parents:
270
diff
changeset
|
25 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
26 // |
|
490
7c34839e7e97
* src/bootp_support.c: Fix licence which should always have been
jlarmour
parents:
270
diff
changeset
|
27 // As a special exception, if other files instantiate templates or use macros |
|
7c34839e7e97
* src/bootp_support.c: Fix licence which should always have been
jlarmour
parents:
270
diff
changeset
|
28 // or inline functions from this file, or you compile this file and link it |
|
7c34839e7e97
* src/bootp_support.c: Fix licence which should always have been
jlarmour
parents:
270
diff
changeset
|
29 // with other works to produce a work based on this file, this file does not |
|
7c34839e7e97
* src/bootp_support.c: Fix licence which should always have been
jlarmour
parents:
270
diff
changeset
|
30 // by itself cause the resulting work to be covered by the GNU General Public |
|
7c34839e7e97
* src/bootp_support.c: Fix licence which should always have been
jlarmour
parents:
270
diff
changeset
|
31 // License. However the source code for this file must still be made available |
|
7c34839e7e97
* src/bootp_support.c: Fix licence which should always have been
jlarmour
parents:
270
diff
changeset
|
32 // in accordance with section (3) of the GNU General Public License. |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
33 // |
|
490
7c34839e7e97
* src/bootp_support.c: Fix licence which should always have been
jlarmour
parents:
270
diff
changeset
|
34 // This exception does not invalidate any other reasons why a work based on |
|
7c34839e7e97
* src/bootp_support.c: Fix licence which should always have been
jlarmour
parents:
270
diff
changeset
|
35 // this file might be covered by the GNU General Public License. |
|
7c34839e7e97
* src/bootp_support.c: Fix licence which should always have been
jlarmour
parents:
270
diff
changeset
|
36 // |
|
7c34839e7e97
* src/bootp_support.c: Fix licence which should always have been
jlarmour
parents:
270
diff
changeset
|
37 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. |
|
7c34839e7e97
* src/bootp_support.c: Fix licence which should always have been
jlarmour
parents:
270
diff
changeset
|
38 // at http://sources.redhat.com/ecos/ecos-license/ |
|
7c34839e7e97
* src/bootp_support.c: Fix licence which should always have been
jlarmour
parents:
270
diff
changeset
|
39 // ------------------------------------------- |
|
7c34839e7e97
* src/bootp_support.c: Fix licence which should always have been
jlarmour
parents:
270
diff
changeset
|
40 //####ECOSGPLCOPYRIGHTEND#### |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
41 //========================================================================== |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
42 //#####DESCRIPTIONBEGIN#### |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
43 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
44 // Author(s): gthomas |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
45 // Contributors: gthomas, hmt, andrew.lunn@ascom.ch (Andrew Lunn) |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
46 // Date: 2000-04-06 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
47 // Purpose: |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
48 // Description: |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
49 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
50 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
51 //####DESCRIPTIONEND#### |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
52 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
53 //========================================================================== |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
54 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
55 // TFTP server support |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
56 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
57 #include <network.h> // Basic networking support |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
58 #include <arpa/tftp.h> // TFTP protocol definitions |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
59 #include <tftp_support.h> // TFTPD structures |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
60 #include <cyg/kernel/kapi.h> |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
61 #include <stdlib.h> // For malloc |
|
1621
26840b464238
* src/tftp_server.c: files are now created with the
jlarmour
parents:
1018
diff
changeset
|
62 #include <fcntl.h> |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
63 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
64 #define nCYGOPT_NET_TFTP_SERVER_INSTRUMENT |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
65 #ifdef CYGOPT_NET_TFTP_SERVER_INSTRUMENT |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
66 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
67 struct subinfo { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
68 int rx; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
69 int rx_repeat; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
70 int rx_skip; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
71 int send; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
72 int resend; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
73 }; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
74 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
75 struct info { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
76 struct subinfo ack, data; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
77 int err_send; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
78 int total_transactions; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
79 }; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
80 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
81 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
82 static struct info tftp_server_instrument = { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
83 { 0,0,0,0,0 }, |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
84 { 0,0,0,0,0 }, |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
85 0, 0, |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
86 }; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
87 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
88 #endif // CYGOPT_NET_TFTP_SERVER_INSTRUMENT |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
89 |
| 957 | 90 #ifdef CYGSEM_NET_TFTPD_MULTITHREADED |
| 91 struct tftpd_sem { | |
| 92 int port; | |
| 93 cyg_sem_t sem; | |
| 94 }; | |
| 95 | |
| 96 static struct tftpd_sem tftpd_sems[CYGNUM_NET_TFTPD_MULTITHREADED_PORTS]; | |
| 97 #endif //CYGSEM_NET_TFTPD_MULTITHREADED | |
| 98 | |
| 1696 | 99 #define STACK_SIZE (((CYGPKG_NET_TFTPD_THREAD_STACK_SIZE) + CYGARC_ALIGNMENT-1) & ~(CYGARC_ALIGNMENT-1)) |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
100 static char *TFTP_tag = "TFTPD"; |
| 957 | 101 #define CYGNUM_NET_MAX_INET_PROTOS 2 |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
102 struct tftp_server { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
103 char *tag; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
104 char stack[STACK_SIZE]; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
105 cyg_thread thread_data; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
106 cyg_handle_t thread_handle; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
107 int port; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
108 struct tftpd_fileops *ops; |
| 957 | 109 int s[CYGNUM_NET_MAX_INET_PROTOS], num_s; |
| 110 struct addrinfo *res; | |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
111 }; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
112 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
113 static char * errmsg[] = { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
114 "Undefined error code", // 0 nothing defined |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
115 "File not found", // 1 TFTP_ENOTFOUND |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
116 "Access violation", // 2 TFTP_EACCESS |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
117 "Disk full or allocation exceeded", // 3 TFTP_ENOSPACE |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
118 "Illegal TFTP operation", // 4 TFTP_EBADOP |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
119 "Unknown transfer ID", // 5 TFTP_EBADID |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
120 "File already exists", // 6 TFTP_EEXISTS |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
121 "No such user", // 7 TFTP_ENOUSER |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
122 }; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
123 |
| 957 | 124 // Little helper function to set the port number in an address |
| 125 static void set_port(struct sockaddr * address, int port) { | |
| 126 | |
| 127 switch (address->sa_family) { | |
| 128 case AF_INET:{ | |
| 129 struct sockaddr_in *addr = (struct sockaddr_in *)address; | |
| 130 addr->sin_port = ntohs(port); | |
| 131 break; | |
| 132 } | |
| 133 #ifdef CYGPKG_NET_INET6 | |
| 134 case AF_INET6: | |
| 135 { | |
| 136 struct sockaddr_in6 *addr = (struct sockaddr_in6 *)address; | |
| 137 addr->sin6_port = ntohs(port); | |
| 138 break; | |
| 139 } | |
| 140 #endif | |
| 141 default: | |
| 142 break; | |
| 143 } | |
| 144 } | |
| 145 | |
| 146 #ifdef CYGSEM_NET_TFTPD_MULTITHREADED | |
| 147 | |
| 148 // Allocate a semaphore for a given port number if one is not already | |
| 149 // allocated. | |
| 150 static void sem_alloc(int port) { | |
| 151 int i; | |
| 152 | |
| 153 CYG_ASSERT(port != 0, "Invalid port number"); | |
| 154 | |
| 155 cyg_scheduler_lock(); // Avoid race with other tftpd's | |
| 156 for (i=0; i < CYGNUM_NET_TFTPD_MULTITHREADED_PORTS; i++) { | |
| 157 if (tftpd_sems[i].port == port) { | |
| 158 cyg_scheduler_unlock(); | |
| 159 return; | |
| 160 } | |
| 161 if (tftpd_sems[i].port == 0) { | |
| 162 tftpd_sems[i].port = port; | |
| 163 cyg_semaphore_init(&tftpd_sems[i].sem,1); | |
| 164 cyg_scheduler_unlock(); | |
| 165 return ; | |
| 166 } | |
| 167 } | |
| 168 cyg_scheduler_unlock(); | |
| 169 diag_printf("TFTPD: Unable to allocate a semaphore for port %d\n",port); | |
| 170 } | |
| 171 | |
| 172 // Wait on the semaphore for a given port number. | |
| 173 static void sem_wait(int port) { | |
| 174 int i; | |
| 175 CYG_ASSERT(port != 0, "Invalid port number"); | |
| 176 | |
| 177 for (i=0; i < CYGNUM_NET_TFTPD_MULTITHREADED_PORTS; i++) { | |
| 178 if (tftpd_sems[i].port == port) { | |
| 179 cyg_semaphore_wait(&tftpd_sems[i].sem); | |
| 180 return; | |
| 181 } | |
| 182 } | |
| 183 diag_printf("TFTPD: No semaphore for port %d\n",port); | |
| 184 } | |
| 185 | |
| 186 // Release the semaphore for a given port number. | |
| 187 static void sem_post(int port) { | |
| 188 int i; | |
| 189 CYG_ASSERT(port != 0, "Invalid port number"); | |
| 190 | |
| 191 for (i=0; i < CYGNUM_NET_TFTPD_MULTITHREADED_PORTS; i++) { | |
| 192 if (tftpd_sems[i].port == port) { | |
| 193 cyg_semaphore_post(&tftpd_sems[i].sem); | |
| 194 return; | |
| 195 } | |
| 196 } | |
| 197 diag_printf("TFTPD: No semaphore for port %d\n",port); | |
| 198 } | |
| 199 #endif | |
| 200 | |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
201 /* Send an error packet to the client */ |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
202 static void |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
203 tftpd_send_error(int s, struct tftphdr * reply, int err, |
| 957 | 204 struct sockaddr *from_addr, int from_len) |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
205 { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
206 CYG_ASSERT( 0 <= err, "err underflow" ); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
207 CYG_ASSERT( sizeof(errmsg)/sizeof(errmsg[0]) > err, "err overflow" ); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
208 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
209 reply->th_opcode = htons(ERROR); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
210 reply->th_code = htons(err); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
211 if ( (0 > err) || (sizeof(errmsg)/sizeof(errmsg[0]) <= err) ) |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
212 err = 0; // Do not copy a random string from hyperspace |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
213 strcpy(reply->th_msg, errmsg[err]); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
214 sendto(s, reply, 4+strlen(reply->th_msg)+1, 0, |
| 957 | 215 from_addr, from_len); |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
216 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
217 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
218 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
219 // Receive a file from the client |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
220 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
221 static void |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
222 tftpd_write_file(struct tftp_server *server, |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
223 struct tftphdr *hdr, |
| 957 | 224 struct sockaddr *from_addr, int from_len) |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
225 { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
226 char data_out[SEGSIZE+sizeof(struct tftphdr)]; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
227 char data_in[SEGSIZE+sizeof(struct tftphdr)]; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
228 struct tftphdr *reply = (struct tftphdr *)data_out; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
229 struct tftphdr *response = (struct tftphdr *)data_in; |
| 270 | 230 int fd, len, ok, tries, closed, data_len, s; |
| 231 unsigned short block; | |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
232 struct timeval timeout; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
233 fd_set fds; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
234 int total_timeouts = 0; |
| 957 | 235 struct sockaddr client_addr; |
| 236 struct addrinfo hints; | |
| 237 struct addrinfo *res; | |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
238 int client_len; |
| 957 | 239 int error; |
| 240 | |
| 241 memset(&hints,0,sizeof(hints)); | |
| 242 hints.ai_family = from_addr->sa_family; | |
| 243 hints.ai_flags = AI_PASSIVE; | |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
244 |
| 957 | 245 error = getaddrinfo(NULL,"tftp",&hints, &res); |
| 246 if (0 != error) { | |
| 247 diag_printf("TFTPD: can't get a suitable local address: %s\n", | |
| 248 gai_strerror(error)); | |
| 249 return; | |
| 250 } | |
| 251 s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); | |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
252 if (s < 0) { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
253 diag_printf("TFTPD: can't open socket for 'write_file'\n"); |
| 957 | 254 freeaddrinfo(res); |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
255 return; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
256 } |
| 957 | 257 |
| 258 // We want the stack to pick a free local port number | |
| 259 set_port(res->ai_addr,0); | |
| 260 | |
| 261 if (bind(s, res->ai_addr, res->ai_addrlen) < 0) { | |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
262 // Problem setting up my end |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
263 diag_printf("TFTPD: can't bind to reply port for 'write_file'\n"); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
264 close(s); |
| 957 | 265 freeaddrinfo(res); |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
266 return; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
267 } |
|
1621
26840b464238
* src/tftp_server.c: files are now created with the
jlarmour
parents:
1018
diff
changeset
|
268 if ((fd = (server->ops->open)(hdr->th_stuff, O_WRONLY|O_TRUNC|O_CREAT)) < 0) { |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
269 tftpd_send_error(s,reply,TFTP_ENOTFOUND,from_addr, from_len); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
270 close(s); |
| 957 | 271 freeaddrinfo(res); |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
272 return; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
273 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
274 ok = true; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
275 closed = false; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
276 block = 0; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
277 while (ok) { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
278 // Send ACK telling client he can send data |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
279 reply->th_opcode = htons(ACK); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
280 reply->th_block = htons(block++); // postincrement |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
281 for (tries = 0; tries < TFTP_RETRIES_MAX; tries++) { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
282 #ifdef CYGOPT_NET_TFTP_SERVER_INSTRUMENT |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
283 tftp_server_instrument.ack.send++; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
284 #endif |
| 957 | 285 sendto(s, reply, 4, 0, from_addr, from_len); |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
286 repeat_select: |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
287 timeout.tv_sec = TFTP_TIMEOUT_PERIOD; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
288 timeout.tv_usec = 0; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
289 FD_ZERO(&fds); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
290 FD_SET(s, &fds); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
291 if (select(s+1, &fds, 0, 0, &timeout) <= 0) { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
292 if (++total_timeouts > TFTP_TIMEOUT_MAX) { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
293 #ifdef CYGOPT_NET_TFTP_SERVER_INSTRUMENT |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
294 tftp_server_instrument.err_send++; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
295 #endif |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
296 tftpd_send_error(s,reply,TFTP_EBADOP,from_addr, from_len); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
297 ok = false; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
298 break; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
299 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
300 #ifdef CYGOPT_NET_TFTP_SERVER_INSTRUMENT |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
301 tftp_server_instrument.ack.resend++; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
302 #endif |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
303 continue; // retry the send, using up one retry. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
304 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
305 // Some data has arrived |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
306 data_len = sizeof(data_in); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
307 client_len = sizeof(client_addr); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
308 if ((data_len = recvfrom(s, data_in, data_len, 0, |
| 957 | 309 &client_addr, &client_len)) < 0) { |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
310 // What happened? No data here! |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
311 #ifdef CYGOPT_NET_TFTP_SERVER_INSTRUMENT |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
312 tftp_server_instrument.ack.resend++; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
313 #endif |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
314 continue; // retry the send, using up one retry. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
315 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
316 if (ntohs(response->th_opcode) == DATA && |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
317 ntohs(response->th_block) < block) { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
318 #ifdef CYGOPT_NET_TFTP_SERVER_INSTRUMENT |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
319 tftp_server_instrument.data.rx_repeat++; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
320 #endif |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
321 // Then it is repeat DATA with an old block; listen again, |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
322 // but do not repeat sending the current ack, and do not |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
323 // use up a retry count. (we do re-send the ack if |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
324 // subsequently we time out) |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
325 goto repeat_select; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
326 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
327 if (ntohs(response->th_opcode) == DATA && |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
328 ntohs(response->th_block) == block) { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
329 #ifdef CYGOPT_NET_TFTP_SERVER_INSTRUMENT |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
330 tftp_server_instrument.data.rx++; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
331 #endif |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
332 // Good data - write to file |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
333 len = (server->ops->write)(fd, response->th_data, data_len-4); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
334 if (len < (data_len-4)) { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
335 // File is "full" |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
336 tftpd_send_error(s,reply,TFTP_ENOSPACE, |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
337 from_addr, from_len); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
338 ok = false; // Give up |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
339 break; // out of the retries loop |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
340 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
341 if (data_len < (SEGSIZE+4)) { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
342 // End of file |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
343 closed = true; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
344 ok = false; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
345 if ((server->ops->close)(fd) == -1) { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
346 tftpd_send_error(s,reply,TFTP_EACCESS, |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
347 from_addr, from_len); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
348 break; // out of the retries loop |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
349 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
350 // Exception to the loop structure: we must ACK the last |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
351 // packet, the one that implied EOF: |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
352 #ifdef CYGOPT_NET_TFTP_SERVER_INSTRUMENT |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
353 tftp_server_instrument.ack.send++; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
354 #endif |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
355 reply->th_opcode = htons(ACK); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
356 reply->th_block = htons(block++); // postincrement |
| 957 | 357 sendto(s, reply, 4, 0, from_addr, from_len); |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
358 break; // out of the retries loop |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
359 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
360 // Happy! Break out of the retries loop. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
361 break; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
362 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
363 // Otherwise, we got something we do not understand! So repeat |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
364 // sending the current ACK, and use up a retry count. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
365 #ifdef CYGOPT_NET_TFTP_SERVER_INSTRUMENT |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
366 if ( (ntohs(response->th_opcode) == DATA) ) |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
367 tftp_server_instrument.data.rx_skip++; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
368 tftp_server_instrument.ack.resend++; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
369 #endif |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
370 } // End of the retries loop. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
371 if (TFTP_RETRIES_MAX <= tries) { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
372 #ifdef CYGOPT_NET_TFTP_SERVER_INSTRUMENT |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
373 tftp_server_instrument.err_send++; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
374 #endif |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
375 tftpd_send_error(s,reply,TFTP_EBADOP,from_addr, from_len); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
376 ok = false; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
377 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
378 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
379 close(s); |
| 957 | 380 freeaddrinfo(res); |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
381 if (!closed) { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
382 (server->ops->close)(fd); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
383 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
384 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
385 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
386 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
387 // Send a file to the client |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
388 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
389 static void |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
390 tftpd_read_file(struct tftp_server *server, |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
391 struct tftphdr *hdr, |
| 957 | 392 struct sockaddr *from_addr, int from_len) |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
393 { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
394 char data_out[SEGSIZE+sizeof(struct tftphdr)]; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
395 char data_in[SEGSIZE+sizeof(struct tftphdr)]; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
396 struct tftphdr *reply = (struct tftphdr *)data_out; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
397 struct tftphdr *response = (struct tftphdr *)data_in; |
| 270 | 398 int fd, len, tries, ok, data_len, s; |
| 399 unsigned short block; | |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
400 struct timeval timeout; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
401 fd_set fds; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
402 int total_timeouts = 0; |
| 957 | 403 struct sockaddr client_addr; |
| 404 struct addrinfo hints; | |
| 405 struct addrinfo *res; | |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
406 int client_len; |
| 957 | 407 int error; |
| 408 | |
| 409 memset(&hints,0,sizeof(hints)); | |
| 410 hints.ai_family = from_addr->sa_family; | |
| 411 hints.ai_flags = AI_PASSIVE; | |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
412 |
| 957 | 413 error = getaddrinfo(NULL,"tftp",&hints, &res); |
| 414 if (0 != error) { | |
| 415 diag_printf("TFTPD: can't get a suitable local address: %s\n", | |
| 416 gai_strerror(error)); | |
| 417 return; | |
| 418 } | |
| 419 s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); | |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
420 if (s < 0) { |
| 957 | 421 diag_printf("TFTPD: can't open socket for 'write_file'\n"); |
| 422 freeaddrinfo(res); | |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
423 return; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
424 } |
| 957 | 425 |
| 426 // We want the stack to pick a free local port number | |
| 427 set_port(res->ai_addr,0); | |
| 428 | |
| 429 if (bind(s, res->ai_addr, res->ai_addrlen) < 0) { | |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
430 // Problem setting up my end |
| 957 | 431 diag_printf("TFTPD: can't bind to reply port for 'write_file'\n"); |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
432 close(s); |
| 957 | 433 freeaddrinfo(res); |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
434 return; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
435 } |
| 957 | 436 |
|
1018
3737492e03d1
* src/tftp_server.c (tftpd_read_file): Open the file for reading,
asl
parents:
1007
diff
changeset
|
437 if ((fd = (server->ops->open)(hdr->th_stuff, O_RDONLY)) < 0) { |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
438 tftpd_send_error(s,reply,TFTP_ENOTFOUND,from_addr, from_len); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
439 close(s); |
| 957 | 440 freeaddrinfo(res); |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
441 return; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
442 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
443 block = 0; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
444 ok = true; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
445 while (ok) { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
446 // Read next chunk of file |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
447 len = (server->ops->read)(fd, reply->th_data, SEGSIZE); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
448 reply->th_block = htons(++block); // preincrement |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
449 reply->th_opcode = htons(DATA); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
450 for (tries = 0; tries < TFTP_RETRIES_MAX; tries++) { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
451 #ifdef CYGOPT_NET_TFTP_SERVER_INSTRUMENT |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
452 tftp_server_instrument.data.send++; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
453 #endif |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
454 if (sendto(s, reply, 4+len, 0, |
| 957 | 455 from_addr, from_len) < 0) { |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
456 // Something went wrong with the network! |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
457 ok = false; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
458 break; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
459 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
460 repeat_select: |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
461 timeout.tv_sec = TFTP_TIMEOUT_PERIOD; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
462 timeout.tv_usec = 0; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
463 FD_ZERO(&fds); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
464 FD_SET(s, &fds); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
465 if (select(s+1, &fds, 0, 0, &timeout) <= 0) { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
466 if (++total_timeouts > TFTP_TIMEOUT_MAX) { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
467 #ifdef CYGOPT_NET_TFTP_SERVER_INSTRUMENT |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
468 tftp_server_instrument.err_send++; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
469 #endif |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
470 tftpd_send_error(s,reply,TFTP_EBADOP,from_addr, from_len); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
471 ok = false; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
472 break; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
473 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
474 #ifdef CYGOPT_NET_TFTP_SERVER_INSTRUMENT |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
475 tftp_server_instrument.data.resend++; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
476 #endif |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
477 continue; // retry the send, using up one retry. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
478 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
479 data_len = sizeof(data_in); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
480 client_len = sizeof(client_addr); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
481 if ((data_len = recvfrom(s, data_in, data_len, 0, |
| 957 | 482 &client_addr, |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
483 &client_len)) < 0) { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
484 // What happened? Maybe someone lied to us... |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
485 #ifdef CYGOPT_NET_TFTP_SERVER_INSTRUMENT |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
486 tftp_server_instrument.data.resend++; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
487 #endif |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
488 continue; // retry the send, using up one retry. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
489 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
490 if ((ntohs(response->th_opcode) == ACK) && |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
491 (ntohs(response->th_block) < block)) { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
492 #ifdef CYGOPT_NET_TFTP_SERVER_INSTRUMENT |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
493 tftp_server_instrument.ack.rx_repeat++; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
494 #endif |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
495 // Then it is a repeat ACK for an old block; listen again, |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
496 // but do not repeat sending the current block, and do not |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
497 // use up a retry count. (we do re-send the data if |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
498 // subsequently we time out) |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
499 goto repeat_select; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
500 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
501 if ((ntohs(response->th_opcode) == ACK) && |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
502 (ntohs(response->th_block) == block)) { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
503 #ifdef CYGOPT_NET_TFTP_SERVER_INSTRUMENT |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
504 tftp_server_instrument.ack.rx++; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
505 #endif |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
506 // Happy! Break out of the retries loop. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
507 break; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
508 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
509 // Otherwise, we got something we do not understand! So repeat |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
510 // sending the current block, and use up a retry count. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
511 #ifdef CYGOPT_NET_TFTP_SERVER_INSTRUMENT |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
512 if ( (ntohs(response->th_opcode) == ACK) ) |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
513 tftp_server_instrument.ack.rx_skip++; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
514 tftp_server_instrument.data.resend++; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
515 #endif |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
516 } // End of the retries loop. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
517 if (TFTP_RETRIES_MAX <= tries) { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
518 #ifdef CYGOPT_NET_TFTP_SERVER_INSTRUMENT |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
519 tftp_server_instrument.err_send++; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
520 #endif |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
521 tftpd_send_error(s,reply,TFTP_EBADOP,from_addr, from_len); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
522 ok = false; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
523 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
524 if (len < SEGSIZE) { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
525 break; // That's end of file then. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
526 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
527 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
528 close(s); |
| 957 | 529 freeaddrinfo(res); |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
530 (server->ops->close)(fd); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
531 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
532 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
533 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
534 // Actual TFTP server |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
535 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
536 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
537 static void |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
538 tftpd_server(cyg_addrword_t p) |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
539 { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
540 struct tftp_server *server = (struct tftp_server *)p; |
| 957 | 541 int max_s = 0; |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
542 int data_len, recv_len, from_len; |
| 957 | 543 struct sockaddr from_addr; |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
544 char data[SEGSIZE+sizeof(struct tftphdr)]; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
545 struct tftphdr *hdr = (struct tftphdr *)data; |
| 957 | 546 struct addrinfo hints; |
| 547 struct addrinfo *ai; | |
| 548 fd_set readfds; | |
| 549 char name[64]; | |
| 550 int error; | |
| 551 int i; | |
| 552 #ifdef CYGOPT_NET_TFTP_SERVER_INSTRUMENT | |
| 553 struct info o = tftp_server_instrument; | |
| 554 #endif | |
| 555 | |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
556 #ifndef CYGPKG_NET_TESTS_USE_RT_TEST_HARNESS |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
557 // Otherwise routine printfs fail the test - interrupts disabled too long. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
558 diag_printf("TFTPD [%x]: port %d\n", p, server->port); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
559 #endif |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
560 |
| 957 | 561 memset(&hints,0,sizeof(hints)); |
| 562 hints.ai_family = PF_UNSPEC; | |
| 563 hints.ai_flags = AI_PASSIVE; | |
| 564 | |
| 565 error = getaddrinfo(NULL,"tftp",&hints, &server->res); | |
| 566 if (0 != error) { | |
| 567 diag_printf("TFTPD [%p] : can't get a local server address to bind to: %s\n", | |
| 568 p, gai_strerror(error)); | |
| 569 return; | |
| 570 } | |
| 571 | |
| 572 // If the port is 0, we need to use the default TFTP port. Extrace | |
| 573 // the port number from one of the addresses returned by | |
| 574 // getaddrinfo. | |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
575 if (server->port == 0) { |
| 957 | 576 switch (server->res->ai_family) { |
| 577 case AF_INET: | |
| 578 { | |
| 579 struct sockaddr_in *addr = (struct sockaddr_in *)server->res->ai_addr; | |
| 580 server->port = ntohs(addr->sin_port); | |
| 581 break; | |
| 582 } | |
| 583 #ifdef CYGPKG_NET_INET6 | |
| 584 case AF_INET6: | |
| 585 { | |
| 586 struct sockaddr_in6 *addr = (struct sockaddr_in6 *)server->res->ai_addr; | |
| 587 server->port = ntohs(addr->sin6_port); | |
| 588 break; | |
| 589 } | |
| 590 #endif | |
| 591 default: | |
| 592 break; | |
| 593 } | |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
594 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
595 |
| 957 | 596 #ifdef CYGSEM_NET_TFTPD_MULTITHREADED |
| 597 sem_alloc(server->port); | |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
598 while (true) { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
599 #endif |
| 957 | 600 // Iterate over the addresses and create a local port to listen for requests |
| 601 ai = server->res; | |
| 602 memset(server->s,0,sizeof(server->s)); | |
| 603 server->num_s = 0; | |
|
1007
16d247bb9c70
* src/ifaddrs.c (getifaddrs): Fill in flags, netmask and broadcast
asl
parents:
957
diff
changeset
|
604 #ifdef CYGSEM_NET_TFTPD_MULTITHREADED |
|
16d247bb9c70
* src/ifaddrs.c (getifaddrs): Fill in flags, netmask and broadcast
asl
parents:
957
diff
changeset
|
605 sem_wait(server->port); |
|
16d247bb9c70
* src/ifaddrs.c (getifaddrs): Fill in flags, netmask and broadcast
asl
parents:
957
diff
changeset
|
606 #endif |
| 957 | 607 while (ai && (server->num_s < CYGNUM_NET_MAX_INET_PROTOS)) { |
| 608 server->s[server->num_s] = socket(ai->ai_family, | |
| 609 ai->ai_socktype, | |
| 610 ai->ai_protocol); | |
| 611 if (server->s[server->num_s] < 0 ) { | |
| 612 diag_printf("TFTPD [%x]: can't open socket\n", p); | |
| 613 freeaddrinfo(server->res); | |
| 614 server->res = NULL; | |
| 615 return; | |
| 616 } | |
| 617 | |
| 618 set_port(ai->ai_addr, server->port); | |
| 619 | |
| 620 if (bind(server->s[server->num_s],ai->ai_addr, ai->ai_addrlen) < 0) { | |
| 621 // Problem setting up my end | |
| 622 diag_printf("TFTPD [%x]: can't bind to server port\n",p); | |
| 623 close(server->s[server->num_s]); | |
| 624 server->s[server->num_s] = 0; | |
| 625 ai = ai->ai_next; | |
| 626 continue; | |
| 627 } | |
| 628 // We need to know the highest socket number for select. | |
| 629 if (server->s[server->num_s] > max_s) | |
| 630 max_s = server->s[server->num_s]; | |
| 631 server->num_s++; | |
| 632 ai = ai->ai_next; | |
| 633 } | |
| 634 | |
| 635 #ifndef CYGSEM_NET_TFTPD_MULTITHREADED | |
| 636 while (true) { | |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
637 #endif |
| 957 | 638 FD_ZERO(&readfds); |
| 639 for (i=0; i < CYGNUM_NET_MAX_INET_PROTOS; i++) { | |
| 640 if (server->s[i]) { | |
| 641 FD_SET(server->s[i],&readfds); | |
| 642 } | |
| 643 } | |
| 644 error = select(max_s+1,&readfds,NULL,NULL,NULL); | |
| 645 if ( -1 == error) { | |
| 646 diag_printf("TFTPD [%x]: error in select\n",p); | |
| 647 } | |
| 648 for (i=0; i < CYGNUM_NET_MAX_INET_PROTOS; i++) { | |
| 649 if (server->s[i] && FD_ISSET(server->s[i],&readfds)) { | |
| 650 recv_len = sizeof(data); | |
| 651 from_len = sizeof(from_addr); | |
| 652 data_len = recvfrom(server->s[i], hdr, recv_len, 0, | |
| 653 &from_addr, &from_len); | |
| 654 if ( data_len < 0) { | |
| 655 diag_printf("TFTPD [%x]: can't read request\n", p); | |
| 656 } else { | |
| 657 #ifdef CYGSEM_NET_TFTPD_MULTITHREADED | |
| 658 // Close the socket and post on the semaphore some | |
| 659 // another thread can start listening for requests. This | |
| 660 // is not quite right. select could of returned with more than | |
| 661 // one socket with data to read. Here we only deal with one of them | |
| 662 for (i=0; i < CYGNUM_NET_MAX_INET_PROTOS; i++) { | |
| 663 if (server->s[i]) { | |
| 664 close (server->s[i]); | |
| 665 server->s[i] = 0; | |
| 666 } | |
| 667 } | |
| 668 sem_post(server->port); | |
| 669 #endif | |
| 670 #ifndef CYGPKG_NET_TESTS_USE_RT_TEST_HARNESS | |
| 671 getnameinfo(&from_addr,sizeof(from_addr), name, sizeof(name),0,0,0); | |
| 672 diag_printf("TFTPD [%x]: received %x from %s\n", p, | |
| 673 ntohs(hdr->th_opcode), name); | |
| 674 #endif | |
| 675 switch (ntohs(hdr->th_opcode)) { | |
| 676 case WRQ: | |
| 677 tftpd_write_file(server, hdr, &from_addr, from_len); | |
| 678 break; | |
| 679 case RRQ: | |
| 680 tftpd_read_file(server, hdr, &from_addr, from_len); | |
| 681 break; | |
| 682 case ACK: | |
| 683 case DATA: | |
| 684 case ERROR: | |
| 685 // Ignore | |
| 686 break; | |
| 687 default: | |
| 688 getnameinfo(&from_addr,sizeof(from_addr), name, sizeof(name),0,0,0); | |
| 689 diag_printf("TFTPD [%x]: bogus request %x from %s\n", p, | |
| 690 ntohs(hdr->th_opcode), | |
| 691 name); | |
| 692 tftpd_send_error(server->s[i],hdr,TFTP_EBADOP,&from_addr,from_len); | |
| 693 } | |
| 694 | |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
695 #ifdef CYGOPT_NET_TFTP_SERVER_INSTRUMENT |
| 957 | 696 tftp_server_instrument.total_transactions++; |
| 697 | |
| 698 o.data.rx -= tftp_server_instrument.data.rx ; | |
| 699 o.data.rx_repeat -= tftp_server_instrument.data.rx_repeat; | |
| 700 o.data.rx_skip -= tftp_server_instrument.data.rx_skip ; | |
| 701 o.data.send -= tftp_server_instrument.data.send ; | |
| 702 o.data.resend -= tftp_server_instrument.data.resend ; | |
| 703 | |
| 704 o.ack.rx -= tftp_server_instrument.ack.rx ; | |
| 705 o.ack.rx_repeat -= tftp_server_instrument.ack.rx_repeat ; | |
| 706 o.ack.rx_skip -= tftp_server_instrument.ack.rx_skip ; | |
| 707 o.ack.send -= tftp_server_instrument.ack.send ; | |
| 708 o.ack.resend -= tftp_server_instrument.ack.resend ; | |
| 709 | |
| 710 o.err_send -= tftp_server_instrument.err_send ; | |
| 711 | |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
712 #ifndef CYGPKG_NET_TESTS_USE_RT_TEST_HARNESS |
| 957 | 713 if ( o.data.rx ) diag_printf( "data rx %4d\n", -o.data.rx ); |
| 714 if ( o.data.rx_repeat ) diag_printf( "data rx_repeat%4d\n", -o.data.rx_repeat ); | |
| 715 if ( o.data.rx_skip ) diag_printf( "data rx_skip %4d\n", -o.data.rx_skip ); | |
| 716 if ( o.data.send ) diag_printf( "data send %4d\n", -o.data.send ); | |
| 717 if ( o.data.resend ) diag_printf( "data resend %4d\n", -o.data.resend ); | |
| 718 | |
| 719 if ( o.ack.rx ) diag_printf( " ack rx %4d\n", -o.ack.rx ); | |
| 720 if ( o.ack.rx_repeat ) diag_printf( " ack rx_repeat%4d\n", -o.ack.rx_repeat ); | |
| 721 if ( o.ack.rx_skip ) diag_printf( " ack rx_skip %4d\n", -o.ack.rx_skip ); | |
| 722 if ( o.ack.send ) diag_printf( " ack send %4d\n", -o.ack.send ); | |
| 723 if ( o.ack.resend ) diag_printf( " ack resend %4d\n", -o.ack.resend ); | |
| 724 | |
| 725 if ( o.err_send ) diag_printf( "*error sends %4d\n", -o.err_send ); | |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
726 #endif // CYGPKG_NET_TESTS_USE_RT_TEST_HARNESS |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
727 #endif // CYGOPT_NET_TFTP_SERVER_INSTRUMENT |
| 957 | 728 #ifdef CYGSEM_NET_TFTPD_MULTITHREADED |
| 729 break; | |
| 730 #endif | |
| 731 } | |
| 732 } | |
| 733 } | |
| 734 // The following looks a little strange, but it keeps emacs's | |
| 735 // auto indention happy. | |
| 736 #ifndef CYGSEM_NET_TFTPD_MULTITHREADED | |
| 737 } | |
| 738 #endif | |
| 739 #ifdef CYGSEM_NET_TFTPD_MULTITHREADED | |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
740 } |
| 957 | 741 #endif |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
742 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
743 |
| 957 | 744 |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
745 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
746 // This function is used to create a new server [thread] which supports |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
747 // the TFTP protocol on the given port. A server 'id' will be returned |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
748 // which can later be used to destroy the server. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
749 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
750 // Note: all [memory] resources for the server thread will be allocated |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
751 // dynamically. If there are insufficient resources, an error will be |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
752 // returned. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
753 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
754 int |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
755 tftpd_start(int port, struct tftpd_fileops *ops) |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
756 { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
757 struct tftp_server *server; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
758 #ifdef CYGSEM_TFTP_SERVER_MULTITHREADED |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
759 static char init = 0; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
760 if ( 0 == init ) { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
761 init++; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
762 cyg_semaphore_init( &tftp_server_sem, 0 ); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
763 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
764 #endif |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
765 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
766 if ((server = malloc(sizeof(struct tftp_server)))) { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
767 server->tag = TFTP_tag; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
768 server->port = port; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
769 server->ops = ops; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
770 cyg_thread_create(CYGPKG_NET_TFTPD_THREAD_PRIORITY, // Priority |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
771 tftpd_server, // entry |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
772 (cyg_addrword_t)server, // entry parameter |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
773 "TFTP server", // Name |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
774 &server->stack[0], // Stack |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
775 STACK_SIZE, // Size |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
776 &server->thread_handle, // Handle |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
777 &server->thread_data // Thread data structure |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
778 ); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
779 cyg_thread_resume(server->thread_handle); // Start it |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
780 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
781 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
782 return (int)server; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
783 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
784 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
785 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
786 // Destroy a TFTP server, using a previously created server 'id'. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
787 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
788 int |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
789 tftpd_stop(int p) |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
790 { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
791 struct tftp_server *server = (struct tftp_server *)p; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
792 // Simple sanity check |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
793 if (server->tag == TFTP_tag) { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
794 cyg_thread_kill(server->thread_handle); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
795 cyg_thread_set_priority(server->thread_handle, 0); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
796 cyg_thread_delay(1); // Make sure it gets to die... |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
797 if (cyg_thread_delete(server->thread_handle)) { |
| 957 | 798 // Success shutting down the thread. Close all its sockets. |
| 799 int i; | |
| 800 for (i = 0 ; i < CYGNUM_NET_MAX_INET_PROTOS; i++) { | |
| 801 if (server->s[i]) { | |
| 802 close (server->s[i]); | |
| 803 } | |
| 804 } | |
| 805 freeaddrinfo(server->res); | |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
806 free(server); // Give up memory |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
807 return 1; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
808 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
809 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
810 return 0; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
811 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
812 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
813 // EOF tftp_server.c |
