diff options
Diffstat (limited to 'contrib/mini-slamd')
-rw-r--r-- | contrib/mini-slamd/COPYING | 339 | ||||
-rw-r--r-- | contrib/mini-slamd/Makefile | 8 | ||||
-rw-r--r-- | contrib/mini-slamd/mini-slamd.c | 521 |
3 files changed, 0 insertions, 868 deletions
diff --git a/contrib/mini-slamd/COPYING b/contrib/mini-slamd/COPYING deleted file mode 100644 index a43ea212..00000000 --- a/contrib/mini-slamd/COPYING +++ /dev/null @@ -1,339 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 675 Mass Ave, Cambridge, MA 02139, USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - Appendix: How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - <one line to give the program's name and a brief idea of what it does.> - Copyright (C) 19yy <name of author> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) 19yy name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - <signature of Ty Coon>, 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. diff --git a/contrib/mini-slamd/Makefile b/contrib/mini-slamd/Makefile deleted file mode 100644 index 05f1a366..00000000 --- a/contrib/mini-slamd/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -CC=gcc -CFLAGS=-Wall -O2 - -mini-slamd: mini-slamd.c - $(CC) $(CFLAGS) -o $@ $< - -clean: - rm -f mini-slamd
\ No newline at end of file diff --git a/contrib/mini-slamd/mini-slamd.c b/contrib/mini-slamd/mini-slamd.c deleted file mode 100644 index 7c33e22b..00000000 --- a/contrib/mini-slamd/mini-slamd.c +++ /dev/null @@ -1,521 +0,0 @@ -/* - * mini-slamd - * (c) 2002 Eric Biederman - */ - -#include <string.h> -#include <errno.h> -#include <stdio.h> -#include <stdint.h> -#include <stdlib.h> -#include <sys/types.h> -#include <sys/poll.h> -#include <sys/socket.h> -#include <sys/stat.h> -#include <netinet/ip.h> -#include <netinet/in.h> -#include <fcntl.h> -#include <unistd.h> -#include <arpa/inet.h> - -/* - * To specify the default interface for multicast packets use: - * route add -net 224.0.0.0 netmask 240.0.0.0 dev eth1 - * This server is stupid and does not override the default. - */ - -/* Sever states. - * - * Waiting for clients. - * Sending data to clients. - * Pinging clients for data. - * - */ -#define SLAM_PORT 10000 -#define SLAM_MULTICAST_IP ((239<<24)|(255<<16)|(1<<8)|(1<<0)) -#define SLAM_MULTICAST_PORT 10000 -#define SLAM_MULTICAST_TTL 1 -#define SLAM_MULTICAST_LOOPBACK 1 -#define SLAM_MAX_CLIENTS 10 - -#define SLAM_PING_TIMEOUT 100 /* ms */ - -/*** Packets Formats *** - * Data Packet: - * transaction - * total bytes - * block size - * packet # - * data - * - * Status Request Packet - * transaction - * total bytes - * block packets - * - * Status Packet - * received packets - * requested packets - * received packets - * requested packets - * ... - * received packets - * requested packtes - * 0 - */ - -#define MAX_HDR (7 + 7 + 7) /* transaction, total size, block size */ -#define MIN_HDR (1 + 1 + 1) /* transaction, total size, block size */ - -#define MAX_DATA_HDR (MAX_HDR + 7) /* header, packet # */ -#define MIN_DATA_HDR (MAX_HDR + 1) /* header, packet # */ - -/* ETH_MAX_MTU 1500 - sizeof(iphdr) 20 - sizeof(udphdr) 8 = 1472 */ -#define SLAM_MAX_NACK (1500 - (20 + 8)) -/* ETH_MAX_MTU 1500 - sizeof(iphdr) 20 - sizeof(udphdr) 8 - MAX_HDR = 1451 */ -#define SLAM_BLOCK_SIZE (1500 - (20 + 8 + MAX_HDR)) - - -/* Define how many debug messages you want - * 1 - sparse but useful - * 2 - everything - */ -#ifndef DEBUG -#define DEBUG 0 -#endif - -static int slam_encode( - unsigned char **ptr, unsigned char *end, unsigned long value) -{ - unsigned char *data = *ptr; - int bytes; - bytes = sizeof(value); - while ((bytes > 0) && ((0xff & (value >> ((bytes -1)<<3))) == 0)) { - bytes--; - } - if (bytes <= 0) { - bytes = 1; - } - if (data + bytes >= end) { - return -1; - } - if ((0xe0 & (value >> ((bytes -1)<<3))) == 0) { - /* packed together */ - *data = (bytes << 5) | (value >> ((bytes -1)<<3)); - } else { - bytes++; - *data = (bytes << 5); - } - bytes--; - data++; - while(bytes) { - *(data++) = 0xff & (value >> ((bytes -1)<<3)); - bytes--; - } - *ptr = data; - return 0; -} - -static unsigned long slam_decode(unsigned char **ptr, unsigned char *end, int *err) -{ - unsigned long value; - unsigned bytes; - if (*ptr >= end) { - *err = -1; - } - bytes = ((**ptr) >> 5) & 7; - if ((bytes == 0) || (bytes > sizeof(unsigned long))) { - *err = -1; - return 0; - } - if ((*ptr) + bytes >= end) { - *err = -1; - } - value = (**ptr) & 0x1f; - bytes--; - (*ptr)++; - while(bytes) { - value <<= 8; - value |= **ptr; - (*ptr)++; - bytes--; - } - return value; -} - - -static struct sockaddr_in client[SLAM_MAX_CLIENTS]; -static int clients; - - -void del_client(struct sockaddr_in *old) -{ - int i; - for(i = 0; i < clients; i++) { - if ((client[i].sin_family == old->sin_family) && - (client[i].sin_addr.s_addr == old->sin_addr.s_addr) && - (client[i].sin_port == old->sin_port)) { - memmove(&client[i], &client[i+1], - (clients - (i+1))*sizeof(client[0])); - clients--; - } - } -} - -void add_client(struct sockaddr_in *new) -{ - del_client(new); - if (clients >= SLAM_MAX_CLIENTS) - return; - memcpy(&client[clients], new, sizeof(*new)); - clients++; -} - -void push_client(struct sockaddr_in *new) -{ - del_client(new); - if (clients >= SLAM_MAX_CLIENTS) { - clients--; - } - memmove(&client[1], &client[0], clients*sizeof(*new)); - memcpy(&client[0], new, sizeof(*new)); - clients++; -} - - -void next_client(struct sockaddr_in *next) -{ - /* Find the next client we want to ping next */ - if (!clients) { - next->sin_family = AF_UNSPEC; - return; - } - /* Return the first client */ - memcpy(next, &client[0], sizeof(*next)); -} - -int main(int argc, char **argv) -{ - char *filename; - uint8_t nack_packet[SLAM_MAX_NACK]; - int nack_len; - uint8_t request_packet[MAX_HDR]; - int request_len; - uint8_t data_packet[MAX_DATA_HDR + SLAM_BLOCK_SIZE]; - int data_len; - uint8_t *ptr, *end; - struct sockaddr_in master_client; - struct sockaddr_in sa_src; - struct sockaddr_in sa_mcast; - uint8_t mcast_ttl; - uint8_t mcast_loop; - int sockfd, filefd; - int result; - struct pollfd fds[1]; - int state; -#define STATE_PINGING 1 -#define STATE_WAITING 2 -#define STATE_RECEIVING 3 -#define STATE_TRANSMITTING 4 - off_t size; - struct stat st; - uint64_t transaction; - unsigned long packet; - unsigned long packet_count; - unsigned slam_port, slam_multicast_port; - struct in_addr slam_multicast_ip; - - slam_port = SLAM_PORT; - slam_multicast_port = SLAM_MULTICAST_PORT; - slam_multicast_ip.s_addr = htonl(SLAM_MULTICAST_IP); - - if (argc != 2) { - fprintf(stderr, "Bad argument count\n"); - fprintf(stderr, "Usage: mini-slamd filename\n"); - exit(EXIT_FAILURE); - } - filename = argv[1]; - filefd = -1; - size = 0; - transaction = 0; - - /* Setup the udp socket */ - sockfd = socket(PF_INET, SOCK_DGRAM, 0); - if (sockfd < 0) { - fprintf(stderr, "Cannot create socket\n"); - exit(EXIT_FAILURE); - } - memset(&sa_src, 0, sizeof(sa_src)); - sa_src.sin_family = AF_INET; - sa_src.sin_port = htons(slam_port); - sa_src.sin_addr.s_addr = INADDR_ANY; - - result = bind(sockfd, &sa_src, sizeof(sa_src)); - if (result < 0) { - fprintf(stderr, "Cannot bind socket to port %d\n", - ntohs(sa_src.sin_port)); - exit(EXIT_FAILURE); - } - - /* Setup the multicast transmission address */ - memset(&sa_mcast, 0, sizeof(sa_mcast)); - sa_mcast.sin_family = AF_INET; - sa_mcast.sin_port = htons(slam_multicast_port); - sa_mcast.sin_addr.s_addr = slam_multicast_ip.s_addr; - if (!IN_MULTICAST(ntohl(sa_mcast.sin_addr.s_addr))) { - fprintf(stderr, "Not a multicast ip\n"); - exit(EXIT_FAILURE); - } - - /* Set the multicast ttl */ - mcast_ttl = SLAM_MULTICAST_TTL; - setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_TTL, - &mcast_ttl, sizeof(mcast_ttl)); - - /* Set the multicast loopback status */ - mcast_loop = SLAM_MULTICAST_LOOPBACK; - setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_LOOP, &mcast_loop, sizeof(mcast_loop)); - - - state = STATE_WAITING; - packet = 0; - packet_count = 0; - fds[0].fd = sockfd; - fds[0].events = POLLIN; - fds[0].revents = 0; - for(;;) { - switch(state) { - case STATE_PINGING: - state = STATE_WAITING; - next_client(&master_client); - if (master_client.sin_family == AF_UNSPEC) { - break; - } -#if DEBUG - printf("Pinging %s:%d\n", - inet_ntoa(master_client.sin_addr), - ntohs(master_client.sin_port)); - fflush(stdout); -#endif - - /* Prepare the request packet, it is all header */ - ptr = request_packet; - end = &request_packet[sizeof(request_packet) -1]; - slam_encode(&ptr, end, transaction); - slam_encode(&ptr, end, size); - slam_encode(&ptr, end, SLAM_BLOCK_SIZE); - request_len = ptr - request_packet; - - result = sendto(sockfd, request_packet, request_len, 0, - &master_client, sizeof(master_client)); - /* Forget the client I just asked, when the reply - * comes in we will remember it again. - */ - del_client(&master_client); - break; - case STATE_WAITING: - { - int timeout; - int from_len; - timeout = -1; - if (master_client.sin_family != AF_UNSPEC) { - timeout = SLAM_PING_TIMEOUT; - } - result = poll(fds, sizeof(fds)/sizeof(fds[0]), timeout); - if (result == 0) { - /* On a timeout try the next client */ - state = STATE_PINGING; - break; - } - if (result > 0) { - from_len = sizeof(master_client); - result = recvfrom(sockfd, - nack_packet, sizeof(nack_packet), 0, - &master_client, &from_len); - if (result < 0) - break; - nack_len = result; -#if DEBUG - printf("Received Nack from %s:%d\n", - inet_ntoa(master_client.sin_addr), - ntohs(master_client.sin_port)); - fflush(stdout); -#endif -#if DEBUG - { - ptr = nack_packet; - end = ptr + result; - packet = 0; - result = 0; - while(ptr < end) { - packet += slam_decode(&ptr, end, &result); - if (result < 0) break; - packet_count = slam_decode(&ptr, end, &result); - if (result < 0) break; - printf("%d-%d ", - packet, packet + packet_count -1); - } - printf("\n"); - fflush(stdout); - } -#endif - /* Forget this client temporarily. - * If the packet appears good they will be - * readded. - */ - del_client(&master_client); - ptr = nack_packet; - end = ptr + nack_len; - result = 0; - packet = slam_decode(&ptr, end, &result); - if (result < 0) - break; - packet_count = slam_decode(&ptr, end, &result); - if (result < 0) - break; - /* We appear to have a good packet, keep - * this client. - */ - push_client(&master_client); - - /* Reopen the file to transmit */ - if (filefd != -1) { - close(filefd); - } - filefd = open(filename, O_RDONLY); - if (filefd < 0) { - fprintf(stderr, "Cannot open %s: %s\n", - filename, strerror(errno)); - break; - } - size = lseek(filefd, 0, SEEK_END); - if (size < 0) { - fprintf(stderr, "Seek failed on %s: %s\n", - filename, strerror(errno)); - break; - } - result = fstat(filefd, &st); - if (result < 0) { - fprintf(stderr, "Stat failed on %s: %s\n", - filename, strerror(errno)); - break; - } - transaction = st.st_mtime; - - state = STATE_TRANSMITTING; - break; - } - break; - } - case STATE_RECEIVING: - /* Now clear the queue of received packets */ - { - struct sockaddr_in from; - int from_len; - uint8_t dummy_packet[SLAM_MAX_NACK]; - state = STATE_TRANSMITTING; - result = poll(fds, sizeof(fds)/sizeof(fds[0]), 0); - if (result < 1) - break; - from_len = sizeof(from); - result = recvfrom(sockfd, - dummy_packet, sizeof(dummy_packet), 0, - &from, &from_len); - if (result <= 0) - break; -#if DEBUG - printf("Received Nack from %s:%d\n", - inet_ntoa(from.sin_addr), - ntohs(from.sin_port)); - fflush(stdout); -#endif - /* Receive packets until I don't get any more */ - state = STATE_RECEIVING; - /* Process a packet */ - if (dummy_packet[0] == '\0') { - /* If the first byte is null it is a disconnect - * packet. - */ - del_client(&from); - } - else { - /* Otherwise attempt to add the client. */ - add_client(&from); - } - break; - } - case STATE_TRANSMITTING: - { - off_t off; - off_t offset; - ssize_t bytes; - uint8_t *ptr2, *end2; - - /* After I transmit a packet check for packets to receive. */ - state = STATE_RECEIVING; - - /* Find the packet to transmit */ - offset = packet * SLAM_BLOCK_SIZE; - - /* Seek to the desired packet */ - off = lseek(filefd, offset, SEEK_SET); - if ((off < 0) || (off != offset)) { - fprintf(stderr, "Seek failed on %s:%s\n", - filename, strerror(errno)); - break; - } - /* Encode the packet header */ - ptr2 = data_packet; - end2 = data_packet + sizeof(data_packet); - slam_encode(&ptr2, end2, transaction); - slam_encode(&ptr2, end2, size); - slam_encode(&ptr2, end2, SLAM_BLOCK_SIZE); - slam_encode(&ptr2, end2, packet); - data_len = ptr2 - data_packet; - - /* Read in the data */ - bytes = read(filefd, &data_packet[data_len], - SLAM_BLOCK_SIZE); - if (bytes <= 0) { - fprintf(stderr, "Read failed on %s:%s\n", - filename, strerror(errno)); - break; - } - data_len += bytes; - /* Write out the data */ - result = sendto(sockfd, data_packet, data_len, 0, - &sa_mcast, sizeof(sa_mcast)); - if (result != data_len) { - fprintf(stderr, "Send failed %s\n", - strerror(errno)); - break; - } -#if DEBUG > 1 - printf("Transmitted: %d\n", packet); - fflush(stdout); -#endif - /* Compute the next packet */ - packet++; - packet_count--; - if (packet_count == 0) { - packet += slam_decode(&ptr, end, &result); - if (result >= 0) - packet_count = slam_decode(&ptr, end, &result); - if (result < 0) { - /* When a transmission is done close the file, - * so it may be updated. And then ping then start - * pinging clients to get the transmission started - * again. - */ - state = STATE_PINGING; - close(filefd); - filefd = -1; - break; - } - } - break; - } - } - } - return EXIT_SUCCESS; -} |