udpcast-20120424/0000755000175000017500000000000011745607103012353 5ustar alainalainudpcast-20120424/udp-receiver.h0000444000175000017500000000335111316710751015114 0ustar alainalain#ifndef UDP_RECEIVER_H #define UDP_RECEIVER_H #include "threads.h" #include "statistics.h" #include "console.h" #define S_UCAST socks[0] #define S_BCAST socks[1] #define S_MCAST_CTRL socks[2] #define S_MCAST_DATA socks[3] #define NR_CLIENT_SOCKS 4 struct client_config { int socks[NR_CLIENT_SOCKS]; struct sockaddr_in serverAddr; int clientNumber; int isStarted; pthread_t thread; int sender_is_newgen; console_t *console; }; struct fifo; #define spawnNetReceiver udpc_spawnNetReceiver #define writer udpc_writer #define openPipe udpcr_openPipe #define sendGo udpc_sendGo #define sendDisconnect udpc_sendDisconnect #define startReceiver udpc_startReceiver int spawnNetReceiver(struct fifo *fifo, struct client_config *client_config, struct net_config *net_config, receiver_stats_t stats); int writer(struct fifo *fifo, int fd); int openPipe(int disk, struct disk_config *disk_config, int *pipePid); int sendGo(struct client_config *); void sendDisconnect(int, struct client_config *); int startReceiver(int doWarn, struct disk_config *disk_config, struct net_config *net_config, struct stat_config *stat_config, const char *ifName); #define SSEND(x) SEND(client_config->S_UCAST, x, client_config->serverAddr) /** * Receiver will passively listen to sender. Works best if sender runs * in async mode */ #define FLAG_PASSIVE 0x0010 /** * Do not write file synchronously */ #define FLAG_NOSYNC 0x0040 /* * Don't ask for keyboard input on receiver end. */ #define FLAG_NOKBD 0x0080 /** * Do write file synchronously */ #define FLAG_SYNC 0x0100 /** * Streaming mode */ #define FLAG_STREAMING 0x200 /** * Ignore lost data */ #define FLAG_IGNORE_LOST_DATA 0x400 #endif udpcast-20120424/Kbuild0000444000175000017500000000321011066004453013475 0ustar alainalain# Makefile for busybox # # Copyright (C) 1999-2005 by Erik Andersen # # Licensed under the GPL v2, see the file LICENSE in this tarball. lib-y:= lib-$(CONFIG_UDPRECEIVER) += udp-receiver.o lib-$(CONFIG_UDPRECEIVER) += socklib.o lib-$(CONFIG_UDPRECEIVER) += udpcast.o lib-$(CONFIG_UDPRECEIVER) += receiver-diskio.o lib-$(CONFIG_UDPRECEIVER) += receivedata.o lib-$(CONFIG_UDPRECEIVER) += udpr-negotiate.o lib-$(CONFIG_UDPRECEIVER) += produconsum.o lib-$(CONFIG_UDPRECEIVER) += fifo.o lib-$(CONFIG_UDPRECEIVER) += log.o lib-$(CONFIG_UDPRECEIVER) += statistics.o lib-$(CONFIG_UDPRECEIVER) += fec.o lib-$(CONFIG_UDPRECEIVER) += udpc_version.o lib-$(CONFIG_UDPRECEIVER) += console.o lib-$(CONFIG_UDPRECEIVER) += process.o lib-$(CONFIG_UDPSENDER) += udp-sender.o lib-$(CONFIG_UDPSENDER) += socklib.o lib-$(CONFIG_UDPSENDER) += udpcast.o lib-$(CONFIG_UDPSENDER) += auto-rate.o lib-$(CONFIG_UDPSENDER) += rate-limit.o lib-$(CONFIG_UDPSENDER) += rateGovernor.o lib-$(CONFIG_UDPSENDER) += sender-diskio.o lib-$(CONFIG_UDPSENDER) += senddata.o lib-$(CONFIG_UDPSENDER) += udps-negotiate.o lib-$(CONFIG_UDPSENDER) += fifo.o lib-$(CONFIG_UDPSENDER) += produconsum.o lib-$(CONFIG_UDPSENDER) += participants.o lib-$(CONFIG_UDPSENDER) += log.o lib-$(CONFIG_UDPSENDER) += statistics.o lib-$(CONFIG_UDPSENDER) += fec.o lib-$(CONFIG_UDPSENDER) += udpc_version.o lib-$(CONFIG_UDPSENDER) += console.o lib-$(CONFIG_UDPSENDER) += process.o udpcast-20120424/rateGovernor.h0000444000175000017500000000422511065223717015202 0ustar alainalain#ifndef RATE_GOVERNOR_H #define RATE_GOVERNOR_H #ifdef HAVE_NETINET_IN_H #include #endif typedef struct rateGovernor_t { /** * Allocate and initialize new instance private data structure for this * rate governor */ void *(*rgInitialize)(void); /** * Set property. All properties are passed as strings, and should be * converted to the appropriate type by this rate governor * * The properties are set by specifying them on the udp-sender command line, * after the name of the module: * udp-sender -f myfile -g ipe.so:ip=224.1.2.3,port=5555 * This would load the rate governor ipe.so, and pass set its property ip * to 224.1.23 and its port to 5555. The port would actually passed as a * string, it's the responsibility of the module to convert that into an * integer as neded. */ void (*rgSetProp)(void *, const char *key, const char *value); /** * Called after all properties have been set * This method will be called after all properties have been set. * In this method, the rate governor knows its configuration, and may start * with * - opening sockets and other communication channels * - communicate with remote servers * - start background threads */ void (*rgEndConfig)(void *); /** * Wait enough time so we can transmit the requested number of bytes * This method is called by udpcast just before it transmits a packet. * The rate governor may uses this to wait until the ougoing channel is * ready to receive more data * Parameters: * p the rate governor private data * fd file descriptor to which data is going to be sent * ip ip address to which data is going to be sent * bytes bytes number of bytes which will be sent */ void (*rgWait)(void *, int fd, in_addr_t ip, long bytes); /** * Shut down the rate governor * Shutdown is called just before program exits. This can be used to * - signal remote servers that this sender is going away * - close filedescriptors/communications channels * - stop background threads * - deallocate data structures */ void (*rgShutdown)(void *); } rateGovernor_t; #endif udpcast-20120424/process.c0000444000175000017500000000343010540515265014172 0ustar alainalain#include "udpc_process.h" #include "log.h" #ifndef __MINGW32__ #include #include #include static void dupFd(int src, int target) { if(src != target) { close(target); if(dup2(src, target) < 0) udpc_fatal(1, "dup2 %d->%d: %s\n", src, target, strerror(errno)); close(src); } } int open2(int in, int out, char **arg, int closeFd) { int pid; switch( (pid=fork()) ) { case 0: /* child */ dupFd(in,0); dupFd(out,1); if(closeFd != -1) close(closeFd); execvp(arg[0], arg); udpc_fatal(1, "exec %s: %s\n", arg[0], strerror(errno)); case -1: /* fork error */ perror("fork"); return -1; default: /* Father: just return */ return pid; } } #else /* __MINGW32__ */ #include #include #include /* Thanks http://lists.gnu.org/archive/html/groff/2003-07/msg00107.html */ static int dupFd(int src, int target, int *savedFd) { *savedFd = -1; if(src != target) { if ((*savedFd = dup (target)) < 0) udpc_fatal(1, "dup parent_fd %d %s", target, strerror(errno)); if (dup2 (src, target) < 0) udpc_fatal(1, "dup2 child_fd %d %s", target, strerror(errno)); } return 0; } static int restoreFd(int src, int target) { if(src == -1 || src == target) /* Do nothing... */ return 0; if (dup2 (src, target) < 0) udpc_fatal(1, "restore child_fd %d %s", target, strerror(errno)); close(src); return 0; } int open2(int in, int out, char **arg, int closeFd) { int parent_in=-1; int parent_out=-1; int child; dupFd(in, 0, &parent_in); dupFd(out, 1, &parent_out); child = _spawnvp(P_NOWAIT, arg[0], (const char* const*)&arg[1]); restoreFd(parent_in, 0); restoreFd(parent_out, 1); return child; } #endif /* __MINGW32__ */ udpcast-20120424/udp-sender.txt0000444000175000017500000000221611110215114015140 0ustar alainalaindefine(`UDPSENDER',` ')dnl udpcast-20120424/console.c0000444000175000017500000001242211606254462014162 0ustar alainalain#include #include #include #include #include #include "console.h" #include "util.h" #include "udpcast.h" #ifndef __MINGW32__ #include #include struct console_t { int fd; /* Filedescriptor for console, or -1 if disabled */ struct termios oldtio; /* old settings, for restore */ int needClose; /* Does file descriptor need to be closed on reset? */ int needRestore; /* Is the file descriptor indeed a terminal, and needs * to be restored? */ }; console_t *prepareConsole(int fd) { struct termios newtio; int needClose=0; console_t *c; if(fd < 0) { fd = open("/dev/tty", O_RDWR); if(fd < 0) { fprintf(stderr, "Could not open keyboard: %s\n", strerror(errno)); return NULL; } needClose=1; } c = MALLOC(console_t); if(c == NULL) return c; c->fd = fd; c->needClose = needClose; c->needRestore = 0; if(tcgetattr(c->fd, &c->oldtio) >= 0) { newtio = c->oldtio; newtio.c_lflag &= ~ECHO; newtio.c_lflag &= ~ICANON; newtio.c_cc[VMIN] = 1; newtio.c_cc[VTIME] = 0; if(tcsetattr(c->fd, TCSAFLUSH, &newtio) < 0) perror("Set terminal to raw"); else c->needRestore = 1; } return c; } int selectWithConsole(console_t *con, int maxFd, fd_set *read_set, struct timeval *tv, int *keyPressed) { int ret; if(con) { int fd = con->fd; FD_SET(fd, read_set); if(fd >= maxFd) maxFd = fd+1; } ret = select(maxFd, read_set, NULL, NULL, tv); if(ret < 0) return -1; if(con && FD_ISSET(con->fd, read_set)) { *keyPressed = 1; } return ret; } void restoreConsole(console_t **cp, int doConsume) { console_t *c=*cp; int ch='\0'; int r UNUSED; if(c == NULL) return; /* If key pressed, consume it. If letter is q, quit */ if(doConsume) { r = read(c->fd, &ch, 1); } if(c->needRestore && tcsetattr(c->fd, TCSAFLUSH, &c->oldtio) < 0) { perror("Restore terminal settings"); } *cp = NULL; if(c->needClose) close(c->fd); free(c); if(ch == 'q') exit(1); } #else /* __MINGW32__ */ #include "log.h" struct console_t { HANDLE thread[2]; /* 0: console, 1: select */ int fd; int maxFd; fd_set read_set; struct timeval tv; struct timeval *tvp; int select_return; int keyPressed; char ch; }; static DWORD WINAPI waitForKeyPress(LPVOID lpParameter) { console_t *con = lpParameter; int n=read(con->fd, &con->ch, 1); if(n == 1) con->keyPressed=1; return 0; } static DWORD WINAPI waitForSelect(LPVOID lpParameter) { console_t *con = lpParameter; con->select_return = select(con->maxFd, &con->read_set, NULL, NULL, con->tvp); return 0; } console_t *prepareConsole(int fd) { console_t *con; if(fd < 0) { fd = open("CON", O_RDONLY); if(fd < 0) return NULL; } else { fd = dup(fd); /* dup console filedescriptor in order to avoid * race with pipe spawner... */ } con = MALLOC(console_t); if(con == NULL) return con; con->thread[0] = con->thread[1] = NULL; con->keyPressed=0; con->fd = fd; return con; } static HANDLE startThread(console_t *con, LPTHREAD_START_ROUTINE lpStartAddress) { /* Start thread ... * see http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/createthread.asp */ return CreateThread(NULL, /* lpThreadAttributes */ 0, /* dwStackSize */ lpStartAddress, con, /* lpParameter */ 0, /* dwCreationFlags */ NULL /* lpThreadId */); } int selectWithConsole(console_t *con, int maxFd, fd_set *read_set, struct timeval *tv, int *keyPressed) { int r; if(con == NULL) return select(maxFd, read_set, NULL, NULL, tv); if(!con->thread[0]) { con->thread[0]=startThread(con, waitForKeyPress); if(!con->thread[0]) udpc_fatal(1, "Could not start console listen thread"); } if(con->thread[1]) udpc_fatal(1, "Two select threads started at once!"); con->maxFd = maxFd; memcpy(&con->read_set, read_set, sizeof(*read_set)); if(tv) { memcpy(&con->tv, tv, sizeof(*tv)); con->tvp = &con->tv; } else { con->tvp=NULL; } /* Start select thread */ con->thread[1]=startThread(con, waitForSelect); if(!con->thread[1]) udpc_fatal(1, "Could not start select thread"); /* http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/waitformultipleobjects.asp */ switch( (r=WaitForMultipleObjects(2, con->thread, FALSE, INFINITE)) ) { case WAIT_OBJECT_0: *keyPressed=1; CloseHandle(con->thread[0]); CloseHandle(con->thread[1]); FD_ZERO(read_set); return 1; case WAIT_OBJECT_0+1: *keyPressed=0; CloseHandle(con->thread[1]); con->thread[1]=NULL; memcpy(read_set, &con->read_set, sizeof(*read_set)); return con->select_return; default: udpc_fatal(1, "Unexpected result %d for waitForMultipleObjects", r); return -1; } } void restoreConsole(console_t **cp, int doConsume) { console_t *c=*cp; /* If key pressed, consume it. If letter is q, quit */ if(doConsume) { if (c->keyPressed && c->ch == 'q') { exit(1); } } /* We do not free the console, because the select thread might * still be active... */ *cp = NULL; } #endif /* __MINGW32__ */ udpcast-20120424/rate-limit.c0000444000175000017500000000465611065120461014567 0ustar alainalain#include #include #include #include "socklib.h" #include "rate-limit.h" #include "util.h" #include "log.h" #include "rateGovernor.h" struct rate_limit { long long date; long long realDate; int bitrate; int queueSize; }; #define MILLION 1000000 #define LLMILLION ((long long)1000000) static unsigned long parseSpeed(const char *speedString) { char *eptr; unsigned long speed = strtoul(speedString, &eptr, 10); if(eptr && *eptr) { switch(*eptr) { case 'm': case 'M': speed *= 1000000; break; case 'k': case 'K': speed *= 1000; break; case '\0': break; default: udpc_fatal(1, "Unit %c unsupported\n", *eptr); } } return speed; } static long long getLongLongDate(void) { long long date; struct timeval tv; gettimeofday(&tv,0); date = (long long) tv.tv_sec; date *= LLMILLION; date += (long long) tv.tv_usec; return date; } static void *allocRateLimit(void) { struct rate_limit *rateLimit = MALLOC(struct rate_limit); if(rateLimit == NULL) return NULL; rateLimit->date = getLongLongDate(); rateLimit->bitrate = 0; rateLimit->queueSize = 0; return rateLimit; } static void setProp(void *data, const char *key, const char *bitrate) { struct rate_limit *rateLimit = (struct rate_limit *) data; if(rateLimit == NULL) return; if(!strcmp(MAX_BITRATE, key)) rateLimit->bitrate = parseSpeed(bitrate); } static void doRateLimit(void *data, int fd, in_addr_t ip, long size) { struct rate_limit *rateLimit = (struct rate_limit *) data; (void) fd; (void) ip; if(rateLimit) { long long now = getLongLongDate(); long long elapsed = now - rateLimit->date; long long bits = elapsed * ((long long)rateLimit->bitrate) / LLMILLION; int sleepTime; size += 28; /* IP header size */ if(bits >= rateLimit->queueSize * 8) { rateLimit->queueSize = size; rateLimit->date = now; return; } rateLimit->queueSize -= bits / 8; rateLimit->date += bits * LLMILLION / rateLimit->bitrate; rateLimit->realDate = now; sleepTime = rateLimit->queueSize * 8 * LLMILLION / rateLimit->bitrate; if(sleepTime > 40000 || rateLimit->queueSize >= 100000) { sleepTime -= 10000; sleepTime -= sleepTime % 10000; usleep(sleepTime); } rateLimit->queueSize += size; } } rateGovernor_t maxBitrate = { allocRateLimit, setProp, NULL, doRateLimit, NULL }; udpcast-20120424/fec.c0000444000175000017500000007236011603173117013256 0ustar alainalain/*#define PROFILE*/ /* * fec.c -- forward error correction based on Vandermonde matrices * 980624 * (C) 1997-98 Luigi Rizzo (luigi@iet.unipi.it) * (C) 2001 Alain Knaff (alain@knaff.lu) * * Portions derived from code by Phil Karn (karn@ka9q.ampr.org), * Robert Morelos-Zaragoza (robert@spectra.eng.hawaii.edu) and Hari * Thirumoorthy (harit@spectra.eng.hawaii.edu), Aug 1995 * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. */ #ifdef BB_FEATURE_UDPCAST_FEC /* * The following parameter defines how many bits are used for * field elements. The code supports any value from 2 to 16 * but fastest operation is achieved with 8 bit elements * This is the only parameter you may want to change. */ #define GF_BITS 8 /* code over GF(2**GF_BITS) - change to suit */ #include #include #include #include #include "fec.h" #include "socklib.h" /* * stuff used for testing purposes only */ #ifdef TEST #define DEB(x) #define DDB(x) x #define DEBUG 0 /* minimal debugging */ #include #define DIFF_T(a,b) \ (1+ 1000000*(a.tv_sec - b.tv_sec) + (a.tv_usec - b.tv_usec) ) #define TICK(t) \ {struct timeval x ; \ gettimeofday(&x, NULL) ; \ t = x.tv_usec + 1000000* (x.tv_sec & 0xff ) ; \ } #define TOCK(t) \ { u_long t1 ; TICK(t1) ; \ if (t1 < t) t = 256000000 + t1 - t ; \ else t = t1 - t ; \ if (t == 0) t = 1 ;} u_long ticks[10]; /* vars for timekeeping */ #else #define DEB(x) #define DDB(x) #define TICK(x) #define TOCK(x) #endif /* TEST */ /* * You should not need to change anything beyond this point. * The first part of the file implements linear algebra in GF. * * gf is the type used to store an element of the Galois Field. * Must constain at least GF_BITS bits. * * Note: unsigned char will work up to GF(256) but int seems to run * faster on the Pentium. We use int whenever have to deal with an * index, since they are generally faster. */ /* * AK: Udpcast only uses GF_BITS=8. Remove other possibilities */ #if (GF_BITS != 8) #error "GF_BITS must be 8" #endif typedef unsigned char gf; #define GF_SIZE ((1 << GF_BITS) - 1) /* powers of \alpha */ /* * Primitive polynomials - see Lin & Costello, Appendix A, * and Lee & Messerschmitt, p. 453. */ static char *allPp[] = { /* GF_BITS polynomial */ NULL, /* 0 no code */ NULL, /* 1 no code */ "111", /* 2 1+x+x^2 */ "1101", /* 3 1+x+x^3 */ "11001", /* 4 1+x+x^4 */ "101001", /* 5 1+x^2+x^5 */ "1100001", /* 6 1+x+x^6 */ "10010001", /* 7 1 + x^3 + x^7 */ "101110001", /* 8 1+x^2+x^3+x^4+x^8 */ "1000100001", /* 9 1+x^4+x^9 */ "10010000001", /* 10 1+x^3+x^10 */ "101000000001", /* 11 1+x^2+x^11 */ "1100101000001", /* 12 1+x+x^4+x^6+x^12 */ "11011000000001", /* 13 1+x+x^3+x^4+x^13 */ "110000100010001", /* 14 1+x+x^6+x^10+x^14 */ "1100000000000001", /* 15 1+x+x^15 */ "11010000000010001" /* 16 1+x+x^3+x^12+x^16 */ }; /* * To speed up computations, we have tables for logarithm, exponent * and inverse of a number. If GF_BITS <= 8, we use a table for * multiplication as well (it takes 64K, no big deal even on a PDA, * especially because it can be pre-initialized an put into a ROM!), * otherwhise we use a table of logarithms. * In any case the macro gf_mul(x,y) takes care of multiplications. */ static gf gf_exp[2*GF_SIZE]; /* index->poly form conversion table */ static int gf_log[GF_SIZE + 1]; /* Poly->index form conversion table */ static gf inverse[GF_SIZE+1]; /* inverse of field elem. */ /* inv[\alpha**i]=\alpha**(GF_SIZE-i-1) */ /* * modnn(x) computes x % GF_SIZE, where GF_SIZE is 2**GF_BITS - 1, * without a slow divide. */ static inline gf modnn(int x) { while (x >= GF_SIZE) { x -= GF_SIZE; x = (x >> GF_BITS) + (x & GF_SIZE); } return x; } #define SWAP(a,b,t) {t tmp; tmp=a; a=b; b=tmp;} /* * gf_mul(x,y) multiplies two numbers. If GF_BITS<=8, it is much * faster to use a multiplication table. * * USE_GF_MULC, GF_MULC0(c) and GF_ADDMULC(x) can be used when multiplying * many numbers by the same constant. In this case the first * call sets the constant, and others perform the multiplications. * A value related to the multiplication is held in a local variable * declared with USE_GF_MULC . See usage in addmul1(). */ static gf gf_mul_table[(GF_SIZE + 1)*(GF_SIZE + 1)] #ifdef WINDOWS __attribute__((aligned (16))) #else __attribute__((aligned (256))) #endif ; #define gf_mul(x,y) gf_mul_table[(x<<8)+y] #define USE_GF_MULC register gf * __gf_mulc_ #define GF_MULC0(c) __gf_mulc_ = &gf_mul_table[(c)<<8] #define GF_ADDMULC(dst, x) dst ^= __gf_mulc_[x] #define GF_MULC(dst, x) dst = __gf_mulc_[x] static void init_mul_table(void) { int i, j; for (i=0; i< GF_SIZE+1; i++) for (j=0; j< GF_SIZE+1; j++) gf_mul_table[(i<<8)+j] = gf_exp[modnn(gf_log[i] + gf_log[j]) ] ; for (j=0; j< GF_SIZE+1; j++) gf_mul_table[j] = gf_mul_table[j<<8] = 0; } /* * Generate GF(2**m) from the irreducible polynomial p(X) in p[0]..p[m] * Lookup tables: * index->polynomial form gf_exp[] contains j= \alpha^i; * polynomial form -> index form gf_log[ j = \alpha^i ] = i * \alpha=x is the primitive element of GF(2^m) * * For efficiency, gf_exp[] has size 2*GF_SIZE, so that a simple * multiplication of two numbers can be resolved without calling modnn */ /* * initialize the data structures used for computations in GF. */ static void generate_gf(void) { int i; gf mask; char *Pp = allPp[GF_BITS] ; mask = 1; /* x ** 0 = 1 */ gf_exp[GF_BITS] = 0; /* will be updated at the end of the 1st loop */ /* * first, generate the (polynomial representation of) powers of \alpha, * which are stored in gf_exp[i] = \alpha ** i . * At the same time build gf_log[gf_exp[i]] = i . * The first GF_BITS powers are simply bits shifted to the left. */ for (i = 0; i < GF_BITS; i++, mask <<= 1 ) { gf_exp[i] = mask; gf_log[gf_exp[i]] = i; /* * If Pp[i] == 1 then \alpha ** i occurs in poly-repr * gf_exp[GF_BITS] = \alpha ** GF_BITS */ if ( Pp[i] == '1' ) gf_exp[GF_BITS] ^= mask; } /* * now gf_exp[GF_BITS] = \alpha ** GF_BITS is complete, so can als * compute its inverse. */ gf_log[gf_exp[GF_BITS]] = GF_BITS; /* * Poly-repr of \alpha ** (i+1) is given by poly-repr of * \alpha ** i shifted left one-bit and accounting for any * \alpha ** GF_BITS term that may occur when poly-repr of * \alpha ** i is shifted. */ mask = 1 << (GF_BITS - 1 ) ; for (i = GF_BITS + 1; i < GF_SIZE; i++) { if (gf_exp[i - 1] >= mask) gf_exp[i] = gf_exp[GF_BITS] ^ ((gf_exp[i - 1] ^ mask) << 1); else gf_exp[i] = gf_exp[i - 1] << 1; gf_log[gf_exp[i]] = i; } /* * log(0) is not defined, so use a special value */ gf_log[0] = GF_SIZE ; /* set the extended gf_exp values for fast multiply */ for (i = 0 ; i < GF_SIZE ; i++) gf_exp[i + GF_SIZE] = gf_exp[i] ; /* * again special cases. 0 has no inverse. This used to * be initialized to GF_SIZE, but it should make no difference * since noone is supposed to read from here. */ inverse[0] = 0 ; inverse[1] = 1; for (i=2; i<=GF_SIZE; i++) inverse[i] = gf_exp[GF_SIZE-gf_log[i]]; } /* * Various linear algebra operations that i use often. */ /* * addmul() computes dst[] = dst[] + c * src[] * This is used often, so better optimize it! Currently the loop is * unrolled 16 times, a good value for 486 and pentium-class machines. * The case c=0 is also optimized, whereas c=1 is not. These * calls are unfrequent in my typical apps so I did not bother. * * Note that gcc on */ #if 0 #define addmul(dst, src, c, sz) \ if (c != 0) addmul1(dst, src, c, sz) #endif #define UNROLL 16 /* 1, 4, 8, 16 */ static void slow_addmul1(gf *dst1, gf *src1, gf c, int sz) { USE_GF_MULC ; register gf *dst = dst1, *src = src1 ; gf *lim = &dst[sz - UNROLL + 1] ; GF_MULC0(c) ; #if (UNROLL > 1) /* unrolling by 8/16 is quite effective on the pentium */ for (; dst < lim ; dst += UNROLL, src += UNROLL ) { GF_ADDMULC( dst[0] , src[0] ); GF_ADDMULC( dst[1] , src[1] ); GF_ADDMULC( dst[2] , src[2] ); GF_ADDMULC( dst[3] , src[3] ); #if (UNROLL > 4) GF_ADDMULC( dst[4] , src[4] ); GF_ADDMULC( dst[5] , src[5] ); GF_ADDMULC( dst[6] , src[6] ); GF_ADDMULC( dst[7] , src[7] ); #endif #if (UNROLL > 8) GF_ADDMULC( dst[8] , src[8] ); GF_ADDMULC( dst[9] , src[9] ); GF_ADDMULC( dst[10] , src[10] ); GF_ADDMULC( dst[11] , src[11] ); GF_ADDMULC( dst[12] , src[12] ); GF_ADDMULC( dst[13] , src[13] ); GF_ADDMULC( dst[14] , src[14] ); GF_ADDMULC( dst[15] , src[15] ); #endif } #endif lim += UNROLL - 1 ; for (; dst < lim; dst++, src++ ) /* final components */ GF_ADDMULC( *dst , *src ); } #if defined i386 && defined USE_ASSEMBLER #define LOOPSIZE 8 static void addmul1(gf *dst1, gf *src1, gf c, int sz) { USE_GF_MULC ; GF_MULC0(c) ; if(((unsigned long)dst1 % LOOPSIZE) || ((unsigned long)src1 % LOOPSIZE) || (sz % LOOPSIZE)) { slow_addmul1(dst1, src1, c, sz); return; } asm volatile("xorl %%eax,%%eax;\n" " xorl %%edx,%%edx;\n" ".align 32;\n" "1:" " addl $8, %%edi;\n" " movb (%%esi), %%al;\n" " movb 4(%%esi), %%dl;\n" " movb (%%ebx,%%eax), %%al;\n" " movb (%%ebx,%%edx), %%dl;\n" " xorb %%al, (%%edi);\n" " xorb %%dl, 4(%%edi);\n" " movb 1(%%esi), %%al;\n" " movb 5(%%esi), %%dl;\n" " movb (%%ebx,%%eax), %%al;\n" " movb (%%ebx,%%edx), %%dl;\n" " xorb %%al, 1(%%edi);\n" " xorb %%dl, 5(%%edi);\n" " movb 2(%%esi), %%al;\n" " movb 6(%%esi), %%dl;\n" " movb (%%ebx,%%eax), %%al;\n" " movb (%%ebx,%%edx), %%dl;\n" " xorb %%al, 2(%%edi);\n" " xorb %%dl, 6(%%edi);\n" " movb 3(%%esi), %%al;\n" " movb 7(%%esi), %%dl;\n" " addl $8, %%esi;\n" " movb (%%ebx,%%eax), %%al;\n" " movb (%%ebx,%%edx), %%dl;\n" " xorb %%al, 3(%%edi);\n" " xorb %%dl, 7(%%edi);\n" " cmpl %%ecx, %%esi;\n" " jb 1b;" : : "b" (__gf_mulc_), "D" (dst1-8), "S" (src1), "c" (sz+src1) : "memory", "eax", "edx" ); } #else # define addmul1 slow_addmul1 #endif static void addmul(gf *dst, gf *src, gf c, int sz) { // fprintf(stderr, "Dst=%p Src=%p, gf=%02x sz=%d\n", dst, src, c, sz); if (c != 0) addmul1(dst, src, c, sz); } /* * mul() computes dst[] = c * src[] * This is used often, so better optimize it! Currently the loop is * unrolled 16 times, a good value for 486 and pentium-class machines. * The case c=0 is also optimized, whereas c=1 is not. These * calls are unfrequent in my typical apps so I did not bother. * * Note that gcc on */ #if 0 #define mul(dst, src, c, sz) \ do { if (c != 0) mul1(dst, src, c, sz); else memset(dst, 0, sz); } while(0) #endif #define UNROLL 16 /* 1, 4, 8, 16 */ static void slow_mul1(gf *dst1, gf *src1, gf c, int sz) { USE_GF_MULC ; register gf *dst = dst1, *src = src1 ; gf *lim = &dst[sz - UNROLL + 1] ; GF_MULC0(c) ; #if (UNROLL > 1) /* unrolling by 8/16 is quite effective on the pentium */ for (; dst < lim ; dst += UNROLL, src += UNROLL ) { GF_MULC( dst[0] , src[0] ); GF_MULC( dst[1] , src[1] ); GF_MULC( dst[2] , src[2] ); GF_MULC( dst[3] , src[3] ); #if (UNROLL > 4) GF_MULC( dst[4] , src[4] ); GF_MULC( dst[5] , src[5] ); GF_MULC( dst[6] , src[6] ); GF_MULC( dst[7] , src[7] ); #endif #if (UNROLL > 8) GF_MULC( dst[8] , src[8] ); GF_MULC( dst[9] , src[9] ); GF_MULC( dst[10] , src[10] ); GF_MULC( dst[11] , src[11] ); GF_MULC( dst[12] , src[12] ); GF_MULC( dst[13] , src[13] ); GF_MULC( dst[14] , src[14] ); GF_MULC( dst[15] , src[15] ); #endif } #endif lim += UNROLL - 1 ; for (; dst < lim; dst++, src++ ) /* final components */ GF_MULC( *dst , *src ); } #if defined i386 && defined USE_ASSEMBLER static void mul1(gf *dst1, gf *src1, gf c, int sz) { USE_GF_MULC ; GF_MULC0(c) ; if(((unsigned long)dst1 % LOOPSIZE) || ((unsigned long)src1 % LOOPSIZE) || (sz % LOOPSIZE)) { slow_mul1(dst1, src1, c, sz); return; } asm volatile("pushl %%eax;\n" "pushl %%edx;\n" "xorl %%eax,%%eax;\n" " xorl %%edx,%%edx;\n" "1:" " addl $8, %%edi;\n" " movb (%%esi), %%al;\n" " movb 4(%%esi), %%dl;\n" " movb (%%ebx,%%eax), %%al;\n" " movb (%%ebx,%%edx), %%dl;\n" " movb %%al, (%%edi);\n" " movb %%dl, 4(%%edi);\n" " movb 1(%%esi), %%al;\n" " movb 5(%%esi), %%dl;\n" " movb (%%ebx,%%eax), %%al;\n" " movb (%%ebx,%%edx), %%dl;\n" " movb %%al, 1(%%edi);\n" " movb %%dl, 5(%%edi);\n" " movb 2(%%esi), %%al;\n" " movb 6(%%esi), %%dl;\n" " movb (%%ebx,%%eax), %%al;\n" " movb (%%ebx,%%edx), %%dl;\n" " movb %%al, 2(%%edi);\n" " movb %%dl, 6(%%edi);\n" " movb 3(%%esi), %%al;\n" " movb 7(%%esi), %%dl;\n" " addl $8, %%esi;\n" " movb (%%ebx,%%eax), %%al;\n" " movb (%%ebx,%%edx), %%dl;\n" " movb %%al, 3(%%edi);\n" " movb %%dl, 7(%%edi);\n" " cmpl %%ecx, %%esi;\n" " jb 1b;\n" " popl %%edx;\n" " popl %%eax;" : : "b" (__gf_mulc_), "D" (dst1-8), "S" (src1), "c" (sz+src1) : "memory", "eax", "edx" ); } #else # define mul1 slow_mul1 #endif static inline void mul(gf *dst, gf *src, gf c, int sz) { /*fprintf(stderr, "%p = %02x * %p\n", dst, c, src);*/ if (c != 0) mul1(dst, src, c, sz); else memset(dst, 0, sz); } /* * invert_mat() takes a matrix and produces its inverse * k is the size of the matrix. * (Gauss-Jordan, adapted from Numerical Recipes in C) * Return non-zero if singular. */ DEB( int pivloops=0; int pivswaps=0 ; /* diagnostic */) static int invert_mat(gf *src, int k) { gf c, *p ; int irow, icol, row, col, i, ix ; int error = 1 ; int indxc[k]; int indxr[k]; int ipiv[k]; gf id_row[k]; memset(id_row, 0, k*sizeof(gf)); DEB( pivloops=0; pivswaps=0 ; /* diagnostic */ ) /* * ipiv marks elements already used as pivots. */ for (i = 0; i < k ; i++) ipiv[i] = 0 ; for (col = 0; col < k ; col++) { gf *pivot_row ; /* * Zeroing column 'col', look for a non-zero element. * First try on the diagonal, if it fails, look elsewhere. */ irow = icol = -1 ; if (ipiv[col] != 1 && src[col*k + col] != 0) { irow = col ; icol = col ; goto found_piv ; } for (row = 0 ; row < k ; row++) { if (ipiv[row] != 1) { for (ix = 0 ; ix < k ; ix++) { DEB( pivloops++ ; ) if (ipiv[ix] == 0) { if (src[row*k + ix] != 0) { irow = row ; icol = ix ; goto found_piv ; } } else if (ipiv[ix] > 1) { fprintf(stderr, "singular matrix\n"); goto fail ; } } } } if (icol == -1) { fprintf(stderr, "XXX pivot not found!\n"); goto fail ; } found_piv: ++(ipiv[icol]) ; /* * swap rows irow and icol, so afterwards the diagonal * element will be correct. Rarely done, not worth * optimizing. */ if (irow != icol) { for (ix = 0 ; ix < k ; ix++ ) { SWAP( src[irow*k + ix], src[icol*k + ix], gf) ; } } indxr[col] = irow ; indxc[col] = icol ; pivot_row = &src[icol*k] ; c = pivot_row[icol] ; if (c == 0) { fprintf(stderr, "singular matrix 2\n"); goto fail ; } if (c != 1 ) { /* otherwhise this is a NOP */ /* * this is done often , but optimizing is not so * fruitful, at least in the obvious ways (unrolling) */ DEB( pivswaps++ ; ) c = inverse[ c ] ; pivot_row[icol] = 1 ; for (ix = 0 ; ix < k ; ix++ ) pivot_row[ix] = gf_mul(c, pivot_row[ix] ); } /* * from all rows, remove multiples of the selected row * to zero the relevant entry (in fact, the entry is not zero * because we know it must be zero). * (Here, if we know that the pivot_row is the identity, * we can optimize the addmul). */ id_row[icol] = 1; if (memcmp(pivot_row, id_row, k*sizeof(gf)) != 0) { for (p = src, ix = 0 ; ix < k ; ix++, p += k ) { if (ix != icol) { c = p[icol] ; p[icol] = 0 ; addmul(p, pivot_row, c, k ); } } } id_row[icol] = 0; } /* done all columns */ for (col = k-1 ; col >= 0 ; col-- ) { if (indxr[col] <0 || indxr[col] >= k) fprintf(stderr, "AARGH, indxr[col] %d\n", indxr[col]); else if (indxc[col] <0 || indxc[col] >= k) fprintf(stderr, "AARGH, indxc[col] %d\n", indxc[col]); else if (indxr[col] != indxc[col] ) { for (row = 0 ; row < k ; row++ ) { SWAP( src[row*k + indxr[col]], src[row*k + indxc[col]], gf) ; } } } error = 0 ; fail: return error ; } static int fec_initialized = 0 ; void fec_init(void) { TICK(ticks[0]); generate_gf(); TOCK(ticks[0]); DDB(fprintf(stderr, "generate_gf took %ldus\n", ticks[0]);) TICK(ticks[0]); init_mul_table(); TOCK(ticks[0]); DDB(fprintf(stderr, "init_mul_table took %ldus\n", ticks[0]);) fec_initialized = 1 ; } /** * Simplified re-implementation of Fec-Bourbon * * Following changes have been made: * 1. Avoid unnecessary copying of block data. * 2. Avoid expliciting matrixes, if we are only going to use one row * anyways * 3. Pick coefficients of Vandermonde matrix in such a way as to get * a "nicer" systematic matrix, such as for instance the following: * 1 0 0 0 0 0 0 0 * 0 1 0 0 0 0 0 0 * 0 0 1 0 0 0 0 0 * 0 0 0 1 0 0 0 0 * 0 0 0 0 1 0 0 0 * 0 0 0 0 0 1 0 0 * 0 0 0 0 0 0 1 0 * 0 0 0 0 0 0 0 1 * a b c d e f g h * b a d c f e h g * c d a b g h e f * d c b a h g f e * * This makes it easyer on processor cache, because we keep on reusing the * same small part of the multiplication table. * The trick to obtain this is to use k=128 and n=256. Use x=col for * top matrix (rather than exp(col-1) as the original did). This makes * the "inverting" polynom to be the following (coefficients of col * col of inverse of top Vandermonde matrix) * * _____ * | | * P = K | | (x - i) * col col | | * 0 < i < 128 && * i != col * * K_col must be chosen such that P_col(col) = 1, thus * * 1 * --------------- * K = _____ * col | | * | | (col - i) * | | * 0 < i < 128 && * i != col * * For obvious reasons, all (col-i)'s are different foreach i (because * col constant). Moreoveover, none has the high bit set (because both * col and i have high bit unset and +/- is really a xor). Moreover * 0 is not among them (because i != col). This means that we calculate * the product of all values for 1 to 0x7f, and we have eliminated * dependancy on col. K_col can be written just k. * * Which make P_col resolves to: * _____ * | | * P = K | | (x - i) * col | | * 0 < i < 128 * ------------------- * (x-col) * * When evaluating this for any x > 0x80, the following thing happens * to the numerator: all (x-i) are different for i, and have high bit * set. Thus, the set of top factors are all values from 0x80 to 0xff, * and the numerator becomes independant from x (as long as x & 0x80 = 0) * Thus, P_col(x) = L / (x-col) * In the systematic matrix value on [row,col] is P_col(row) = L/(row-col) * To simplify we multiply each bottom row by 1/L (which is a simple * scaling operation, and should not affect invertibility of any partial * matrix contained therein), and we get S[row,col] = 1/(row-col) * Benefits of all this: * - no complicated encoding matrix to compute (it's just the inverse * table!) * - cache efficiency when multiplying blocks, because we get to * reuse the same coefficients. Probability of mult table already in * cache increases. * Downside: * - less flexibility: we can for instance not do 240/200, because * 200 is more than 128, and using this technique we unfortunately * limited number of data blocks to 128 instead of 256 as would be * possible otherwise */ /* We do the matrix multiplication columns by column, instead of the * usual row-by-row, in order to capitalize on the cache freshness of * each data block . The data block only needs to be fetched once, and * can be used to be addmull'ed into all FEC blocks at once. No need * to worry about evicting FEC blocks from the cache: those are so * few (typically, 4 or 8) that they will fit easily in the cache (even * in the L2 cache...) */ void fec_encode(unsigned int blockSize, unsigned char **data_blocks, unsigned int nrDataBlocks, unsigned char **fec_blocks, unsigned int nrFecBlocks) { unsigned int blockNo; /* loop for block counter */ unsigned int row, col; assert(fec_initialized); assert(nrDataBlocks <= 128); assert(nrFecBlocks <= 128); if(!nrDataBlocks) return; for(row=0; row < nrFecBlocks; row++) mul(fec_blocks[row], data_blocks[0], inverse[128 ^ row], blockSize); for(col=129, blockNo=1; blockNo < nrDataBlocks; col++, blockNo ++) { for(row=0; row < nrFecBlocks; row++) addmul(fec_blocks[row], data_blocks[blockNo], inverse[row ^ col], blockSize); } } /** * Reduce the system by substracting all received data blocks from FEC blocks * This will allow to resolve the system by inverting a much smaller matrix * (with size being number of blocks lost, rather than number of data blocks * + fec) */ static inline void reduce(unsigned int blockSize, unsigned char **data_blocks, unsigned int nr_data_blocks, unsigned char **fec_blocks, unsigned int *fec_block_nos, unsigned int *erased_blocks, unsigned short nr_fec_blocks) { int erasedIdx=0; unsigned int col; /* First we reduce the code vector by substracting all known elements * (non-erased data packets) */ for(col=0; col\n" " http://udpcast.linux.lu/\n" "\n" "the FEC code is covered by the following license:\n" "fec.c -- forward error correction based on Vandermonde matrices\n" "980624\n" "(C) 1997-98 Luigi Rizzo (luigi@iet.unipi.it)\n" "(C) 2001 Alain Knaff (alain@knaff.lu)\n" "\n" "Portions derived from code by Phil Karn (karn@ka9q.ampr.org),\n" "Robert Morelos-Zaragoza (robert@spectra.eng.hawaii.edu) and Hari\n" "Thirumoorthy (harit@spectra.eng.hawaii.edu), Aug 1995\n" "\n" "Redistribution and use in source and binary forms, with or without\n" "modification, are permitted provided that the following conditions\n" "are met:\n" "\n" "1. Redistributions of source code must retain the above copyright\n" " notice, this list of conditions and the following disclaimer.\n" "2. Redistributions in binary form must reproduce the above\n" " copyright notice, this list of conditions and the following\n" " disclaimer in the documentation and/or other materials\n" " provided with the distribution.\n" "\n" "THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND\n" "ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,\n" "THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A\n" "PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS\n" "BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,\n" "OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n" "PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\n" "OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n" "THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR\n" "TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n" "OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY\n" "OF SUCH DAMAGE.\n" ); exit(0); } #endif udpcast-20120424/Makefile.flags0000444000175000017500000000015411110055006015065 0ustar alainalainifeq ($(CONFIG_UDPSENDER),y) LDLIBS += pthread endif ifeq ($(CONFIG_UDPRECEIVER),y) LDLIBS += pthread endif udpcast-20120424/sender-diskio.c0000444000175000017500000000364711064536466015276 0ustar alainalain#include #include #include #include #include #include "log.h" #include "fifo.h" #include "udp-sender.h" #include "udpcast.h" #include "udpc_process.h" #define BLOCKSIZE 4096 #ifdef O_BINARY #include #define HAVE_O_BINARY #endif #ifndef O_BINARY # define O_BINARY 0 #endif int openFile(struct disk_config *config) { if(config->fileName != NULL) { int in = open(config->fileName, O_RDONLY | O_BINARY, 0); if (in < 0) { #ifdef NO_BB #ifndef errno extern int errno; #endif #endif udpc_fatal(1, "Could not open file %s: %s\n", config->fileName, strerror(errno)); } return in; } else { #ifdef __MINGW32__ setmode(0, O_BINARY); #endif return 0; } } int openPipe(struct disk_config *config, int in, int *pidp) { /** * Open the pipe */ *pidp=0; if(config->pipeName != NULL) { /* pipe */ char *arg[256]; int filedes[2]; udpc_parseCommand(config->pipeName, arg); if(pipe(filedes) < 0) { perror("pipe"); exit(1); } #ifdef HAVE_O_BINARY setmode(filedes[0], O_BINARY); setmode(filedes[1], O_BINARY); #endif *pidp=open2(in, filedes[1], arg, filedes[0]); close(filedes[1]); in = filedes[0]; } return in; } /** * This file is reponsible for reading the data to be sent from disk */ int localReader(struct fifo *fifo, int in) { while(1) { int pos = pc_getConsumerPosition(fifo->freeMemQueue); int bytes = pc_consumeContiguousMinAmount(fifo->freeMemQueue, BLOCKSIZE); if(bytes > (pos + bytes) % BLOCKSIZE) bytes -= (pos + bytes) % BLOCKSIZE; if(bytes == 0) /* net writer exited? */ break; bytes = read(in, fifo->dataBuffer + pos, bytes); if(bytes < 0) { perror("read"); exit(1); } if (bytes == 0) { /* the end */ pc_produceEnd(fifo->data); break; } else { pc_consumed(fifo->freeMemQueue, bytes); pc_produce(fifo->data, bytes); } } return 0; } udpcast-20120424/configure.in0000444000175000017500000001512211606101754014660 0ustar alainalaindnl Process this file with autoconf to produce a configure script. AC_INIT(socklib.c) AC_CONFIG_HEADER(config.h) dnl Checks for compiler AC_PROG_CC AC_PROG_GCC_TRADITIONAL AC_PROG_INSTALL dnl Check for Systems AC_CANONICAL_SYSTEM AC_C_CONST AC_C_INLINE dnl Checks for libraries. AC_CHECK_LIB(pthread, pthread_create) AC_CHECK_LIB(dl, dlsym) dnl Checks for header files. AC_HEADER_STDC AC_HEADER_SYS_WAIT AC_CHECK_HEADERS(fcntl.h limits.h sys/ioctl.h sys/time.h arpa/inet.h netdb.h \ sys/select.h sys/sockio.h sys/socket.h sys/param.h memory.h malloc.h signal.h \ net/if.h netinet/in.h winsock2.h sys/uio.h getopt.h dlfcn.h string.h) AC_CHECK_HEADERS(termios.h sys/termios.h, [break]) dnl Check for structures AC_CHECK_MEMBERS([struct ip_mreqn.imr_ifindex],[],[],[#ifdef HAVE_NETINET_IN_H #include #endif]) dnl Check for types AC_CHECK_TYPES(in_addr_t,[],[],[#ifdef HAVE_ARPA_INET_H #include #endif]) dnl dnl Check to see if llseek() is declared in unistd.h. On some libc's dnl it is, and on others it isn't..... Thank you glibc developers.... dnl dnl Warning! Use of --enable-gcc-wall may throw off this test. dnl dnl AC_MSG_CHECKING(whether llseek declared in unistd.h) AC_CACHE_VAL(mtools_cv_have_llseek_prototype, AC_TRY_COMPILE( [#include ], [extern int llseek(int);], [mtools_cv_have_llseek_prototype=no], [mtools_cv_have_llseek_prototype=yes])) AC_MSG_RESULT($mtools_cv_have_llseek_prototype) if test "$mtools_cv_have_llseek_prototype" = yes; then AC_DEFINE([HAVE_LLSEEK_PROTOTYPE],1,[Define when you have an LLSEEK prototype]) fi AC_MSG_CHECKING(whether lseek64 declared in unistd.h) AC_CACHE_VAL(mtools_cv_have_lseek64_prototype, AC_TRY_COMPILE( [ #include "sysincludes.h" #include ], [extern int lseek64(int);], [mtools_cv_have_lseek64_prototype=no], [mtools_cv_have_lseek64_prototype=yes])) AC_MSG_RESULT($mtools_cv_have_lseek64_prototype) if test "$mtools_cv_have_lseek64_prototype" = yes; then AC_DEFINE([HAVE_LSEEK64_PROTOTYPE],1,[Define when you have an LSEEK64 prototype]) fi AC_CHECK_FUNCS(htons kill daemon) dnl Checks for typedefs, structures, and compiler characteristics. AC_C_CONST AC_C_INLINE AC_TYPE_SIZE_T AC_HEADER_TIME AC_STRUCT_TM dnl Checks for library functions. AC_TYPE_SIGNAL AC_CHECK_FUNCS(atexit on_exit tcsetattr lseek64 snprintf inet_pton inet_aton getopt_long dlsym) dnl dnl Check for 64-bit off_t dnl AC_DEFUN(SFS_CHECK_OFF_T_64, [AC_CACHE_CHECK(for 64-bit off_t, sfs_cv_off_t_64, AC_TRY_COMPILE([ #include #include ],[ switch (0) case 0: case (sizeof (off_t) <= 4):; ], sfs_cv_off_t_64=no, sfs_cv_off_t_64=yes)) if test $sfs_cv_off_t_64 = yes; then AC_DEFINE([HAVE_OFF_T_64],1,[Define when the system has a 64 bit off_t type]) fi]) dnl ICE_CC_LOFF_T dnl ------------- dnl dnl If the CC compiler supports `loff_t' type, define `HAVE_LOFF_T'. dnl AC_DEFUN(ICE_CC_LOFF_T, [ AC_MSG_CHECKING(whether ${CC} supports loff_t type) AC_CACHE_VAL(ice_cv_have_loff_t, [ AC_TRY_COMPILE([#include ],[loff_t a;], ice_cv_have_loff_t=yes, ice_cv_have_loff_t=no) ]) AC_MSG_RESULT($ice_cv_have_loff_t) if test "$ice_cv_have_loff_t" = yes; then AC_DEFINE([HAVE_LOFF_T],1,[Define when the compiler supports LOFF_T type]) fi ])dnl dnl ICE_CC_OFFSET_T dnl ------------- dnl dnl If the CC compiler supports `offset_t' type, define `HAVE_OFFSET_T'. dnl AC_DEFUN(ICE_CC_OFFSET_T, [ AC_MSG_CHECKING(whether ${CC} supports offset_t type) AC_CACHE_VAL(ice_cv_have_offset_t, [ AC_TRY_COMPILE([#include ],[offset_t a;], ice_cv_have_offset_t=yes, ice_cv_have_offset_t=no) ]) AC_MSG_RESULT($ice_cv_have_offset_t) if test "$ice_cv_have_offset_t" = yes; then AC_DEFINE([HAVE_OFFSET_T],1,[Define when the compiler supports OFFSET_T type]) fi ])dnl dnl ICE_CC_LONG_LONG dnl ------------- dnl dnl If the CC compiler supports `long long' type, define `HAVE_LONG_LONG'. dnl AC_DEFUN(ICE_CC_LONG_LONG, [ AC_MSG_CHECKING(whether ${CC} supports long long type) AC_CACHE_VAL(ice_cv_have_long_long, [ AC_TRY_COMPILE(,[long long a;], ice_cv_have_long_long=yes, ice_cv_have_long_long=no) ]) AC_MSG_RESULT($ice_cv_have_long_long) if test "$ice_cv_have_long_long" = yes; then AC_DEFINE([HAVE_LONG_LONG],1,[Define when the compiler supports LONG_LONG type]) fi ])dnl SFS_CHECK_OFF_T_64 ICE_CC_LOFF_T ICE_CC_OFFSET_T ICE_CC_LONG_LONG [ host_os0=`echo $host_os | sed 's/-/_/g'` host_os1=`echo $host_os0 | sed 's/\./_/g'` host_os2=`echo $host_os0 | sed 's/^\([^.]*\)\..*$/\1/g'` host_os3=`echo $host_os2 | sed 's/^\([^0-9]*\)[0-9]*$/\1/g'` host_cpu1=`echo $host_cpu | sed 's/\./_/g'` host_vendor1=`echo $host_vendor | sed 's/\./_/g'` HOST_ID="-DCPU_$host_cpu1 -DVENDOR_$host_vendor1 -DOS_$host_os1" if [ $host_os1 != $host_os2 ] ; then HOST_ID="$HOST_ID -DOS_$host_os2" fi if [ $host_os1 != $host_os3 ] && [ $host_os2 != $host_os3 ] ; then HOST_ID="$HOST_ID -DOS_$host_os3" fi my_host_os=`echo $host_os1 $host_os2 $host_os3 | sort -u` objs=`echo $srcdir/*.c | sed 's/\.c$/.o/' ` if [ "X$GCC" = "Xyes" ] ; then Wall=-Wall if [ "$host_os3" = sunos ] ; then Wall="" fi if [ "$host_os3" = solaris ] ; then CFLAGS="$CFLAGS -D_XOPEN_SOURCE -D_XOPEN_SOURCE_EXTENDED=1 -D__EXTENSIONS__" LIBS="$LIBS -lnsl -lsocket" Wall="" fi if [ "$host_os3" = ultrix ] ; then Wall="" fi if [ "$host_os3" = linux ] ; then CFLAGS="$CFLAGS -fno-strength-reduce" fi if [ "$host_os3" = aux ] ; then CFLAGS="$CFLAGS -ZP" MACHDEPLIBS="-lposix -UTIL" fi case "${host}" in arm*-*-linux) CFLAGS="$CFLAGS -mstructure-size-boundary=8";; esac CFLAGS="$CFLAGS $Wall" else if [ $host_os3 = hpux ] ; then CPPFLAGS="$CPPFLAGS -Ae" fi if [ $host_os3 = xenix ] ; then CFLAGS="$CFLAGS -M2e" fi fi if [ $host_os3 = hpux ] ; then LDFLAGS="$LDFLAGS -z" fi if [ $host_vendor = linux ] ; then LDFLAGS="$LDFLAGS -z" fi if [ $host_os3 = xenix ] ; then LDFLAGS="$LDFLAGS -M2e -i -f 5000" fi if [ $host_os2 = sysv4 ] ; then SHLIB="-lc -L/usr/ucblib -lucb" else SHLIB="" fi if [ $host_os3 = isc ] ; then CFLAGS="$CFLAGS -D_SYSV3" SHLIB="-lc_s" fi if [ $host_os3 = nextstep ] ; then CFLAGS="$CFLAGS -DBSD" SHLIB="" fi if [ $host_os3 = mingw -o $host_os3 = mingw32msvc ] ; then LIBS="$LIBS -lws2_32 -liphlpapi" EXESUFFIX=".exe" fi if [ -d /usr/5lib ] ; then extralibdir=-L/usr/5lib fi ] AC_SUBST(extraincludedir) AC_SUBST(extralibdir) AC_SUBST(MACHDEPLIBS) AC_SUBST(SHLIB) AC_SUBST(LIBS) AC_SUBST(EXESUFFIX) AC_SUBST(host_cpu) AC_SUBST(HOST_ID) AC_SUBST(CFLAGS) AC_SUBST(CPPFLAGS) AC_SUBST(LDFLAGS) AC_OUTPUT(Makefile) udpcast-20120424/fec-test.c0000444000175000017500000003070110015753501014221 0ustar alainalain#include #include #include #include #include #include #include #include "fec.h" #include "fec.c" #if 0 static void mul2(gf *dst1, gf *src1, gf c, int sz) { USE_GF_MULC ; GF_MULC0(c) ; if(((unsigned long)dst1 % 8) || ((unsigned long)src1 % 8) || (sz % 8)) { slow_mul1(dst1, src1, c, sz); return; } asm volatile(" xorl %%eax,%%eax;\n" " xorl %%edx,%%edx;\n" "1: " " addl $8, %%edi;\n" " movb (%%esi), %%al;\n" " movb 4(%%esi), %%dl;\n" " movb (%%ebx,%%eax), %%al;\n" " movb (%%ebx,%%edx), %%dl;\n" " movb %%al, (%%edi);\n" " movb %%dl, 4(%%edi);\n" " movb 1(%%esi), %%al;\n" " movb 5(%%esi), %%dl;\n" " movb (%%ebx,%%eax), %%al;\n" " movb (%%ebx,%%edx), %%dl;\n" " movb %%al, 1(%%edi);\n" " movb %%dl, 5(%%edi);\n" " movb 2(%%esi), %%al;\n" " movb 6(%%esi), %%dl;\n" " movb (%%ebx,%%eax), %%al;\n" " movb (%%ebx,%%edx), %%dl;\n" " movb %%al, 2(%%edi);\n" " movb %%dl, 6(%%edi);\n" " movb 3(%%esi), %%al;\n" " movb 7(%%esi), %%dl;\n" " addl $8, %%esi;\n" " movb (%%ebx,%%eax), %%al;\n" " movb (%%ebx,%%edx), %%dl;\n" " movb %%al, 3(%%edi);\n" " movb %%dl, 7(%%edi);\n" " cmpl %%ecx, %%esi;\n" " jb 1b;\n" : : "b" (__gf_mulc_), "D" (dst1-8), "S" (src1), "c" (sz+src1) : "memory", "eax", "edx" ); } #endif static inline long long rdtsc(void) { unsigned long low, hi; asm volatile ("rdtsc" : "=d" (hi), "=a" (low)); return ( (((long long)hi) << 32) | ((long long) low)); } static inline void prefetch0(char *ptr) { asm volatile ("prefetcht0 (%%eax)" : : "a" (ptr)); } static inline void prefetch1(char *ptr) { asm volatile ("prefetcht1 (%%eax)" : : "a" (ptr)); } static inline void prefetch2(char *ptr) { asm volatile ("prefetcht2 (%%eax)" : : "a" (ptr)); } static inline void prefetchnta(char *ptr) { asm volatile ("prefetchnta (%%eax)" : : "a" (ptr)); } unsigned long long globalstart; int timeptr=0; unsigned long long times[1024]; #if 0 #define MYTICK() 1 #define MYTOCK() 1 #else #define MYTICK() globalstart=rdtsc() #define MYTOCK() times[timeptr++]=rdtsc()-globalstart #endif #if 0 int main(int argc, char **argv) { int width=atoi(argv[1]); fec_code_t fec = fec_new(width, width*2); fast_fec_new(width); if(width > 16) width=16; printf("w=%d\n", width); fec_print(fec, width); return 0; } #endif #define SIZE (8192) /* static unsigned char highbit_test[] __attribute__ ((aligned (16))) = { 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 }; static unsigned char multable[16] __attribute__ ((aligned (16))); */ //static unsigned char test_result[16] __attribute__ ((aligned (16))); static void emms(void) { asm volatile("emms"); } #define BITBUFSIZE 512 static unsigned char exp8[(255+8)*16] __attribute__ ((aligned (4096))); static void initFastTable(void) { int i; unsigned char *ptr=exp8; for(i=0; i< (255+8); i++) { int j; for(j=0; j<8; j++, ptr++) *ptr = gf_exp[(254+8-i)%255]; } } static unsigned char dst2[SIZE] __attribute__ ((aligned (4096))); static void mmx_addmul1(gf *dst1, gf *src1, gf c, int sz) { /* Register allocation: * mm0: source * mm1: target * eax: high-bit bitmask * ebx: table base-pointer */ #if 0 fprintf(stderr, "src=%p dst=%p %p %d\n", src1, dst1, mul_results, mul_results[64]); #endif #if 1 /* first initialize bitmap */ MYTICK(); asm volatile( "1:" " movq (%%esi),%%mm2;\n" " movq (%%edi),%%mm1;\n" " movq %%mm2,%%mm3;\n" " pcmpgtb %%mm0,%%mm3;\n" " pandn (%%ebx),%%mm3;\n" " psllw $1,%%mm2;\n" " movq %%mm2,%%mm4;\n" " pxor %%mm3,%%mm1;\n" " pcmpgtb %%mm0,%%mm3;\n" " pandn 0x08(%%ebx),%%mm4;\n" " psllw $1,%%mm2;\n" " movq %%mm2,%%mm3;\n" " pxor %%mm4,%%mm1;\n" " pcmpgtb %%mm0,%%mm3;\n" " psllw $1,%%mm2;\n" " pandn 0x10(%%ebx),%%mm3;\n" " movq %%mm2,%%mm4;\n" " pxor %%mm3,%%mm1;\n" " pcmpgtb %%mm0,%%mm3;\n" " psllw $1,%%mm2;\n" " pandn 0x18(%%ebx),%%mm4;\n" " movq %%mm2,%%mm3;\n" " pxor %%mm4,%%mm1;\n" " pcmpgtb %%mm0,%%mm3;\n" " pandn 0x20(%%ebx),%%mm3;\n" " psllw $1,%%mm2;\n" " movq %%mm2,%%mm4;\n" " pxor %%mm3,%%mm1;\n" " pcmpgtb %%mm0,%%mm3;\n" " psllw $1,%%mm2;\n" " pandn 0x28(%%ebx),%%mm4;\n" " movq %%mm2,%%mm3;\n" " pxor %%mm4,%%mm1;\n" " pcmpgtb %%mm0,%%mm3;\n" " psllw $1,%%mm2;\n" " pandn 0x30(%%ebx),%%mm3;\n" " pcmpgtb %%mm0,%%mm2;\n" " pxor %%mm3,%%mm1;\n" " pandn 0x38(%%ebx),%%mm4;\n" " addl $8,%%edi;\n" " pxor %%mm4,%%mm1;\n" " addl $8,%%esi;\n" " movq %%mm1,-8(%%edi);\n" " cmpl %%ecx,%%esi;\n" " jb 1b;\n" : : "b" (exp8+(255-gf_log[c])*8), "c" (sz+src1), "S" (src1), "D" (dst1) : "eax"); MYTOCK(); #endif } #if 1 /* ENCDEC */ void print(unsigned char *data, int s) { int i; for(i=0; i/tmp/x */ int main(int argc, char **argv) { struct stat buf; int size; int redundancy=atoi(argv[1]); int blocksize=atoi(argv[2]); int corrupted=atoi(argv[3]); unsigned char *data, *fec_data, *fec_data2; unsigned char *data_blocks[128], *fec_blocks[128], *dec_fec_blocks[128]; unsigned int fec_block_nos[128], erased_blocks[128]; int fec_size; int n; int nrBlocks; int i,j; int zilch[1024]; struct timeval tv; int seed; long long begin, end; #if 1 gettimeofday(&tv, 0); seed = tv.tv_sec ^ tv.tv_usec; #endif seed=996035588; srandom(seed); fprintf(stderr,"%d\n", seed); fstat(0, &buf); size=buf.st_size; if(size > blocksize * 128) size = blocksize * 128; nrBlocks = (size+blocksize-1)/blocksize; fprintf(stderr, "Size=%d nr=%d\n", size, nrBlocks); data = xmalloc(size+4096); data += 4096 - ((unsigned long) data) % 4096; fec_size = blocksize*redundancy; fec_data = xmalloc(fec_size+4096); fec_data += 4096 - ((unsigned long) fec_data) % 4096; fec_data2 = xmalloc(fec_size+4096); fec_data2 += 4096 - ((unsigned long) fec_data2) % 4096; n = read(0, data, size); if(n < size) { fprintf(stderr, "Short read\n"); exit(1); } begin = rdtsc(0); init_fec(); initFastTable(); end = rdtsc(1); fprintf(stderr, "%d cycles to create FEC buffer\n", (unsigned int) (end-begin)); for(i=0, j=0; i #endif struct participantsDb { int nrParticipants; struct clientDesc { struct sockaddr_in addr; int used; int capabilities; unsigned int rcvbuf; } clientTable[MAX_CLIENTS]; }; int addParticipant(participantsDb_t, struct sockaddr_in *addr, int capabilities, unsigned int rcvbuf, int pointopoint); int isParticipantValid(struct participantsDb *db, int i) { return db->clientTable[i].used; } int removeParticipant(struct participantsDb *db, int i) { if(db->clientTable[i].used) { char ipBuffer[16]; flprintf("Disconnecting #%d (%s)\n", i, getIpString(&db->clientTable[i].addr, ipBuffer)); #ifdef USE_SYSLOG syslog(LOG_INFO, "Disconnecting #%d (%s)\n", i, getIpString(&db->clientTable[i].addr, ipBuffer)); #endif db->clientTable[i].used = 0; db->nrParticipants--; } return 0; } int lookupParticipant(struct participantsDb *db, struct sockaddr_in *addr) { int i; for (i=0; i < MAX_CLIENTS; i++) { if (db->clientTable[i].used && ipIsEqual(&db->clientTable[i].addr, addr)) { return i; } } return -1; } int nrParticipants(participantsDb_t db) { return db->nrParticipants; } int addParticipant(participantsDb_t db, struct sockaddr_in *addr, int capabilities, unsigned int rcvbuf, int pointopoint) { int i; if((i = lookupParticipant(db, addr)) >= 0) return i; for (i=0; i < MAX_CLIENTS; i++) { if (!db->clientTable[i].used) { char ipBuffer[16]; db->clientTable[i].addr = *addr; db->clientTable[i].used = 1; db->clientTable[i].capabilities = capabilities; db->clientTable[i].rcvbuf = rcvbuf; db->nrParticipants++; fprintf(stderr, "New connection from %s (#%d) %08x\n", getIpString(addr, ipBuffer), i, capabilities); #ifdef USE_SYSLOG syslog(LOG_INFO, "New connection from %s (#%d)\n", getIpString(addr, ipBuffer), i); #endif return i; } else if(pointopoint) return -1; } return -1; /* no space left in participant's table */ } participantsDb_t makeParticipantsDb(void) { return MALLOC(struct participantsDb); } int getParticipantCapabilities(participantsDb_t db, int i) { return db->clientTable[i].capabilities; } unsigned int getParticipantRcvBuf(participantsDb_t db, int i) { return db->clientTable[i].rcvbuf; } struct sockaddr_in *getParticipantIp(participantsDb_t db, int i) { return &db->clientTable[i].addr; } void printNotSet(participantsDb_t db, char *d) { int first=1; int i; flprintf("["); for (i=0; i < MAX_CLIENTS; i++) { if (db->clientTable[i].used) { if(!BIT_ISSET(i, d)) { if(!first) flprintf(","); first=0; flprintf("%d", i); } } } flprintf("]"); } void printSet(participantsDb_t db, char *d) { int first=1; int i; flprintf("["); for (i=0; i < MAX_CLIENTS; i++) { if (db->clientTable[i].used) { if(BIT_ISSET(i, d)) { if(!first) flprintf(","); first=0; flprintf("%d", i); } } } flprintf("]"); } udpcast-20120424/auto-rate.h0000444000175000017500000000015211065117174014420 0ustar alainalain#ifndef AUTO_RATE_H #define AUTO_RATE_H extern struct rateGovernor_t autoRate; #endif /* AUTO_RATE_H */ udpcast-20120424/configure0000755000175000017500000050214311745607103014267 0ustar alainalain#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.65. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, # 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, # Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 test \$(( 1 + 1 )) = 2 || exit 1" if (eval "$as_required") 2>/dev/null; then : as_have_required=yes else as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir/$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : CONFIG_SHELL=$as_shell as_have_required=yes if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : break 2 fi fi done;; esac as_found=false done $as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : CONFIG_SHELL=$SHELL as_have_required=yes fi; } IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV export CONFIG_SHELL exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} fi if test x$as_have_required = xno; then : $as_echo "$0: This script requires a shell more modern than all" $as_echo "$0: the shells that I found on your system." if test x${ZSH_VERSION+set} = xset ; then $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, $0: including any error possibly output before this $0: message. Then install a modern shell, or manually run $0: the script under such a shell if you do have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_error ERROR [LINENO LOG_FD] # --------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with status $?, using 1 if that was 0. as_fn_error () { as_status=$?; test $as_status -eq 0 && as_status=1 if test "$3"; then as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3 fi $as_echo "$as_me: error: $1" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in #( -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME= PACKAGE_TARNAME= PACKAGE_VERSION= PACKAGE_STRING= PACKAGE_BUGREPORT= PACKAGE_URL= ac_unique_file="socklib.c" # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef STDC_HEADERS # include # include #else # ifdef HAVE_STDLIB_H # include # endif #endif #ifdef HAVE_STRING_H # if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include # endif # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_subst_vars='LTLIBOBJS LIBOBJS HOST_ID EXESUFFIX SHLIB MACHDEPLIBS extralibdir extraincludedir target_os target_vendor target_cpu target host_os host_vendor host_cpu host build_os build_vendor build_cpu build INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM EGREP GREP CPP OBJEXT EXEEXT ac_ct_CC CPPFLAGS LDFLAGS CFLAGS CC target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking ' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS CPP' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) as_fn_error "unrecognized option: \`$ac_option' Try \`$0 --help' for more information." ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error "unrecognized options: $ac_unrecognized_opts" ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe $as_echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. If a cross compiler is detected then cross compile mode will be used." >&2 elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error "pwd does not report name of working directory" # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures this package to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF System types: --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] --target=TARGET configure for building compilers for TARGET [HOST] _ACEOF fi if test -n "$ac_init_help"; then cat <<\_ACEOF Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CPP C preprocessor Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to the package provider. _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF configure generated by GNU Autoconf 2.65 Copyright (C) 2009 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## # ac_fn_c_try_compile LINENO # -------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} as_fn_set_status $ac_retval } # ac_fn_c_try_compile # ac_fn_c_try_cpp LINENO # ---------------------- # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} as_fn_set_status $ac_retval } # ac_fn_c_try_cpp # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} as_fn_set_status $ac_retval } # ac_fn_c_try_link # ac_fn_c_try_run LINENO # ---------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes # that executables *can* be run. ac_fn_c_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then : ac_retval=0 else $as_echo "$as_me: program exited with status $ac_status" >&5 $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} as_fn_set_status $ac_retval } # ac_fn_c_try_run # ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists, giving a warning if it cannot be compiled using # the include files in INCLUDES and setting the cache variable VAR # accordingly. ac_fn_c_check_header_mongrel () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 $as_echo_n "checking $2 usability... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_header_compiler=yes else ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 $as_echo_n "checking $2 presence... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <$2> _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : ac_header_preproc=yes else ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( yes:no: ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; no:yes:* ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} } # ac_fn_c_check_header_mongrel # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists and can be compiled using the include files in # INCLUDES, setting the cache variable VAR accordingly. ac_fn_c_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} } # ac_fn_c_check_header_compile # ac_fn_c_check_member LINENO AGGR MEMBER VAR INCLUDES # ---------------------------------------------------- # Tries to find if the field MEMBER exists in type AGGR, after including # INCLUDES, setting cache variable VAR accordingly. ac_fn_c_check_member () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5 $as_echo_n "checking for $2.$3... " >&6; } if { as_var=$4; eval "test \"\${$as_var+set}\" = set"; }; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $5 int main () { static $2 ac_aggr; if (ac_aggr.$3) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$4=yes" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $5 int main () { static $2 ac_aggr; if (sizeof ac_aggr.$3) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$4=yes" else eval "$4=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$4 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} } # ac_fn_c_check_member # ac_fn_c_check_type LINENO TYPE VAR INCLUDES # ------------------------------------------- # Tests whether TYPE exists after having included INCLUDES, setting cache # variable VAR accordingly. ac_fn_c_check_type () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : $as_echo_n "(cached) " >&6 else eval "$3=no" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof ($2)) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof (($2))) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else eval "$3=yes" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} } # ac_fn_c_check_type # ac_fn_c_check_func LINENO FUNC VAR # ---------------------------------- # Tests whether FUNC exists, setting the cache variable VAR accordingly ac_fn_c_check_func () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case declares $2. For example, HP-UX 11i declares gettimeofday. */ #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $2 (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $2 /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $2 (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$2 || defined __stub___$2 choke me #endif int main () { return $2 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} } # ac_fn_c_check_func cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by $as_me, which was generated by GNU Autoconf 2.65. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. $as_echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo cat <<\_ASBOX ## ---------------- ## ## Cache variables. ## ## ---------------- ## _ASBOX echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo cat <<\_ASBOX ## ----------------- ## ## Output variables. ## ## ----------------- ## _ASBOX echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then cat <<\_ASBOX ## ------------------- ## ## File substitutions. ## ## ------------------- ## _ASBOX echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then cat <<\_ASBOX ## ----------- ## ## confdefs.h. ## ## ----------- ## _ASBOX echo cat confdefs.h echo fi test "$ac_signal" != 0 && $as_echo "$as_me: caught signal $ac_signal" $as_echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h $as_echo "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_URL "$PACKAGE_URL" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then ac_site_file1=$CONFIG_SITE elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site else ac_site_file1=$ac_default_prefix/share/config.site ac_site_file2=$ac_default_prefix/etc/config.site fi for ac_site_file in "$ac_site_file1" "$ac_site_file2" do test "x$ac_site_file" = xNONE && continue if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 $as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 $as_echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 $as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 $as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_config_headers="$ac_config_headers config.h" ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_CC+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_CC+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_CC+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_CC+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_CC+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_CC+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error "no acceptable C compiler found in \$PATH See \`config.log' for more details." "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 $as_echo_n "checking whether the C compiler works... " >&6; } ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { { ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else ac_file='' fi if test -z "$ac_file"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { as_fn_set_status 77 as_fn_error "C compiler cannot create executables See \`config.log' for more details." "$LINENO" 5; }; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 $as_echo_n "checking for C compiler default output file name... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 $as_echo "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 $as_echo_n "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 $as_echo "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 $as_echo_n "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error "cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." "$LINENO" 5; } fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 $as_echo "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } if test "${ac_cv_objext+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error "cannot compute suffix of object files: cannot compile See \`config.log' for more details." "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if test "${ac_cv_c_compiler_gnu+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if test "${ac_cv_prog_cc_g+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if test "${ac_cv_prog_cc_c89+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 $as_echo_n "checking how to run the C preprocessor... " >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if test "${ac_cv_prog_CPP+set}" = set; then : $as_echo_n "(cached) " >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 $as_echo "$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error "C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } if test "${ac_cv_path_GREP+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then as_fn_error "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 $as_echo "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } if test "${ac_cv_path_EGREP+set}" = set; then : $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else if test -z "$EGREP"; then ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then as_fn_error "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 $as_echo "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" if test $ac_cv_c_compiler_gnu = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC needs -traditional" >&5 $as_echo_n "checking whether $CC needs -traditional... " >&6; } if test "${ac_cv_prog_gcc_traditional+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_pattern="Autoconf.*'x'" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include Autoconf TIOCGETP _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "$ac_pattern" >/dev/null 2>&1; then : ac_cv_prog_gcc_traditional=yes else ac_cv_prog_gcc_traditional=no fi rm -f conftest* if test $ac_cv_prog_gcc_traditional = no; then cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include Autoconf TCGETA _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "$ac_pattern" >/dev/null 2>&1; then : ac_cv_prog_gcc_traditional=yes fi rm -f conftest* fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_gcc_traditional" >&5 $as_echo "$ac_cv_prog_gcc_traditional" >&6; } if test $ac_cv_prog_gcc_traditional = yes; then CC="$CC -traditional" fi fi ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do for ac_t in install-sh install.sh shtool; do if test -f "$ac_dir/$ac_t"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/$ac_t -c" break 2 fi done done if test -z "$ac_aux_dir"; then as_fn_error "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. # Reject install programs that cannot install multiple files. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 $as_echo_n "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if test "${ac_cv_path_install+set}" = set; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in #(( ./ | .// | /[cC]/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else rm -rf conftest.one conftest.two conftest.dir echo one > conftest.one echo two > conftest.two mkdir conftest.dir if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && test -s conftest.one && test -s conftest.two && test -s conftest.dir/conftest.one && test -s conftest.dir/conftest.two then ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi fi done done ;; esac done IFS=$as_save_IFS rm -rf conftest.one conftest.two conftest.dir fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 $as_echo "$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' # Make sure we can run config.sub. $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || as_fn_error "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 $as_echo_n "checking build system type... " >&6; } if test "${ac_cv_build+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_build_alias=$build_alias test "x$ac_build_alias" = x && ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` test "x$ac_build_alias" = x && as_fn_error "cannot guess build type; you must specify one" "$LINENO" 5 ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || as_fn_error "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 $as_echo "$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; *) as_fn_error "invalid value of canonical build" "$LINENO" 5;; esac build=$ac_cv_build ac_save_IFS=$IFS; IFS='-' set x $ac_cv_build shift build_cpu=$1 build_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: build_os=$* IFS=$ac_save_IFS case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 $as_echo_n "checking host system type... " >&6; } if test "${ac_cv_host+set}" = set; then : $as_echo_n "(cached) " >&6 else if test "x$host_alias" = x; then ac_cv_host=$ac_cv_build else ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || as_fn_error "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 $as_echo "$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; *) as_fn_error "invalid value of canonical host" "$LINENO" 5;; esac host=$ac_cv_host ac_save_IFS=$IFS; IFS='-' set x $ac_cv_host shift host_cpu=$1 host_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: host_os=$* IFS=$ac_save_IFS case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking target system type" >&5 $as_echo_n "checking target system type... " >&6; } if test "${ac_cv_target+set}" = set; then : $as_echo_n "(cached) " >&6 else if test "x$target_alias" = x; then ac_cv_target=$ac_cv_host else ac_cv_target=`$SHELL "$ac_aux_dir/config.sub" $target_alias` || as_fn_error "$SHELL $ac_aux_dir/config.sub $target_alias failed" "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_target" >&5 $as_echo "$ac_cv_target" >&6; } case $ac_cv_target in *-*-*) ;; *) as_fn_error "invalid value of canonical target" "$LINENO" 5;; esac target=$ac_cv_target ac_save_IFS=$IFS; IFS='-' set x $ac_cv_target shift target_cpu=$1 target_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: target_os=$* IFS=$ac_save_IFS case $target_os in *\ *) target_os=`echo "$target_os" | sed 's/ /-/g'`;; esac # The aliases save the names the user supplied, while $host etc. # will get canonicalized. test -n "$target_alias" && test "$program_prefix$program_suffix$program_transform_name" = \ NONENONEs,x,x, && program_prefix=${target_alias}- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 $as_echo_n "checking for an ANSI C-conforming const... " >&6; } if test "${ac_cv_c_const+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { /* FIXME: Include the comments suggested by Paul. */ #ifndef __cplusplus /* Ultrix mips cc rejects this. */ typedef int charset[2]; const charset cs; /* SunOS 4.1.1 cc rejects this. */ char const *const *pcpcc; char **ppc; /* NEC SVR4.0.2 mips cc rejects this. */ struct point {int x, y;}; static struct point const zero = {0,0}; /* AIX XL C 1.02.0.0 rejects this. It does not let you subtract one const X* pointer from another in an arm of an if-expression whose if-part is not a constant expression */ const char *g = "string"; pcpcc = &g + (g ? g-g : 0); /* HPUX 7.0 cc rejects these. */ ++pcpcc; ppc = (char**) pcpcc; pcpcc = (char const *const *) ppc; { /* SCO 3.2v4 cc rejects this. */ char *t; char const *s = 0 ? (char *) 0 : (char const *) 0; *t++ = 0; if (s) return 0; } { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ int x[] = {25, 17}; const int *foo = &x[0]; ++foo; } { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ typedef const int *iptr; iptr p = 0; ++p; } { /* AIX XL C 1.02.0.0 rejects this saying "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ struct s { int j; const int *ap[3]; }; struct s *b; b->j = 5; } { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ const int foo = 10; if (!foo) return 0; } return !cs[0] && !zero.x; #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_const=yes else ac_cv_c_const=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 $as_echo "$ac_cv_c_const" >&6; } if test $ac_cv_c_const = no; then $as_echo "#define const /**/" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5 $as_echo_n "checking for inline... " >&6; } if test "${ac_cv_c_inline+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_cv_c_inline=no for ac_kw in inline __inline__ __inline; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifndef __cplusplus typedef int foo_t; static $ac_kw foo_t static_foo () {return 0; } $ac_kw foo_t foo () {return 0; } #endif _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_inline=$ac_kw fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext test "$ac_cv_c_inline" != no && break done fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5 $as_echo "$ac_cv_c_inline" >&6; } case $ac_cv_c_inline in inline | yes) ;; *) case $ac_cv_c_inline in no) ac_val=;; *) ac_val=$ac_cv_c_inline;; esac cat >>confdefs.h <<_ACEOF #ifndef __cplusplus #define inline $ac_val #endif _ACEOF ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_create in -lpthread" >&5 $as_echo_n "checking for pthread_create in -lpthread... " >&6; } if test "${ac_cv_lib_pthread_pthread_create+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpthread $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char pthread_create (); int main () { return pthread_create (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_pthread_pthread_create=yes else ac_cv_lib_pthread_pthread_create=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread_pthread_create" >&5 $as_echo "$ac_cv_lib_pthread_pthread_create" >&6; } if test "x$ac_cv_lib_pthread_pthread_create" = x""yes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBPTHREAD 1 _ACEOF LIBS="-lpthread $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlsym in -ldl" >&5 $as_echo_n "checking for dlsym in -ldl... " >&6; } if test "${ac_cv_lib_dl_dlsym+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlsym (); int main () { return dlsym (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dl_dlsym=yes else ac_cv_lib_dl_dlsym=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlsym" >&5 $as_echo "$ac_cv_lib_dl_dlsym" >&6; } if test "x$ac_cv_lib_dl_dlsym" = x""yes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBDL 1 _ACEOF LIBS="-ldl $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if test "${ac_cv_header_stdc+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sys/wait.h that is POSIX.1 compatible" >&5 $as_echo_n "checking for sys/wait.h that is POSIX.1 compatible... " >&6; } if test "${ac_cv_header_sys_wait_h+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #ifndef WEXITSTATUS # define WEXITSTATUS(stat_val) ((unsigned int) (stat_val) >> 8) #endif #ifndef WIFEXITED # define WIFEXITED(stat_val) (((stat_val) & 255) == 0) #endif int main () { int s; wait (&s); s = WIFEXITED (s) ? WEXITSTATUS (s) : 1; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_sys_wait_h=yes else ac_cv_header_sys_wait_h=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_sys_wait_h" >&5 $as_echo "$ac_cv_header_sys_wait_h" >&6; } if test $ac_cv_header_sys_wait_h = yes; then $as_echo "#define HAVE_SYS_WAIT_H 1" >>confdefs.h fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " eval as_val=\$$as_ac_Header if test "x$as_val" = x""yes; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in fcntl.h limits.h sys/ioctl.h sys/time.h arpa/inet.h netdb.h \ sys/select.h sys/sockio.h sys/socket.h sys/param.h memory.h malloc.h signal.h \ net/if.h netinet/in.h winsock2.h sys/uio.h getopt.h dlfcn.h string.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" eval as_val=\$$as_ac_Header if test "x$as_val" = x""yes; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in termios.h sys/termios.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" eval as_val=\$$as_ac_Header if test "x$as_val" = x""yes; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF break fi done ac_fn_c_check_member "$LINENO" "struct ip_mreqn" "imr_ifindex" "ac_cv_member_struct_ip_mreqn_imr_ifindex" "#ifdef HAVE_NETINET_IN_H #include #endif " if test "x$ac_cv_member_struct_ip_mreqn_imr_ifindex" = x""yes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STRUCT_IP_MREQN_IMR_IFINDEX 1 _ACEOF fi ac_fn_c_check_type "$LINENO" "in_addr_t" "ac_cv_type_in_addr_t" "#ifdef HAVE_ARPA_INET_H #include #endif " if test "x$ac_cv_type_in_addr_t" = x""yes; then : cat >>confdefs.h <<_ACEOF #define HAVE_IN_ADDR_T 1 _ACEOF fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether llseek declared in unistd.h" >&5 $as_echo_n "checking whether llseek declared in unistd.h... " >&6; } if test "${mtools_cv_have_llseek_prototype+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { extern int llseek(int); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : mtools_cv_have_llseek_prototype=no else mtools_cv_have_llseek_prototype=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $mtools_cv_have_llseek_prototype" >&5 $as_echo "$mtools_cv_have_llseek_prototype" >&6; } if test "$mtools_cv_have_llseek_prototype" = yes; then $as_echo "#define HAVE_LLSEEK_PROTOTYPE 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether lseek64 declared in unistd.h" >&5 $as_echo_n "checking whether lseek64 declared in unistd.h... " >&6; } if test "${mtools_cv_have_lseek64_prototype+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include "sysincludes.h" #include int main () { extern int lseek64(int); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : mtools_cv_have_lseek64_prototype=no else mtools_cv_have_lseek64_prototype=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $mtools_cv_have_lseek64_prototype" >&5 $as_echo "$mtools_cv_have_lseek64_prototype" >&6; } if test "$mtools_cv_have_lseek64_prototype" = yes; then $as_echo "#define HAVE_LSEEK64_PROTOTYPE 1" >>confdefs.h fi for ac_func in htons kill daemon do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" eval as_val=\$$as_ac_var if test "x$as_val" = x""yes; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 $as_echo_n "checking for an ANSI C-conforming const... " >&6; } if test "${ac_cv_c_const+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { /* FIXME: Include the comments suggested by Paul. */ #ifndef __cplusplus /* Ultrix mips cc rejects this. */ typedef int charset[2]; const charset cs; /* SunOS 4.1.1 cc rejects this. */ char const *const *pcpcc; char **ppc; /* NEC SVR4.0.2 mips cc rejects this. */ struct point {int x, y;}; static struct point const zero = {0,0}; /* AIX XL C 1.02.0.0 rejects this. It does not let you subtract one const X* pointer from another in an arm of an if-expression whose if-part is not a constant expression */ const char *g = "string"; pcpcc = &g + (g ? g-g : 0); /* HPUX 7.0 cc rejects these. */ ++pcpcc; ppc = (char**) pcpcc; pcpcc = (char const *const *) ppc; { /* SCO 3.2v4 cc rejects this. */ char *t; char const *s = 0 ? (char *) 0 : (char const *) 0; *t++ = 0; if (s) return 0; } { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ int x[] = {25, 17}; const int *foo = &x[0]; ++foo; } { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ typedef const int *iptr; iptr p = 0; ++p; } { /* AIX XL C 1.02.0.0 rejects this saying "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ struct s { int j; const int *ap[3]; }; struct s *b; b->j = 5; } { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ const int foo = 10; if (!foo) return 0; } return !cs[0] && !zero.x; #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_const=yes else ac_cv_c_const=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 $as_echo "$ac_cv_c_const" >&6; } if test $ac_cv_c_const = no; then $as_echo "#define const /**/" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5 $as_echo_n "checking for inline... " >&6; } if test "${ac_cv_c_inline+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_cv_c_inline=no for ac_kw in inline __inline__ __inline; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifndef __cplusplus typedef int foo_t; static $ac_kw foo_t static_foo () {return 0; } $ac_kw foo_t foo () {return 0; } #endif _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_inline=$ac_kw fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext test "$ac_cv_c_inline" != no && break done fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5 $as_echo "$ac_cv_c_inline" >&6; } case $ac_cv_c_inline in inline | yes) ;; *) case $ac_cv_c_inline in no) ac_val=;; *) ac_val=$ac_cv_c_inline;; esac cat >>confdefs.h <<_ACEOF #ifndef __cplusplus #define inline $ac_val #endif _ACEOF ;; esac ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" if test "x$ac_cv_type_size_t" = x""yes; then : else cat >>confdefs.h <<_ACEOF #define size_t unsigned int _ACEOF fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether time.h and sys/time.h may both be included" >&5 $as_echo_n "checking whether time.h and sys/time.h may both be included... " >&6; } if test "${ac_cv_header_time+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main () { if ((struct tm *) 0) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_time=yes else ac_cv_header_time=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_time" >&5 $as_echo "$ac_cv_header_time" >&6; } if test $ac_cv_header_time = yes; then $as_echo "#define TIME_WITH_SYS_TIME 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether struct tm is in sys/time.h or time.h" >&5 $as_echo_n "checking whether struct tm is in sys/time.h or time.h... " >&6; } if test "${ac_cv_struct_tm+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { struct tm tm; int *p = &tm.tm_sec; return !p; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_struct_tm=time.h else ac_cv_struct_tm=sys/time.h fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_struct_tm" >&5 $as_echo "$ac_cv_struct_tm" >&6; } if test $ac_cv_struct_tm = sys/time.h; then $as_echo "#define TM_IN_SYS_TIME 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking return type of signal handlers" >&5 $as_echo_n "checking return type of signal handlers... " >&6; } if test "${ac_cv_type_signal+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { return *(signal (0, 0)) (0) == 1; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_type_signal=int else ac_cv_type_signal=void fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_signal" >&5 $as_echo "$ac_cv_type_signal" >&6; } cat >>confdefs.h <<_ACEOF #define RETSIGTYPE $ac_cv_type_signal _ACEOF for ac_func in atexit on_exit tcsetattr lseek64 snprintf inet_pton inet_aton getopt_long dlsym do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" eval as_val=\$$as_ac_var if test "x$as_val" = x""yes; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for 64-bit off_t" >&5 $as_echo_n "checking for 64-bit off_t... " >&6; } if test "${sfs_cv_off_t_64+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { switch (0) case 0: case (sizeof (off_t) <= 4):; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sfs_cv_off_t_64=no else sfs_cv_off_t_64=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sfs_cv_off_t_64" >&5 $as_echo "$sfs_cv_off_t_64" >&6; } if test $sfs_cv_off_t_64 = yes; then $as_echo "#define HAVE_OFF_T_64 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${CC} supports loff_t type" >&5 $as_echo_n "checking whether ${CC} supports loff_t type... " >&6; } if test "${ice_cv_have_loff_t+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { loff_t a; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ice_cv_have_loff_t=yes else ice_cv_have_loff_t=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ice_cv_have_loff_t" >&5 $as_echo "$ice_cv_have_loff_t" >&6; } if test "$ice_cv_have_loff_t" = yes; then $as_echo "#define HAVE_LOFF_T 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${CC} supports offset_t type" >&5 $as_echo_n "checking whether ${CC} supports offset_t type... " >&6; } if test "${ice_cv_have_offset_t+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { offset_t a; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ice_cv_have_offset_t=yes else ice_cv_have_offset_t=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ice_cv_have_offset_t" >&5 $as_echo "$ice_cv_have_offset_t" >&6; } if test "$ice_cv_have_offset_t" = yes; then $as_echo "#define HAVE_OFFSET_T 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${CC} supports long long type" >&5 $as_echo_n "checking whether ${CC} supports long long type... " >&6; } if test "${ice_cv_have_long_long+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { long long a; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ice_cv_have_long_long=yes else ice_cv_have_long_long=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ice_cv_have_long_long" >&5 $as_echo "$ice_cv_have_long_long" >&6; } if test "$ice_cv_have_long_long" = yes; then $as_echo "#define HAVE_LONG_LONG 1" >>confdefs.h fi host_os0=`echo $host_os | sed 's/-/_/g'` host_os1=`echo $host_os0 | sed 's/\./_/g'` host_os2=`echo $host_os0 | sed 's/^\([^.]*\)\..*$/\1/g'` host_os3=`echo $host_os2 | sed 's/^\([^0-9]*\)[0-9]*$/\1/g'` host_cpu1=`echo $host_cpu | sed 's/\./_/g'` host_vendor1=`echo $host_vendor | sed 's/\./_/g'` HOST_ID="-DCPU_$host_cpu1 -DVENDOR_$host_vendor1 -DOS_$host_os1" if [ $host_os1 != $host_os2 ] ; then HOST_ID="$HOST_ID -DOS_$host_os2" fi if [ $host_os1 != $host_os3 ] && [ $host_os2 != $host_os3 ] ; then HOST_ID="$HOST_ID -DOS_$host_os3" fi my_host_os=`echo $host_os1 $host_os2 $host_os3 | sort -u` objs=`echo $srcdir/*.c | sed 's/\.c$/.o/' ` if [ "X$GCC" = "Xyes" ] ; then Wall=-Wall if [ "$host_os3" = sunos ] ; then Wall="" fi if [ "$host_os3" = solaris ] ; then CFLAGS="$CFLAGS -D_XOPEN_SOURCE -D_XOPEN_SOURCE_EXTENDED=1 -D__EXTENSIONS__" LIBS="$LIBS -lnsl -lsocket" Wall="" fi if [ "$host_os3" = ultrix ] ; then Wall="" fi if [ "$host_os3" = linux ] ; then CFLAGS="$CFLAGS -fno-strength-reduce" fi if [ "$host_os3" = aux ] ; then CFLAGS="$CFLAGS -ZP" MACHDEPLIBS="-lposix -UTIL" fi case "${host}" in arm*-*-linux) CFLAGS="$CFLAGS -mstructure-size-boundary=8";; esac CFLAGS="$CFLAGS $Wall" else if [ $host_os3 = hpux ] ; then CPPFLAGS="$CPPFLAGS -Ae" fi if [ $host_os3 = xenix ] ; then CFLAGS="$CFLAGS -M2e" fi fi if [ $host_os3 = hpux ] ; then LDFLAGS="$LDFLAGS -z" fi if [ $host_vendor = linux ] ; then LDFLAGS="$LDFLAGS -z" fi if [ $host_os3 = xenix ] ; then LDFLAGS="$LDFLAGS -M2e -i -f 5000" fi if [ $host_os2 = sysv4 ] ; then SHLIB="-lc -L/usr/ucblib -lucb" else SHLIB="" fi if [ $host_os3 = isc ] ; then CFLAGS="$CFLAGS -D_SYSV3" SHLIB="-lc_s" fi if [ $host_os3 = nextstep ] ; then CFLAGS="$CFLAGS -DBSD" SHLIB="" fi if [ $host_os3 = mingw -o $host_os3 = mingw32msvc ] ; then LIBS="$LIBS -lws2_32 -liphlpapi" EXESUFFIX=".exe" fi if [ -d /usr/5lib ] ; then extralibdir=-L/usr/5lib fi ac_config_files="$ac_config_files Makefile" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then test "x$cache_file" != "x/dev/null" && { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} cat confcache >$cache_file else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`$as_echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs : ${CONFIG_STATUS=./config.status} ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # as_fn_error ERROR [LINENO LOG_FD] # --------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with status $?, using 1 if that was 0. as_fn_error () { as_status=$?; test $as_status -eq 0 && as_status=1 if test "$3"; then as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3 fi $as_echo "$as_me: error: $1" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in #( -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by $as_me, which was generated by GNU Autoconf 2.65. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac case $ac_config_headers in *" "*) set x $ac_config_headers; shift; ac_config_headers=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" config_headers="$ac_config_headers" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Report bugs to the package provider." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ config.status configured by $0, generated by GNU Autoconf 2.65, with options \\"\$ac_cs_config\\" Copyright (C) 2009 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' INSTALL='$INSTALL' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append CONFIG_HEADERS " '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header as_fn_error "ambiguous option: \`$1' Try \`$0 --help' for more information.";; --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX $as_echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; *) as_fn_error "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= trap 'exit_status=$? { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error "cannot create a temporary directory in ." "$LINENO" 5 # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '$'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \ || as_fn_error "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove $(srcdir), # ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=/{ s/:*\$(srcdir):*/:/ s/:*\${srcdir}:*/:/ s/:*@srcdir@:*/:/ s/^\([^=]*=[ ]*\):*/\1/ s/:*$// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" # Set up the scripts for CONFIG_HEADERS section. # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then cat >"$tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF # Transform confdefs.h into an awk script `defines.awk', embedded as # here-document in config.status, that substitutes the proper values into # config.h.in to produce config.h. # Create a delimiter string that does not exist in confdefs.h, to ease # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do ac_t=`sed -n "/$ac_delim/p" confdefs.h` if test -z "$ac_t"; then break elif $ac_last_try; then as_fn_error "could not make $CONFIG_HEADERS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done # For the awk script, D is an array of macro values keyed by name, # likewise P contains macro parameters if any. Preserve backslash # newline sequences. ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* sed -n ' s/.\{148\}/&'"$ac_delim"'/g t rset :rset s/^[ ]*#[ ]*define[ ][ ]*/ / t def d :def s/\\$// t bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3"/p s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p d :bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3\\\\\\n"\\/p t cont s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p t cont d :cont n s/.\{148\}/&'"$ac_delim"'/g t clear :clear s/\\$// t bsnlc s/["\\]/\\&/g; s/^/"/; s/$/"/p d :bsnlc s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p b cont ' >$CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 for (key in D) D_is_set[key] = 1 FS = "" } /^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { line = \$ 0 split(line, arg, " ") if (arg[1] == "#") { defundef = arg[2] mac1 = arg[3] } else { defundef = substr(arg[1], 2) mac1 = arg[2] } split(mac1, mac2, "(") #) macro = mac2[1] prefix = substr(line, 1, index(line, defundef) - 1) if (D_is_set[macro]) { # Preserve the white space surrounding the "#". print prefix "define", macro P[macro] D[macro] next } else { # Replace #undef with comments. This is necessary, for example, # in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. if (defundef == "undef") { print "/*", prefix defundef, macro, "*/" next } } } { print } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 as_fn_error "could not setup config headers machinery" "$LINENO" 5 fi # test -n "$CONFIG_HEADERS" eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS " shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$tmp/stdin" \ || as_fn_error "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \ || as_fn_error "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined." >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined." >&2;} rm -f "$tmp/stdin" case $ac_file in -) cat "$tmp/out" && rm -f "$tmp/out";; *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";; esac \ || as_fn_error "could not create $ac_file" "$LINENO" 5 ;; :H) # # CONFIG_HEADER # if test x"$ac_file" != x-; then { $as_echo "/* $configure_input */" \ && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" } >"$tmp/config.h" \ || as_fn_error "could not create $ac_file" "$LINENO" 5 if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$tmp/config.h" "$ac_file" \ || as_fn_error "could not create $ac_file" "$LINENO" 5 fi else $as_echo "/* $configure_input */" \ && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error "could not create -" "$LINENO" 5 fi ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit $? fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi udpcast-20120424/log.h0000444000175000017500000000142711606074507013311 0ustar alainalain#ifndef LOG_H #define LOG_H #include #undef HAVE_STDINT_H #include "libbb_udpcast.h" #define logprintf udpc_logprintf #define flprintf udpc_flprintf #define fatal udpc_fatal #define printLongNum udpc_printLongNum /*void printNewlineIfNeeded(void);*/ #ifdef __GNUC__ int logprintf(FILE *logfile, const char *fmt, ...) __attribute__ ((format (printf, 2, 3))); int flprintf(const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); int fatal(int code, const char *fmt, ...) __attribute__ ((noreturn)) __attribute__ ((format (printf, 2, 3))); #else int logprintf(FILE *logfile, const char *fmt, ...); int flprintf(const char *fmt, ...) ; int fatal(int code, const char *fmt, ...) ; #endif int printLongNum(unsigned long long x); extern FILE *udpc_log; #endif udpcast-20120424/receivedata.c0000444000175000017500000010271311606103427014771 0ustar alainalain#include #include #include #include #include #include #include "socklib.h" #include "threads.h" #include "log.h" #include "fifo.h" #include "udpc-protoc.h" #include "udp-receiver.h" #include "util.h" #include "statistics.h" #include "fec.h" #define DEBUG 0 #define ADR(x, bs) (fifo->dataBuffer + \ (slice->base+(x)*bs) % fifo->dataBufSize) #define SLICEMAGIC 0x41424344 #define NR_SLICES 4 typedef enum slice_state { SLICE_FREE, /* Free slice */ SLICE_RECEIVING, /* Data being received */ SLICE_DONE /* All data received */ #ifdef BB_FEATURE_UDPCAST_FEC , SLICE_FEC, /* Fec calculation in progress */ SLICE_FEC_DONE /* Fec calculation done */ #endif } slice_state_t; #ifdef BB_FEATURE_UDPCAST_FEC struct fec_desc { unsigned char *adr; /* address of FEC block */ int fecBlockNo; /* number of FEC block */ int erasedBlockNo; /* erased data block */ }; #endif typedef struct slice { int magic; volatile slice_state_t state; int base; /* base offset of beginning of slice */ int sliceNo; /* current slice number */ int blocksTransferred; /* blocks transferred during this slice */ int dataBlocksTransferred; /* data blocks transferred during this slice */ int bytes; /* number of bytes in this slice (or 0, if unknown) */ int bytesKnown; /* is number of bytes known yet? */ int freePos; /* where the next data part will be stored to */ struct retransmit retransmit; /* How many data blocks are there missing per stripe? */ short missing_data_blocks[MAX_FEC_INTERLEAVE]; #ifdef BB_FEATURE_UDPCAST_FEC int fec_stripes; /* number of stripes for FEC */ /* How many FEC blocs do we have per stripe? */ short fec_blocks[MAX_FEC_INTERLEAVE]; struct fec_desc fec_descs[MAX_SLICE_SIZE]; #endif } *slice_t; struct clientState { struct fifo *fifo; struct client_config *client_config; struct net_config *net_config; union serverDataMsg Msg; struct msghdr data_hdr; /* pre-prepared messages */ struct iovec data_iov[2]; struct slice *currentSlice; int currentSliceNo; receiver_stats_t stats; produconsum_t free_slices_pc; struct slice slices[NR_SLICES]; /* Completely received slices */ int receivedPtr; int receivedSliceNo; #ifdef BB_FEATURE_UDPCAST_FEC int use_fec; /* do we use forward error correction ? */ #endif produconsum_t fec_data_pc; struct slice *fec_slices[NR_SLICES]; pthread_t fec_thread; /* A reservoir of free blocks for FEC */ produconsum_t freeBlocks_pc; unsigned char **blockAddresses; /* adresses of blocks in local queue */ unsigned char **localBlockAddresses; /* local blocks: freed FEC blocks after we * have received the corresponding data */ int localPos; unsigned char *blockData; unsigned char *nextBlock; int endReached; /* end of transmission reached: 0: transmission in progress 2: network transmission _and_ FEC processing finished */ int netEndReached; /* In case of a FEC transmission; network * transmission finished. This is needed to avoid * a race condition, where the receiver thread would * already prepare to wait for more data, at the same * time that the FEC would set endReached. To avoid * this, we do a select without timeout before * receiving the last few packets, so that if the * race condition strikes, we have a way to protect * against */ int selectedFd; int promptPrinted; /* Has "Press any key..." prompt already been printed */ #ifdef BB_FEATURE_UDPCAST_FEC fec_code_t fec_code; #endif }; static void printMissedBlockMap(struct clientState *clst, slice_t slice) { int i, first=1; int blocksInSlice = (slice->bytes + clst->net_config->blockSize - 1) / clst->net_config->blockSize; for(i=0; i< blocksInSlice ; i++) { if(!BIT_ISSET(i,slice->retransmit.map)) { if(first) fprintf(stderr, "Missed blocks: "); else fprintf(stderr, ","); fprintf(stderr, "%d",i); first=0; } } if(!first) fprintf(stderr, "\n"); first=1; #ifdef BB_FEATURE_UDPCAST_FEC if(slice->fec_stripes != 0) { for(i=0; ifec_stripes < slice->fec_blocks[i % slice->fec_stripes]) { if(first) fprintf(stderr, "FEC blocks: "); else fprintf(stderr, ","); fprintf(stderr, "%d",slice->fec_descs[i].fecBlockNo); first=0; } } } #endif if(!first) fprintf(stderr, "\n"); fprintf(stderr, "Blocks received: %d/%d/%d\n", slice->dataBlocksTransferred, slice->blocksTransferred, blocksInSlice); #ifdef BB_FEATURE_UDPCAST_FEC for(i=0; ifec_stripes; i++) { fprintf(stderr, "Stripe %2d: %3d/%3d %s\n", i, slice->missing_data_blocks[i], slice->fec_blocks[i], slice->missing_data_blocks[i] > slice->fec_blocks[i] ? "**************" :""); } #endif } static int sendOk(struct client_config *client_config, unsigned int sliceNo) { struct ok ok; ok.opCode = htons(CMD_OK); ok.reserved = 0; ok.sliceNo = htonl(sliceNo); return SSEND(ok); } static int sendRetransmit(struct clientState *clst, struct slice *slice, int rxmit) { struct client_config *client_config = clst->client_config; assert(slice->magic == SLICEMAGIC); slice->retransmit.opCode = htons(CMD_RETRANSMIT); slice->retransmit.reserved = 0; slice->retransmit.sliceNo = htonl(slice->sliceNo); slice->retransmit.rxmit = htonl(rxmit); return SSEND(slice->retransmit); } static unsigned char *getBlockSpace(struct clientState *clst) { int pos; if(clst->localPos) { clst->localPos--; return clst->localBlockAddresses[clst->localPos]; } pc_consume(clst->freeBlocks_pc, 1); pos = pc_getConsumerPosition(clst->freeBlocks_pc); pc_consumed(clst->freeBlocks_pc, 1); return clst->blockAddresses[pos]; } #ifdef BB_FEATURE_UDPCAST_FEC static void freeBlockSpace(struct clientState *clst, unsigned char *block) { int pos = pc_getProducerPosition(clst->freeBlocks_pc); assert(block != 0); clst->blockAddresses[pos] = block; pc_produce(clst->freeBlocks_pc, 1); } #endif static void setNextBlock(struct clientState *clst) { clst->nextBlock = getBlockSpace(clst); } /** * Initialize slice for new slice number * memory is not touched */ static struct slice *initSlice(struct clientState *clst, struct slice *slice, int sliceNo) { assert(slice->state == SLICE_FREE || slice->state == SLICE_RECEIVING); slice->magic = SLICEMAGIC; slice->state = SLICE_RECEIVING; slice->blocksTransferred = 0; slice->dataBlocksTransferred = 0; BZERO(slice->retransmit); slice->freePos = 0; slice->bytes = 0; if(clst->currentSlice != NULL) { if(!clst->currentSlice->bytesKnown) udpc_fatal(1, "Previous slice size not known\n"); if(clst->net_config->flags & FLAG_IGNORE_LOST_DATA) slice->bytes = clst->currentSlice->bytes; } if(!(clst->net_config->flags & FLAG_STREAMING)) if(clst->currentSliceNo != sliceNo-1) { udpc_fatal(1, "Slice no mismatch %d <-> %d\n", sliceNo, clst->currentSliceNo); } slice->bytesKnown = 0; slice->sliceNo = sliceNo; BZERO(slice->missing_data_blocks); #ifdef BB_FEATURE_UDPCAST_FEC BZERO(slice->fec_stripes); BZERO(slice->fec_blocks); BZERO(slice->fec_descs); #endif clst->currentSlice = slice; clst->currentSliceNo = sliceNo; return slice; } static struct slice *newSlice(struct clientState *clst, int sliceNo) { struct slice *slice=NULL; int i; #if DEBUG flprintf("Getting new slice %d\n", pc_getConsumerPosition(clst->free_slices_pc)); #endif pc_consume(clst->free_slices_pc, 1); #if DEBUG flprintf("Got new slice\n"); #endif i = pc_getConsumerPosition(clst->free_slices_pc); pc_consumed(clst->free_slices_pc, 1); slice = &clst->slices[i]; assert(slice->state == SLICE_FREE); /* wait for free data memory */ slice->base = pc_getConsumerPosition(clst->fifo->freeMemQueue); #if DEBUG if(pc_consume(clst->fifo->freeMemQueue, 0) < clst->net_config->blockSize * MAX_SLICE_SIZE) flprintf("Pipeline full\n"); #endif pc_consume(clst->fifo->freeMemQueue, clst->net_config->blockSize * MAX_SLICE_SIZE); initSlice(clst, slice, sliceNo); return slice; } static void checkSliceComplete(struct clientState *clst, struct slice *slice); static struct slice *findSlice(struct clientState *clst, int sliceNo); static void setSliceBytes(struct slice *slice, struct clientState *clst, int bytes); static void fakeSliceComplete(struct clientState *clst) { slice_t slice = NULL; slice = findSlice(clst, clst->receivedSliceNo+1); assert(slice != NULL); assert(slice->state != SLICE_DONE); if(! slice->bytesKnown ) setSliceBytes(slice, clst, slice->bytes); slice->blocksTransferred = slice->dataBlocksTransferred = (slice->bytes + clst->net_config->blockSize - 1) / clst->net_config->blockSize; checkSliceComplete(clst, slice); } static struct slice *findSlice(struct clientState *clst, int sliceNo) { if(! clst->currentSlice) { /* Streaming mode? */ clst->currentSliceNo = sliceNo-1; return newSlice(clst, sliceNo); } if(sliceNo <= clst->currentSliceNo) { struct slice *slice = clst->currentSlice; int pos = slice - clst->slices; assert(slice == NULL || slice->magic == SLICEMAGIC); while(slice->sliceNo != sliceNo) { if(slice->state == SLICE_FREE) return NULL; assert(slice->magic == SLICEMAGIC); pos--; if(pos < 0) pos += NR_SLICES; slice = &clst->slices[pos]; } return slice; } if((clst->net_config->flags & FLAG_STREAMING) && sliceNo != clst->currentSliceNo) { assert(clst->currentSlice = &clst->slices[0]); return initSlice(clst, clst->currentSlice, sliceNo); } while(sliceNo > clst->receivedSliceNo + 2 || sliceNo != clst->currentSliceNo + 1) { slice_t slice = findSlice(clst, clst->receivedSliceNo+1); if(clst->net_config->flags & FLAG_IGNORE_LOST_DATA) fakeSliceComplete(clst); else { udpc_flprintf("Dropped by server now=%d last=%d\n", sliceNo, clst->receivedSliceNo); if(slice != NULL) printMissedBlockMap(clst, slice); exit(1); } } return newSlice(clst, sliceNo); } static void setSliceBytes(struct slice *slice, struct clientState *clst, int bytes) { assert(slice->magic == SLICEMAGIC); if(slice->bytesKnown) { if(slice->bytes != bytes) { udpc_fatal(1, "Byte number mismatch %d <-> %d\n", bytes, slice->bytes); } } else { slice->bytesKnown = 1; slice->bytes = bytes; if(bytes == 0) clst->netEndReached=1; if(! (clst->net_config->flags & FLAG_STREAMING) ) { /* In streaming mode, do not reserve space as soon as first * block of slice received, but only when slice complete. * For detailed discussion why, see comment in checkSliceComplete */ pc_consumed(clst->fifo->freeMemQueue, bytes); } } } /** * Advance pointer of received slices */ static void advanceReceivedPointer(struct clientState *clst) { int pos = clst->receivedPtr; while(1) { slice_t slice = &clst->slices[pos]; if( #ifdef BB_FEATURE_UDPCAST_FEC slice->state != SLICE_FEC && slice->state != SLICE_FEC_DONE && #endif slice->state != SLICE_DONE) break; pos++; clst->receivedSliceNo = slice->sliceNo; if(pos >= NR_SLICES) pos -= NR_SLICES; } clst->receivedPtr = pos; } /** * Cleans up all finished slices. At first, invoked by the net receiver * thread. However, once FEC has become active, net receiver will no longer * call it, and instead it will be called by the fec thread. */ static void cleanupSlices(struct clientState *clst, unsigned int doneState) { while(1) { int pos = pc_getProducerPosition(clst->free_slices_pc); int bytes; slice_t slice = &clst->slices[pos]; #if DEBUG flprintf("Attempting to clean slice %d %d %d %d at %d\n", slice->sliceNo, slice->state, doneState, clst->use_fec, pos); #endif if(slice->state != doneState) break; receiverStatsAddBytes(clst->stats, slice->bytes); displayReceiverStats(clst->stats, 0); bytes = slice->bytes; /* signal data received */ if(bytes == 0) { pc_produceEnd(clst->fifo->data); } else pc_produce(clst->fifo->data, slice->bytes); /* free up slice structure */ clst->slices[pos].state = SLICE_FREE; #if DEBUG flprintf("Giving back slice %d => %d %p\n", clst->slices[pos].sliceNo, pos, &clst->slices[pos]); #endif pc_produce(clst->free_slices_pc, 1); /* if at end, exit this thread */ if(!bytes) { clst->endReached = 2; } } } /** * Check whether this slice is sufficiently complete */ static void checkSliceComplete(struct clientState *clst, struct slice *slice) { int blocksInSlice; assert(slice->magic == SLICEMAGIC); if(slice->state != SLICE_RECEIVING) /* bad starting state */ return; /* is this slice ready ? */ assert(clst->net_config->blockSize != 0); blocksInSlice = (slice->bytes + clst->net_config->blockSize - 1) / clst->net_config->blockSize; if(blocksInSlice == slice->blocksTransferred) { if(clst->net_config->flags & FLAG_STREAMING) { /* If we are in streaming mode, the storage space for the first * entire slice is only consumed once it is complete. This * is because it is only at comletion time that we know * for sure that it can be completed (before, we could * have missed the beginning). * After having completed one slice, revert back to normal * mode where we consumed the free space as soon as the * first block is received (not doing this would produce * errors if a new slice is started before a previous one * is complete, such as during retransmissions) */ pc_consumed(clst->fifo->freeMemQueue, slice->bytes); clst->net_config->flags &= ~FLAG_STREAMING; } if(blocksInSlice == slice->dataBlocksTransferred) slice->state = SLICE_DONE; else { #ifdef BB_FEATURE_UDPCAST_FEC assert(clst->use_fec == 1); slice->state = SLICE_FEC; #else assert(0); #endif } advanceReceivedPointer(clst); #ifdef BB_FEATURE_UDPCAST_FEC if(clst->use_fec) { int n = pc_getProducerPosition(clst->fec_data_pc); assert(slice->state == SLICE_DONE || slice->state == SLICE_FEC); clst->fec_slices[n] = slice; pc_produce(clst->fec_data_pc, 1); } else #endif cleanupSlices(clst, SLICE_DONE); } } #ifdef BB_FEATURE_UDPCAST_FEC static int getSliceBlocks(struct slice *slice, struct net_config *net_config) { assert(net_config->blockSize != 0); return (slice->bytes + net_config->blockSize - 1) / net_config->blockSize; } static void fec_decode_one_stripe(struct clientState *clst, struct slice *slice, int stripe, int bytes, int stripes, short nr_fec_blocks, struct fec_desc *fec_descs) { struct fifo *fifo = clst->fifo; struct net_config *config = clst->net_config; unsigned char *map = slice->retransmit.map; /* int nrBlocks = (bytes + data->blockSize - 1) / data->blockSize; */ int nrBlocks = getSliceBlocks(slice, config); int leftOver = bytes % config->blockSize; int j; unsigned char *fec_blocks[nr_fec_blocks]; unsigned int fec_block_nos[nr_fec_blocks]; unsigned int erased_blocks[nr_fec_blocks]; unsigned char *data_blocks[128]; int erasedIdx = stripe; int i; for(i=stripe, j=0; iblockSize); memset(lastBlock+leftOver, 0, config->blockSize-leftOver); } for(i=stripe, j=0; i< nrBlocks; i+=stripes, j++) data_blocks[j] = ADR(i, config->blockSize); fec_decode(config->blockSize, data_blocks, j, fec_blocks, fec_block_nos, erased_blocks, nr_fec_blocks); } static THREAD_RETURN fecMain(void *args0) { struct clientState *clst = (struct clientState *) args0; int pos; struct fifo *fifo = clst->fifo; struct net_config *config = clst->net_config; assert(fifo->dataBufSize % config->blockSize == 0); assert(config->blockSize != 0); while(clst->endReached < 2) { struct slice *slice; pc_consume(clst->fec_data_pc, 1); pos = pc_getConsumerPosition(clst->fec_data_pc); slice = clst->fec_slices[pos]; pc_consumed(clst->fec_data_pc, 1); if(slice->state != SLICE_FEC && slice->state != SLICE_DONE) /* This can happen if a SLICE_DONE was enqueued after a SLICE_FEC: * the cleanup after SLICE_FEC also cleaned away the SLICE_DONE (in * main queue), and thus we will find it as SLICE_FREE in the * fec queue. Or worse receiving, or whatever if it made full * circle ... */ continue; if(slice->state == SLICE_FEC) { int stripes = slice->fec_stripes; struct fec_desc *fec_descs = slice->fec_descs; int stripe; /* Record the addresses of FEC blocks */ for(stripe=0; stripeblockSize != 0); fec_decode_one_stripe(clst, slice, stripe, slice->bytes, slice->fec_stripes, slice->fec_blocks[stripe], fec_descs); } slice->state = SLICE_FEC_DONE; for(stripe=0; stripemissing_data_blocks[stripe] >= slice->fec_blocks[stripe]); for(i=0; ifec_blocks[stripe]; i++) { freeBlockSpace(clst,fec_descs[stripe+i*stripes].adr); fec_descs[stripe+i*stripes].adr=0; } } } else if(slice->state == SLICE_DONE) { slice->state = SLICE_FEC_DONE; } assert(slice->state == SLICE_FEC_DONE); cleanupSlices(clst, SLICE_FEC_DONE); } return 0; } #ifdef BB_FEATURE_UDPCAST_FEC static void initClstForFec(struct clientState *clst) { clst->use_fec = 1; pthread_create(&clst->fec_thread, NULL, fecMain, clst); } #endif static void initSliceForFec(struct clientState *clst, struct slice *slice) { int i, j; int blocksInSlice; assert(slice->magic == SLICEMAGIC); #ifdef BB_FEATURE_UDPCAST_FEC /* make this client ready for fec */ if(!clst->use_fec) initClstForFec(clst); #endif /* is this slice ready ? */ assert(clst->net_config->blockSize != 0); blocksInSlice = (slice->bytes + clst->net_config->blockSize - 1) / clst->net_config->blockSize; for(i=0; ifec_stripes; i++) { slice->missing_data_blocks[i]=0; slice->fec_blocks[i]=0; } for(i=0; i< (blocksInSlice+7)/8 ; i++) { if(slice->retransmit.map[i] != 0xff) { int max = i*8+8; if(max > blocksInSlice) max = blocksInSlice; for(j=i*8; j < max; j++) if(!BIT_ISSET(j, slice->retransmit.map)) slice->missing_data_blocks[j % slice->fec_stripes]++; } } } static int processFecBlock(struct clientState *clst, int stripes, int sliceNo, int blockNo, int bytes) { struct slice *slice = findSlice(clst, sliceNo); unsigned char *shouldAddress, *isAddress; int stripe; struct fec_desc *desc; int adr; #if DEBUG flprintf("Handling FEC packet %d %d %d %d\n", stripes, sliceNo, blockNo, bytes); #endif assert(slice == NULL || slice->magic == SLICEMAGIC); if(slice == NULL || slice->state == SLICE_FREE || slice->state == SLICE_DONE || slice->state == SLICE_FEC) { /* an old slice. Ignore */ return 0; } shouldAddress = clst->nextBlock; isAddress = clst->data_hdr.msg_iov[1].iov_base; setSliceBytes(slice, clst, bytes); if(slice->fec_stripes == 0) { slice->fec_stripes = stripes; initSliceForFec(clst, slice); } else if(slice->fec_stripes != stripes) { udpc_flprintf("Interleave mismatch %d <-> %d", slice->fec_stripes, stripes); return 0; } stripe = blockNo % slice->fec_stripes; if(slice->missing_data_blocks[stripe] <= slice->fec_blocks[stripe]) { /* not useful */ /* FIXME: we should forget block here */ checkSliceComplete(clst, slice); advanceReceivedPointer(clst); #ifdef BB_FEATURE_UDPCAST_FEC if(!clst->use_fec) cleanupSlices(clst, SLICE_DONE); #endif return 0; } adr = slice->fec_blocks[stripe]*stripes+stripe; { int i; /* check for duplicates, in case of retransmission... */ for(i=stripe; ifec_descs[i]; if(desc->fecBlockNo == blockNo) { udpc_flprintf("**** duplicate block...\n"); return 0; } } } if(shouldAddress != isAddress) /* copy message to the correct place */ memcpy(shouldAddress, isAddress, clst->net_config->blockSize); desc = &slice->fec_descs[adr]; desc->adr = shouldAddress; desc->fecBlockNo = blockNo; slice->fec_blocks[stripe]++; slice->blocksTransferred++; setNextBlock(clst); slice->freePos = MAX_SLICE_SIZE; checkSliceComplete(clst, slice); advanceReceivedPointer(clst); return 0; } #endif static int processDataBlock(struct clientState *clst, int sliceNo, int blockNo, int bytes) { struct fifo *fifo = clst->fifo; struct slice *slice = findSlice(clst, sliceNo); unsigned char *shouldAddress, *isAddress; assert(slice == NULL || slice->magic == SLICEMAGIC); if(slice == NULL || slice->state == SLICE_FREE || slice->state == SLICE_DONE #ifdef BB_FEATURE_UDPCAST_FEC || slice->state == SLICE_FEC || slice->state == SLICE_FEC_DONE #endif ) { /* an old slice. Ignore */ return 0; } if(sliceNo > clst->currentSliceNo+2) udpc_fatal(1, "We have been dropped by sender\n"); if(BIT_ISSET(blockNo, slice->retransmit.map)) { /* we already have this packet, ignore */ #if 0 flprintf("Packet %d:%d not for us\n", sliceNo, blockNo); #endif return 0; } if(slice->base % clst->net_config->blockSize) { udpc_fatal(1, "Bad base %d, not multiple of block size %d\n", slice->base, clst->net_config->blockSize); } shouldAddress = ADR(blockNo, clst->net_config->blockSize); isAddress = clst->data_hdr.msg_iov[1].iov_base; if(shouldAddress != isAddress) { /* copy message to the correct place */ memcpy(shouldAddress, isAddress, clst->net_config->blockSize); } if(clst->client_config->sender_is_newgen && bytes != 0) setSliceBytes(slice, clst, bytes); if(clst->client_config->sender_is_newgen && bytes == 0) clst->netEndReached = 0; SET_BIT(blockNo, slice->retransmit.map); #ifdef BB_FEATURE_UDPCAST_FEC if(slice->fec_stripes) { int stripe = blockNo % slice->fec_stripes; slice->missing_data_blocks[stripe]--; assert(slice->missing_data_blocks[stripe] >= 0); if(slice->missing_data_blocks[stripe] < slice->fec_blocks[stripe]) { int blockIdx; /* FIXME: FEC block should be enqueued in local queue here...*/ slice->fec_blocks[stripe]--; blockIdx = stripe+slice->fec_blocks[stripe]*slice->fec_stripes; assert(slice->fec_descs[blockIdx].adr != 0); clst->localBlockAddresses[clst->localPos++] = slice->fec_descs[blockIdx].adr; slice->fec_descs[blockIdx].adr=0; slice->blocksTransferred--; } } #endif slice->dataBlocksTransferred++; slice->blocksTransferred++; while(slice->freePos < MAX_SLICE_SIZE && BIT_ISSET(slice->freePos, slice->retransmit.map)) slice->freePos++; checkSliceComplete(clst, slice); return 0; } static int processReqAck(struct clientState *clst, int sliceNo, int bytes, int rxmit) { struct slice *slice = findSlice(clst, sliceNo); int blocksInSlice; char *readySet = (char *) clst->data_hdr.msg_iov[1].iov_base; #if DEBUG flprintf("Received REQACK (sn=%d, rxmit=%d sz=%d) %d\n", sliceNo, rxmit, bytes, (slice - &clst->slices[0])); #endif assert(slice == NULL || slice->magic == SLICEMAGIC); { struct timeval tv; gettimeofday(&tv, 0); /* usleep(1); DEBUG: FIXME */ } if(BIT_ISSET(clst->client_config->clientNumber, readySet)) { /* not for us */ #if DEBUG flprintf("Not for us\n"); #endif return 0; } if(slice == NULL) { /* an old slice => send ok */ #if DEBUG flprintf("old slice => sending ok\n"); #endif return sendOk(clst->client_config, sliceNo); } setSliceBytes(slice, clst, bytes); assert(clst->net_config->blockSize != 0); blocksInSlice = (slice->bytes + clst->net_config->blockSize - 1) / clst->net_config->blockSize; if (blocksInSlice == slice->blocksTransferred) { /* send ok */ sendOk(clst->client_config, slice->sliceNo); } else { #if DEBUG flprintf("Ask for retransmission (%d/%d %d)\n", slice->blocksTransferred, blocksInSlice, bytes); #endif sendRetransmit(clst, slice, rxmit); } #if DEBUG flprintf("Received reqack %d %d\n", slice->sliceNo, bytes); #endif checkSliceComplete(clst, slice); /* needed for the final 0 sized slice */ advanceReceivedPointer(clst); #ifdef BB_FEATURE_UDPCAST_FEC if(!clst->use_fec) cleanupSlices(clst, SLICE_DONE); #endif return 0; } /** * Close all sockets except the named file descriptor and the slot 0 socket * The 0 should not be closed, because we use that for sending */ static void closeAllExcept(struct clientState *clst, int fd) { int i; int *socks = clst->client_config->socks; if(clst->selectedFd >= 0) return; restoreConsole(&clst->client_config->console, 0); clst->selectedFd = fd; for(i=1; ififo; int fd = -1; struct client_config *client_config = clst->client_config; /* set up message header */ if (clst->currentSlice != NULL && clst->currentSlice->freePos < MAX_SLICE_SIZE) { struct slice *slice = clst->currentSlice; assert(slice == NULL || slice->magic == SLICEMAGIC); clst->data_iov[1].iov_base = ADR(slice->freePos, clst->net_config->blockSize); } else { clst->data_iov[1].iov_base = clst->nextBlock; } clst->data_iov[1].iov_len = clst->net_config->blockSize; clst->data_hdr.msg_iovlen = 2; clst->data_hdr.msg_name = &lserver; clst->data_hdr.msg_namelen = sizeof(struct sockaddr_in); while(clst->endReached || clst->netEndReached) { int oldEndReached = clst->endReached; int nr_desc; struct timeval tv; fd_set read_set; int maxFd = prepareForSelect(client_config->socks, NR_CLIENT_SOCKS, &read_set); tv.tv_sec = clst->net_config->exitWait / 1000; tv.tv_usec = (clst->net_config->exitWait % 1000)*1000; nr_desc = select(maxFd, &read_set, 0, 0, &tv); if(nr_desc < 0) { flprintf("Select error: %s\n", strerror(errno)); break; } fd = getSelectedSock(client_config->socks, NR_CLIENT_SOCKS, &read_set); if(fd >= 0) break; /* Timeout expired */ if(oldEndReached >= 2) { clst->endReached = 3; return 0; } } if(fd < 0) fd = clst->selectedFd; if(fd < 0) { struct timeval tv, *tvp; fd_set read_set; int keyPressed = 0; int maxFd = prepareForSelect(client_config->socks, NR_CLIENT_SOCKS, &read_set); if(client_config->console && !clst->promptPrinted) #ifdef __MINGW32__ fprintf(stderr, "Press return to start receiving data!\n"); #else /* __MINGW32__ */ fprintf(stderr, "Press any key to start receiving data!\n"); #endif /* __MINGW32__ */ clst->promptPrinted=1; if(clst->net_config->startTimeout == 0) { tvp=NULL; } else { tv.tv_sec = clst->net_config->startTimeout; tv.tv_usec = 0; tvp = &tv; } ret = selectWithConsole(client_config->console, maxFd+1, &read_set, tvp, &keyPressed); if(ret < 0) { perror("Select"); return 0; } if(ret == 0) { clst->endReached=3; clst->netEndReached=3; pc_produceEnd(clst->fifo->data); return 1; } if(keyPressed) { /* Close our console and flush pending keystroke. * a restore console will be done later in closeAllExcept, but this * one is necessary to flush out buffered character */ restoreConsole(&client_config->console, 1); /* ... and send go signal */ udpc_flprintf("Sending go signal\n"); if(sendGo(client_config) < 0) perror("Send go"); return 0; /* Trigger next loop */ } fd = getSelectedSock(clst->client_config->socks, NR_CLIENT_SOCKS, &read_set); } #ifdef LOSSTEST loseRecvPacket(fd); ret=RecvMsg(fd, &clst->data_hdr, 0); #else ret=recvmsg(fd, &clst->data_hdr, #ifdef MSG_DONTWAIT clst->net_config->receiveTimeout ? MSG_DONTWAIT : #endif 0); #ifdef MSG_DONTWAIT if(ret < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) { struct timeval tv; fd_set read_set; int nr_desc; FD_ZERO(&read_set); FD_SET(fd, &read_set); tv.tv_sec = clst->net_config->receiveTimeout; tv.tv_usec = 0; nr_desc = select(fd+1, &read_set, 0, 0, &tv); if(nr_desc == 0) { flprintf("Receiver timeout\n"); exit(1); } ret = recvmsg(fd, &clst->data_hdr, MSG_DONTWAIT); } #endif #endif if (ret < 0) { #if DEBUG flprintf("data recvfrom %d: %s\n", fd, strerror(errno)); #endif return -1; } #if 0 flprintf("received packet for slice %d, block %d\n", ntohl(Msg.sliceNo), ntohs(db.blockNo)); #endif if(!udpc_isAddressEqual(&lserver, &clst->client_config->serverAddr)) { char buffer1[16], buffer2[16]; udpc_flprintf("Rogue packet received %s:%d, expecting %s:%d\n", udpc_getIpString(&lserver, buffer1), getPort(&lserver), udpc_getIpString(&clst->client_config->serverAddr, buffer2), udpc_getPort(&clst->client_config->serverAddr)); return -1; } switch(ntohs(clst->Msg.opCode)) { case CMD_DATA: closeAllExcept(clst, fd); udpc_receiverStatsStartTimer(clst->stats); clst->client_config->isStarted = 1; return processDataBlock(clst, ntohl(clst->Msg.dataBlock.sliceNo), ntohs(clst->Msg.dataBlock.blockNo), ntohl(clst->Msg.dataBlock.bytes)); #ifdef BB_FEATURE_UDPCAST_FEC case CMD_FEC: closeAllExcept(clst, fd); receiverStatsStartTimer(clst->stats); clst->client_config->isStarted = 1; return processFecBlock(clst, ntohs(clst->Msg.fecBlock.stripes), ntohl(clst->Msg.fecBlock.sliceNo), ntohs(clst->Msg.fecBlock.blockNo), ntohl(clst->Msg.fecBlock.bytes)); #endif case CMD_REQACK: closeAllExcept(clst, fd); receiverStatsStartTimer(clst->stats); clst->client_config->isStarted = 1; return processReqAck(clst, ntohl(clst->Msg.reqack.sliceNo), ntohl(clst->Msg.reqack.bytes), ntohl(clst->Msg.reqack.rxmit)); case CMD_HELLO_STREAMING: case CMD_HELLO_NEW: case CMD_HELLO: /* retransmission of hello to find other participants ==> ignore */ return 0; default: break; } udpc_flprintf("Unexpected opcode %04x\n", (unsigned short) clst->Msg.opCode); return -1; } static int setupMessages(struct clientState *clst) { /* the messages received from the server */ clst->data_iov[0].iov_base = (void *)&clst->Msg; clst->data_iov[0].iov_len = sizeof(clst->Msg); /* namelen set just before reception */ clst->data_hdr.msg_iov = clst->data_iov; /* iovlen set just before reception */ initMsgHdr(&clst->data_hdr); return 0; } static THREAD_RETURN netReceiverMain(void *args0) { struct clientState *clst = (struct clientState *) args0; clst->currentSliceNo = 0; setupMessages(clst); clst->currentSliceNo = -1; clst->currentSlice = NULL; clst->promptPrinted = 0; if(! (clst->net_config->flags & FLAG_STREAMING)) newSlice(clst, 0); else { clst->currentSlice = NULL; clst->currentSliceNo = 0; } while(clst->endReached < 3) { dispatchMessage(clst); } #ifdef BB_FEATURE_UDPCAST_FEC if(clst->use_fec) pthread_join(clst->fec_thread, NULL); #endif return 0; } int spawnNetReceiver(struct fifo *fifo, struct client_config *client_config, struct net_config *net_config, receiver_stats_t stats) { int i; struct clientState *clst = MALLOC(struct clientState); clst->fifo = fifo; clst->client_config = client_config; clst->net_config = net_config; clst->stats = stats; clst->endReached = 0; clst->netEndReached = 0; clst->selectedFd = -1; clst->free_slices_pc = pc_makeProduconsum(NR_SLICES, "free slices"); pc_produce(clst->free_slices_pc, NR_SLICES); for(i = 0; i slices[i].state = SLICE_FREE; clst->slices[i].sliceNo = -1; } clst->receivedPtr = 0; clst->receivedSliceNo = -1; #ifdef BB_FEATURE_UDPCAST_FEC fec_init(); /* fec new involves memory * allocation. Better do it here */ clst->use_fec = 0; clst->fec_data_pc = pc_makeProduconsum(NR_SLICES, "fec data"); #endif #define NR_BLOCKS 4096 clst->freeBlocks_pc = pc_makeProduconsum(NR_BLOCKS, "free blocks"); pc_produce(clst->freeBlocks_pc, NR_BLOCKS); clst->blockAddresses = calloc(NR_BLOCKS, sizeof(char *)); clst->localBlockAddresses = calloc(NR_BLOCKS, sizeof(char *)); clst->blockData = xmalloc(NR_BLOCKS * net_config->blockSize); for(i = 0; i < NR_BLOCKS; i++) clst->blockAddresses[i] = clst->blockData + i * net_config->blockSize; clst->localPos=0; setNextBlock(clst); return pthread_create(&client_config->thread, NULL, netReceiverMain, clst); } udpcast-20120424/udps-negotiate.c0000444000175000017500000003570111606253376015460 0ustar alainalain#include #include #include #include #include #include #include "log.h" #include "fifo.h" #include "socklib.h" #include "udpcast.h" #include "udpc-protoc.h" #include "udp-sender.h" #include "participants.h" #include "statistics.h" #include "console.h" #ifdef USE_SYSLOG #include #endif /** * This file contains the code to set up the connection */ static int doTransfer(int sock, participantsDb_t db, struct disk_config *disk_config, struct net_config *net_config, struct stat_config *stat_config); static int isPointToPoint(participantsDb_t db, int flags) { if(flags & FLAG_POINTOPOINT) return 1; if(flags & (FLAG_NOPOINTOPOINT | FLAG_ASYNC)) return 0; return udpc_nrParticipants(db) == 1; } static int sendConnectionReply(participantsDb_t db, int sock, struct net_config *config, struct sockaddr_in *client, int capabilities, unsigned int rcvbuf) { struct connectReply reply; if(rcvbuf == 0) rcvbuf = 65536; if(capabilities & CAP_BIG_ENDIAN) { reply.opCode = htons(CMD_CONNECT_REPLY); reply.clNr = htonl(udpc_addParticipant(db, client, capabilities, rcvbuf, config->flags & FLAG_POINTOPOINT)); reply.blockSize = htonl(config->blockSize); } else { udpc_fatal(1, "Little endian protocol no longer supported"); } reply.reserved = 0; if(config->flags & FLAG_POINTOPOINT) { copyIpFrom(&config->dataMcastAddr, client); } /* new parameters: always big endian */ reply.capabilities = ntohl(config->capabilities); copyToMessage(reply.mcastAddr,&config->dataMcastAddr); /*reply.mcastAddress = mcastAddress;*/ rgWaitAll(config, sock, client->sin_addr.s_addr, sizeof(reply)); if(SEND(sock, reply, *client) < 0) { perror("reply add new client"); return -1; } return 0; } void sendHello(struct net_config *net_config, int sock, int streaming) { struct hello hello; /* send hello message */ if(streaming) hello.opCode = htons(CMD_HELLO_STREAMING); else hello.opCode = htons(CMD_HELLO); hello.reserved = 0; hello.capabilities = htonl(net_config->capabilities); copyToMessage(hello.mcastAddr,&net_config->dataMcastAddr); hello.blockSize = htons(net_config->blockSize); rgWaitAll(net_config, sock, net_config->controlMcastAddr.sin_addr.s_addr, sizeof(hello)); BCAST_CONTROL(sock, hello); } /* Returns 1 if we should start because of clientWait, 0 otherwise */ static int checkClientWait(participantsDb_t db, struct net_config *net_config, time_t *firstConnected) { time_t now; if (!nrParticipants(db) || !firstConnected || !*firstConnected) return 0; /* do not start: no receivers */ now = time(0); /* * If we have a max_client_wait, start the transfer after first client * connected + maxSendWait */ if(net_config->max_receivers_wait && (now >= *firstConnected + net_config->max_receivers_wait)) { #ifdef USE_SYSLOG syslog(LOG_INFO, "max wait[%d] passed: starting", net_config->max_receivers_wait ); #endif return 1; /* send-wait passed: start */ } /* * Otherwise check to see if the minimum of clients * have checked in. */ else if (nrParticipants(db) >= net_config->min_receivers && /* * If there are enough clients and there's a min wait time, we'll * wait around anyway until then. * Otherwise, we always transfer */ (!net_config->min_receivers_wait || now >= *firstConnected + net_config->min_receivers_wait)) { #ifdef USE_SYSLOG syslog(LOG_INFO, "min receivers[%d] reached: starting", net_config->min_receivers ); #endif return 1; } else return 0; } /* ***************************************************** * Receive and process a localization enquiry by a client * Params: * fd - file descriptor for network socket on which to receiver * client requests * db - participant database * disk_config - disk configuration * net_config - network configuration * keyboardFd - keyboard filedescriptor (-1 if keyboard inaccessible, * or configured away) * tries - how many hello messages have been sent? * firstConnected - when did the first client connect? */ static int mainDispatcher(int *fd, int nr, participantsDb_t db, struct net_config *net_config, console_t **console, int *tries, time_t *firstConnected) { struct sockaddr_in client; union message fromClient; fd_set read_set; int ret; int msgLength; int startNow=0; int selected; int keyPressed=0; long loopStart = time(0); if ((udpc_nrParticipants(db) || (net_config->flags & FLAG_ASYNC)) && !(net_config->flags & FLAG_NOKBD) && *console != NULL) #ifdef __MINGW32__ fprintf(stderr, "Ready. Press return to start sending data.\n"); #else /* __MINGW32__ */ fprintf(stderr, "Ready. Press any key to start sending data.\n"); #endif /* __MINGW32__ */ if (firstConnected && !*firstConnected && udpc_nrParticipants(db)) { *firstConnected = time(0); #ifdef USE_SYSLOG syslog(LOG_INFO, "first connection: min wait[%d] secs - max wait[%d] - min clients[%d]", net_config->min_receivers_wait, net_config->max_receivers_wait, net_config->min_receivers ); #endif } while(!startNow) { struct timeval tv; struct timeval *tvp; int nr_desc; int maxFd = prepareForSelect(fd, nr, &read_set); if(net_config->rexmit_hello_interval) { tv.tv_usec = (net_config->rexmit_hello_interval % 1000)*1000; tv.tv_sec = net_config->rexmit_hello_interval / 1000; tvp = &tv; } else if((firstConnected && nrParticipants(db)) || net_config->startTimeout) { tv.tv_usec = 0; tv.tv_sec = 2; tvp = &tv; } else tvp = 0; nr_desc = selectWithConsole(*console, maxFd+1, &read_set, tvp, &keyPressed); if(nr_desc < 0) { perror("select"); return -1; } if(nr_desc > 0 || keyPressed) /* key pressed, or receiver activity */ break; if(net_config->rexmit_hello_interval) { /* retransmit hello message */ sendHello(net_config, fd[0], 0); (*tries)++; if(net_config->autostart != 0 && *tries > net_config->autostart) startNow=1; } if(firstConnected) startNow = startNow || checkClientWait(db, net_config, firstConnected); if(!startNow && net_config->startTimeout && time(0) - loopStart >= net_config->startTimeout) { startNow = -1; break; } } if(keyPressed) { restoreConsole(console,1); startNow = 1; } selected = getSelectedSock(fd, nr, &read_set); if(selected == -1) return startNow; BZERO(fromClient); /* Zero it out in order to cope with short messages * from older versions */ msgLength = RECV(selected, fromClient, client, net_config->portBase); if(msgLength < 0) { perror("problem getting data from client"); return 0; /* don't panic if we get weird messages */ } if(net_config->flags & FLAG_ASYNC) return 0; switch(ntohs(fromClient.opCode)) { case CMD_CONNECT_REQ: sendConnectionReply(db, fd[0], net_config, &client, CAP_BIG_ENDIAN | ntohl(fromClient.connectReq.capabilities), ntohl(fromClient.connectReq.rcvbuf)); return startNow; case CMD_GO: return 1; case CMD_DISCONNECT: ret = udpc_lookupParticipant(db, &client); if (ret >= 0) udpc_removeParticipant(db, ret); return startNow; default: break; } udpc_flprintf("Unexpected command %04x\n", (unsigned short) fromClient.opCode); return startNow; } int udpc_openMainSenderSock(struct net_config *net_config, const char *ifName) { net_config->net_if = getNetIf(ifName); return makeSocket(ADDR_TYPE_UCAST, net_config->net_if, NULL, SENDER_PORT(net_config->portBase)); } int startSender(struct disk_config *disk_config, struct net_config *net_config, struct stat_config *stat_config, int mainSock) { char ipBuffer[16]; int tries; int r; /* return value for maindispatch. If 1, start transfer */ int j; time_t firstConnected = 0; time_t *firstConnectedP; console_t *console=NULL; participantsDb_t db; /* make the socket and print banner */ int sock[3]; int nr=0; int fd; #ifdef SIG_BLOCK /* signal sets */ sigset_t sig, oldsig; int shouldRestoreSig; #endif sock[nr++] = mainSock; if(! (net_config->flags & (FLAG_SN | FLAG_NOTSN)) ) { if(isFullDuplex(sock[0], net_config->net_if->name) == 1) { fprintf(stderr, "Using full duplex mode\n"); net_config->flags |= FLAG_SN; } } fd = makeSocket(ADDR_TYPE_BCAST, net_config->net_if, NULL, SENDER_PORT(net_config->portBase)); if(fd >= 0) sock[nr++] = fd; if(net_config->requestedBufSize) setSendBuf(sock[0], net_config->requestedBufSize); net_config->controlMcastAddr.sin_addr.s_addr =0; if(net_config->ttl == 1 && net_config->mcastRdv == NULL) { getBroadCastAddress(net_config->net_if, &net_config->controlMcastAddr, RECEIVER_PORT(net_config->portBase)); setSocketToBroadcast(sock[0]); } if(net_config->controlMcastAddr.sin_addr.s_addr == 0) { getMcastAllAddress(&net_config->controlMcastAddr, net_config->mcastRdv, RECEIVER_PORT(net_config->portBase)); /* Only do the following if controlMcastAddr is indeed an mcast address ... */ if(isMcastAddress(&net_config->controlMcastAddr)) { setMcastDestination(sock[0], net_config->net_if, &net_config->controlMcastAddr); setTtl(sock[0], net_config->ttl); sock[nr++] = makeSocket(ADDR_TYPE_MCAST, net_config->net_if, &net_config->controlMcastAddr, SENDER_PORT(net_config->portBase)); } } if(!(net_config->flags & FLAG_POINTOPOINT) && ipIsZero(&net_config->dataMcastAddr)) { getDefaultMcastAddress(net_config->net_if, &net_config->dataMcastAddr); udpc_flprintf("Using mcast address %s\n", getIpString(&net_config->dataMcastAddr, ipBuffer)); } if(net_config->flags & FLAG_POINTOPOINT) { clearIp(&net_config->dataMcastAddr); } setPort(&net_config->dataMcastAddr, RECEIVER_PORT(net_config->portBase)); udpc_flprintf("%sUDP sender for %s at ", disk_config->pipeName == NULL ? "" : "Compressed ", disk_config->fileName == NULL ? "(stdin)" : disk_config->fileName); printMyIp(net_config->net_if); udpc_flprintf(" on %s \n", net_config->net_if->name); udpc_flprintf("Broadcasting control to %s\n", getIpString(&net_config->controlMcastAddr, ipBuffer)); net_config->capabilities = SENDER_CAPABILITIES; if(net_config->flags & FLAG_ASYNC) net_config->capabilities |= CAP_ASYNC; sendHello(net_config, sock[0], 0); db = udpc_makeParticipantsDb(); tries = 0; if(!(net_config->flags & FLAG_NOKBD)) console = prepareConsole((disk_config->fileName != NULL) ? 0 : -1); if(net_config->min_receivers || net_config->min_receivers_wait || net_config->max_receivers_wait) firstConnectedP = &firstConnected; else firstConnectedP = NULL; while(!(r=mainDispatcher(sock, nr, db, net_config, &console,&tries,firstConnectedP))){} for(j=1; jflags & FLAG_ASYNC) || udpc_nrParticipants(db) > 0) doTransfer(sock[0], db, disk_config, net_config, stat_config); else fprintf(stderr, "No participants... exiting\n"); } free(db); #ifdef SIG_BLOCK if(shouldRestoreSig) sigprocmask(SIG_SETMASK, &oldsig, NULL); #endif return 0; } /* * Do the actual data transfer */ static int doTransfer(int sock, participantsDb_t db, struct disk_config *disk_config, struct net_config *net_config, struct stat_config *stat_config) { int i; struct fifo fifo; sender_stats_t stats; int in; int origIn; int pid; int isPtP = isPointToPoint(db, net_config->flags); int printUncompressedPos; if((net_config->flags & FLAG_POINTOPOINT) && udpc_nrParticipants(db) != 1) { udpc_fatal(1, "pointopoint mode set, and %d participants instead of 1\n", udpc_nrParticipants(db)); } net_config->rcvbuf=0; for(i=0; idataMcastAddr, udpc_getParticipantIp(db,i)); net_config->capabilities &= udpc_getParticipantCapabilities(db, i); if(pRcvBuf != 0 && (net_config->rcvbuf == 0 || net_config->rcvbuf > pRcvBuf)) net_config->rcvbuf = pRcvBuf; } if(isMcastAddress(&net_config->dataMcastAddr)) setMcastDestination(sock, net_config->net_if, &net_config->dataMcastAddr); udpc_flprintf("Starting transfer: %08x\n", net_config->capabilities); #ifdef USE_SYSLOG syslog(LOG_INFO, "Starting transfer: file[%s] pipe[%s] port[%d] if[%s] participants[%d]", disk_config->fileName == NULL ? "" : disk_config->fileName, disk_config->pipeName == NULL ? "" : disk_config->pipeName, net_config->portBase, net_config->net_if->name == NULL ? "" : net_config->net_if->name, udpc_nrParticipants(db) ); #endif if(! (net_config->capabilities & CAP_BIG_ENDIAN)) udpc_fatal(1, "Peer with incompatible endianness"); if(! (net_config->capabilities & CAP_NEW_GEN)) { net_config->dataMcastAddr = net_config->controlMcastAddr; net_config->flags &= ~(FLAG_SN | FLAG_ASYNC); } if(net_config->flags & FLAG_BCAST) net_config->dataMcastAddr = net_config->controlMcastAddr; origIn = openFile(disk_config); in = openPipe(disk_config, origIn, &pid); printUncompressedPos = udpc_shouldPrintUncompressedPos(stat_config->printUncompressedPos, origIn, in); stats = allocSenderStats(origIn, stat_config->log, stat_config->bwPeriod, stat_config->statPeriod, printUncompressedPos, stat_config->noProgress); udpc_initFifo(&fifo, net_config->blockSize); spawnNetSender(&fifo, sock, net_config, db, stats); localReader(&fifo, in); close(in); /* if we have a pipe, now wait for that too */ if(pid) { udpc_waitForProcess(pid, "Pipe"); } pthread_join(fifo.thread, NULL); displaySenderStats(stats, net_config->blockSize, net_config->sliceSize, 1); /* This has to be done last, or else the final sender stats will not be able to print uncompressed position */ if(in != origIn) close(origIn); udpc_flprintf("Transfer complete.\007\n"); #ifdef USE_SYSLOG syslog(LOG_INFO, "Transfer complete."); #endif /* remove all participants */ for(i=0; i < MAX_CLIENTS; i++) { udpc_removeParticipant(db, i); } udpc_flprintf("\n"); return 0; } udpcast-20120424/statistics.h0000444000175000017500000000256211606052553014720 0ustar alainalain#ifndef STATISTICS_H #define STATISTICS_H typedef struct receiver_stats *receiver_stats_t; typedef struct sender_stats *sender_stats_t; #define allocReadStats udpc_allocReadStats #define receiverStatsStartTimer udpc_receiverStatsStartTimer #define receiverStatsAddBytes udpc_receiverStatsAddBytes #define displayReceiverStats udpc_displayReceiverStats receiver_stats_t udpc_allocReadStats(int fd, long statPeriod, int printUncompressedPos, int noProgress); void udpc_receiverStatsStartTimer(receiver_stats_t); void udpc_receiverStatsAddBytes(receiver_stats_t, long bytes); void udpc_displayReceiverStats(receiver_stats_t, int isFinal); #define allocSenderStats udpc_allocSenderStats #define senderStatsAddBytes udpc_senderStatsAddBytes #define senderStatsAddRetransmissions udpc_senderStatsAddRetransmissions #define displaySenderStats udpc_displaySenderStats #define senderSetAnswered udpc_senderSetAnswered sender_stats_t udpc_allocSenderStats(int fd, FILE *logfile, long bwPeriod, long statPeriod, int printUncompressedPos, int noProgress); void udpc_senderStatsAddBytes(sender_stats_t, long bytes); void udpc_senderStatsAddRetransmissions(sender_stats_t ss, int retransmissions); void udpc_displaySenderStats(sender_stats_t,int blockSize, int sliceSize, int isFinal); void udpc_senderSetAnswered(sender_stats_t ss, int clNo); #endif udpcast-20120424/fifo.h0000444000175000017500000000066310407537665013463 0ustar alainalain#ifndef FIFO_H #define FIFO_H #include "threads.h" #include "produconsum.h" typedef struct fifo { unsigned char *dataBuffer; unsigned int dataBufSize; produconsum_t freeMemQueue; /* queue for free memory */ produconsum_t data; /* queue for received data or data received * from disk */ pthread_t thread; } *fifo_t; #define initFifo udpc_initFifo void initFifo(struct fifo *fifo, int blockSize); #endif udpcast-20120424/udpc-protoc.h0000444000175000017500000001033411247052242014755 0ustar alainalain#ifndef UDPC_PROTOC_H #define UDPC_PROTOC_H #include "udpcast.h" #define MAX_BLOCK_SIZE 1456 #define MAX_FEC_INTERLEAVE 256 /** * This file describes the UDPCast protocol */ enum opCode { /* Receiver to sender */ CMD_OK, /* all is ok, no need to retransmit anything */ CMD_RETRANSMIT, /* receiver asks for some data to be retransmitted */ CMD_GO, /* receiver tells server to start */ CMD_CONNECT_REQ, /* receiver tries to find out server's address */ CMD_DISCONNECT, /* receiver wants to disconnect itself */ CMD_UNUSED, /* obsolete version of CMD_HELLO, dating back to the * time when we had little endianness (PC). This * opcode contained a long unnoticed bug with parsing of * blocksize */ /* Sender to receiver */ CMD_REQACK, /* server request acknowledgments from receiver */ CMD_CONNECT_REPLY, /* receiver tries to find out server's address */ CMD_DATA, /* a block of data */ CMD_FEC, /* a forward-error-correction block */ CMD_HELLO_NEW, /* sender says he's up */ CMD_HELLO_STREAMING, /* retransmitted hello during streaming mode */ }; /* Sender says he's up. This is not in the enum with the others, * because of some endianness Snafu in early versions. However,since * 2005-12-23, new receivers now understand a CMD_HELLO_NEW which is * in sequence. Once enough of those are out in the field, we'll send * CMD_HELLO_NEW by default, and then phase out the old variant. */ /* Tried to remove this on 2009-08-30, but noticed that receiver was printing * "unexpected opcode" on retransmitted hello */ #define CMD_HELLO 0x0500 union message { unsigned short opCode; struct ok { unsigned short opCode; short reserved; int sliceNo; } ok; struct retransmit { unsigned short opCode; short reserved; int sliceNo; int rxmit; unsigned char map[MAX_SLICE_SIZE / BITS_PER_CHAR]; } retransmit; struct connectReq { unsigned short opCode; short reserved; int capabilities; unsigned int rcvbuf; } connectReq; struct go { unsigned short opCode; short reserved; } go; struct disconnect { unsigned short opCode; short reserved; } disconnect; }; struct connectReply { unsigned short opCode; short reserved; int clNr; int blockSize; int capabilities; unsigned char mcastAddr[16]; /* provide enough place for IPV6 */ }; struct hello { unsigned short opCode; short reserved; int capabilities; unsigned char mcastAddr[16]; /* provide enough place for IPV6 */ short blockSize; }; union serverControlMsg { unsigned short opCode; short reserved; struct hello hello; struct connectReply connectReply; }; struct dataBlock { unsigned short opCode; short reserved; int sliceNo; unsigned short blockNo; unsigned short reserved2; int bytes; }; struct fecBlock { unsigned short opCode; short stripes; int sliceNo; unsigned short blockNo; unsigned short reserved2; int bytes; }; struct reqack { unsigned short opCode; short reserved; int sliceNo; int bytes; int rxmit; }; union serverDataMsg { unsigned short opCode; struct reqack reqack; struct dataBlock dataBlock; struct fecBlock fecBlock; }; /* ============================================ * Capabilities */ /* Does the receiver support the new CMD_DATA command, which carries * capabilities mask? * "new generation" receiver: * - capabilities word included in hello/connectReq commands * - receiver multicast capable * - receiver can receive ASYNC and SN */ #define CAP_NEW_GEN 0x0001 /* Use multicast instead of Broadcast for data */ /*#define CAP_MULTICAST 0x0002*/ #ifdef BB_FEATURE_UDPCAST_FEC /* Forward error correction */ #define CAP_FEC 0x0004 #endif /* Supports big endians (a.k.a. network) */ #define CAP_BIG_ENDIAN 0x0008 /* Support little endians (a.k.a. PC) ==> obsolete! */ #define CAP_LITTLE_ENDIAN 0x0010 /* This transmission is asynchronous (no receiver reply) */ #define CAP_ASYNC 0x0020 /* Sender currently supports CAPABILITIES and MULTICAST */ #define SENDER_CAPABILITIES ( \ CAP_NEW_GEN | \ CAP_BIG_ENDIAN) #define RECEIVER_CAPABILITIES ( \ CAP_NEW_GEN | \ CAP_BIG_ENDIAN) #endif udpcast-20120424/udp-sender.c0000444000175000017500000003771211606141656014577 0ustar alainalain#ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #include #include #include #include #include #include #include "log.h" #include "socklib.h" #include "udpcast.h" #include "udp-sender.h" #include "udpc_version.h" #include "rateGovernor.h" #include "rate-limit.h" #include "auto-rate.h" #ifdef HAVE_GETOPT_H #include #endif #ifdef USE_SYSLOG #include #endif #ifdef HAVE_STRING_H #include #endif #ifdef BB_FEATURE_UDPCAST_FEC #include "fec.h" #endif #if defined HAVE_DLSYM && defined NO_BB #define DL_RATE_GOVERNOR #endif #ifdef HAVE_GETOPT_LONG static struct option options[] = { { "file", 1, NULL, 'f' }, { "half-duplex", 0, NULL, 'c' }, { "full-duplex", 0, NULL, 'd' }, { "pipe", 1, NULL, 'p' }, { "port", 1, NULL, 'P' }, { "portbase", 1, NULL, 'P' }, { "blocksize", 1, NULL, 'b' }, { "interface", 1, NULL, 'i' }, { "mcast_address", 1, NULL, 'm' }, /* Obsolete name */ { "mcast-address", 1, NULL, 'm' }, /* Obsolete name */ { "mcast_data_address", 1, NULL, 'm' }, { "mcast-data-address", 1, NULL, 'm' }, { "mcast_all_address", 1, NULL, 'M' }, /* Obsolete name */ { "mcast-all-address", 1, NULL, 'M' }, /* Obsolete name */ { "mcast_rdv_address", 1, NULL, 'M' }, { "mcast-rdv-address", 1, NULL, 'M' }, { "max_bitrate", 1, NULL, 'r' }, { "max-bitrate", 1, NULL, 'r' }, { "point-to-point", 0, NULL, '1' }, { "point_to_point", 0, NULL, '1' }, { "pointopoint", 0, NULL, '1' }, { "nopoint-to-point", 0, NULL, '2' }, { "nopoint_to_point", 0, NULL, '2' }, { "nopointopoint", 0, NULL, '2' }, { "async", 0, NULL, 'a' }, #ifdef FLAG_AUTORATE { "autorate", 0, NULL, 'A' }, #endif { "log", 1, NULL, 'l' }, { "no-progress", 0, NULL, 0x701 }, /* slice size configuration */ { "min-slice-size", 1, NULL, 0x0101 }, { "default-slice-size", 1, NULL, 0x0102 }, { "slice-size", 1, NULL, 0x0102 }, { "max-slice-size", 1, NULL, 0x0103 }, { "ttl", 1, NULL, 't' }, #ifdef BB_FEATURE_UDPCAST_FEC { "fec", 1, NULL, 'F' }, { "license", 0, NULL, 'L' }, #endif #ifdef LOSSTEST /* simulating packet loss */ { "write-loss", 1, NULL, 0x601 }, { "read-loss", 1, NULL, 0x602 }, { "seed", 1, NULL, 0x603 }, { "print-seed", 0, NULL, 0x604 }, #endif { "rexmit-hello-interval", 1, NULL, 'H' }, { "autostart", 1, NULL, 'S' }, { "broadcast", 0, NULL, 'B' }, { "sendbuf", 1, NULL, 's' }, { "min-clients", 1, NULL, 'C' }, /* Obsolete name */ { "min-receivers", 1, NULL, 'C' }, { "max-wait", 1, NULL, 'W' }, { "min-wait", 1, NULL, 'w' }, { "nokbd", 0, NULL, 'k' }, { "start-timeout", 1, NULL, 'T' }, { "retriesUntilDrop", 1, NULL, 'R' }, /* Obsolete name */ { "retries-until-drop", 1, NULL, 'R' }, { "daemon-mode", 0, NULL, 'D'}, { "pid-file", 1, NULL, 0x901 }, #ifdef HAVE_KILL { "kill", 0, NULL, 'K' }, #endif { "bw-period", 1, NULL, 'I'}, #ifdef DL_RATE_GOVERNOR { "rate-governor", 1, NULL, 'g'}, #endif { "print-uncompressed-position", 1, NULL, 'x' }, { "statistics-period", 1, NULL, 'z' }, { "stat-period", 1, NULL, 'z' }, { "streaming", 0, NULL, 'Z' }, { "rehello-offset", 0, NULL, 'Y' }, { NULL, 0, NULL, 0} }; # define getopt_l(c,v,o) getopt_long(c, v, o, options, NULL) #else /* HAVE_GETOPT_LONG */ # define getopt_l(c,v,o) getopt(c, v, o) #endif /* HAVE_GETOPT_LONG */ #ifdef NO_BB static void usage(char *progname) { #ifdef HAVE_GETOPT_LONG fprintf(stderr, "%s [--file file] [--full-duplex] [--pipe pipe] [--portbase portbase] [--blocksize size] [--interface net-interface] [--mcast-data-address data-mcast-address] [--mcast-rdv-address mcast-rdv-address] [--max-bitrate bitrate] [--pointopoint] [--async] [--log file] [--no-progress] [--min-slice-size min] [--max-slice-size max] [--slice-size] [--ttl time-to-live] [--fec x/] [--print-seed] [--rexmit-hello-interval interval] [--autostart autostart] [--broadcast] [--min-receivers receivers] [--min-wait sec] [--max-wait sec] [--start-timeout n] [--retries-until-drop n] [--nokbd] [--bw-period n] [--streaming] [--rehello-offset offs]" #ifdef DL_RATE_GOVERNOR " [--rate-governor module:parameters]" #endif #ifdef FLAG_AUTORATE " [--autorate]" #endif "[--license]\n", progname); /* FIXME: copy new options to busybox */ #else /* HAVE_GETOPT_LONG */ fprintf(stderr, "%s [-f file] [-d] [-p pipe] [-P portbase] [-b size] [-i net-interface] [-m data-mcast-address] [-M mcast-rdv-address] [-r bitrate] [-1] [-a] [-l logfile] [-t time-to-live] [-F x/][-H hello-retransmit-interval] [-S autostart] [-B] [-C min-receivers] [-w min-wait-sec] [-w max-wait-sec] [-T start-timeout] [-R n] [-k] [-I n] [-x uncomprStatPrint] [-z statPeriod] [-Z] [-Y rehello-offset]" #ifdef DL_RATE_GOVERNOR " [-g rate-governor:parameters ]" #endif #ifdef FLAG_AUTORATE " [-A]" #endif " [-L]\n", progname); /* FIXME: copy new options to busybox */ #endif /* HAVE_GETOPT_LONG */ exit(1); } #else static inline void usage(char *progname) { (void) progname; /* shut up warning while compiling busybox... */ bb_show_usage(); } #endif static const char *pidfile = NULL; #ifdef HAVE_DAEMON static void cleanPidfile(int nr UNUSED) { unlink(pidfile); signal(SIGTERM, SIG_DFL); raise(SIGTERM); } #endif #ifndef NO_BB int udp_sender_main(int argc, char **argv); int udp_sender_main(int argc, char **argv) #else int main(int argc, char **argv) #endif { int c; char *ptr; #ifdef LOSSTEST int seedSet = 0; int printSeed = 0; #endif int daemon_mode = 0; int doKill = 0; int r; struct net_config net_config; struct disk_config disk_config; struct stat_config stat_config; char *ifName = NULL; int dataMcastSupplied = 0; int mainSock; /* argument parsing */ disk_config.fileName = NULL; disk_config.pipeName = NULL; disk_config.flags = 0; clearIp(&net_config.dataMcastAddr); net_config.mcastRdv = NULL; net_config.blockSize = 1456; net_config.sliceSize = 16; net_config.portBase = 9000; net_config.nrGovernors = 0; net_config.flags = 0; net_config.capabilities = 0; net_config.min_slice_size = 16; net_config.max_slice_size = 1024; net_config.default_slice_size = 0; net_config.ttl = 1; net_config.rexmit_hello_interval = 0; net_config.autostart = 0; net_config.requestedBufSize = 0; net_config.min_receivers=0; net_config.max_receivers_wait=0; net_config.min_receivers_wait=0; net_config.startTimeout=0; net_config.retriesUntilDrop = 200; net_config.rehelloOffset = 50; stat_config.log = NULL; stat_config.bwPeriod = 0; stat_config.printUncompressedPos = -1; stat_config.statPeriod = DEFLT_STAT_PERIOD; stat_config.noProgress = 0; ptr = strrchr(argv[0], '/'); if(!ptr) ptr = argv[0]; else ptr++; net_config.net_if = NULL; if (strcmp(ptr, "init") == 0) { disk_config.pipeName = strdup("/bin/gzip -c"); disk_config.fileName = "/dev/hda"; } else { const char *argLetters = "b:C:f:F:" #ifdef DL_RATE_GOVERNOR "g:" #endif "H:i:I:" #ifdef HAVE_KILL "K" #endif "l:m:M:p:P:r:R:s:S:t:T:w:W:x:z:12a" #ifdef FLAG_AUTORATE "A" #endif "BcdDkLY:Z"; while( (c=getopt_l(argc, argv, argLetters)) != EOF ) { switch(c) { case 'a': net_config.flags |= FLAG_ASYNC|FLAG_SN; break; case 'c': net_config.flags &= ~FLAG_SN; net_config.flags |= FLAG_NOTSN; break; case 'd': net_config.flags |= FLAG_SN; break; case 'f': disk_config.fileName=optarg; break; case 'i': ifName=optarg; break; case 'p': disk_config.pipeName=optarg; break; case 'P': net_config.portBase = atoi(optarg); break; case '1': net_config.flags |= FLAG_POINTOPOINT; break; case '2': net_config.flags |= FLAG_NOPOINTOPOINT; break; case 'b': net_config.blockSize = strtoul(optarg, 0, 0); net_config.blockSize -= net_config.blockSize % 4; if (net_config.blockSize <= 0) { perror("block size too small"); exit(1); } #if 0 if (net_config.blockSize > 1456) { perror("block size too large"); exit(1); } #endif break; case 'l': stat_config.log = udpc_log = fopen(optarg, "a"); break; case 0x701: stat_config.noProgress = 1; break; case 'm': setIpFromString(&net_config.dataMcastAddr, optarg); ipIsZero(&net_config.dataMcastAddr); dataMcastSupplied = 1; break; case 'M': net_config.mcastRdv = strdup(optarg); break; case 'r': { void *gov = rgInitGovernor(&net_config, &maxBitrate); maxBitrate.rgSetProp(gov, MAX_BITRATE, optarg); } break; case 'A': #ifdef FLAG_AUTORATE rgInitGovernor(&net_config, &autoRate); #else fatal(1, "Auto rate limit not supported on this platform\n"); #endif break; case 0x0101: net_config.min_slice_size = atoi(optarg); if(net_config.min_slice_size > MAX_SLICE_SIZE) fatal(1, "min slice size too big\n"); break; case 0x0102: net_config.default_slice_size = atoi(optarg); break; case 0x0103: net_config.max_slice_size = atoi(optarg); if(net_config.max_slice_size > MAX_SLICE_SIZE) fatal(1, "max slice size too big\n"); break; case 't': /* ttl */ net_config.ttl = atoi(optarg); break; #ifdef BB_FEATURE_UDPCAST_FEC case 'F': /* fec */ net_config.flags |= FLAG_FEC; { char *eptr; ptr = strchr(optarg, 'x'); if(ptr) { net_config.fec_stripes = strtoul(optarg, &eptr, 10); if(ptr != eptr) { flprintf("%s != %s\n", ptr, eptr); usage(argv[0]); } ptr++; } else { net_config.fec_stripes = 8; ptr = optarg; } net_config.fec_redundancy = strtoul(ptr, &eptr, 10); if(*eptr == '/') { ptr = eptr+1; net_config.fec_stripesize = strtoul(ptr, &eptr, 10); } else { net_config.fec_stripesize = 128; } if(*eptr) { flprintf("string not at end %s\n", eptr); usage(argv[0]); } fprintf(stderr, "stripes=%d redund=%d stripesize=%d\n", net_config.fec_stripes, net_config.fec_redundancy, net_config.fec_stripesize); } break; case 'z': stat_config.statPeriod = atoi(optarg) * 1000; break; case 'x': stat_config.printUncompressedPos = atoi(optarg); break; case 'L': fec_license(); break; #endif #ifdef LOSSTEST case 0x601: setWriteLoss(optarg); break; case 0x602: setReadLoss(optarg); break; case 0x603: seedSet=1; srandom(strtoul(optarg,0,0)); break; case 0x604: printSeed=1; break; #endif case 'H': /* rexmit-hello-interval */ net_config.rexmit_hello_interval = atoi(optarg); break; case 'S': /* autostart */ net_config.autostart = atoi(optarg); break; case 'B': /* broadcast */ net_config.flags |= FLAG_BCAST; break; case 's': /* sendbuf */ net_config.requestedBufSize=parseSize(optarg); break; case 'C': /* min-clients */ net_config.min_receivers = atoi(optarg); break; case 'W': /* max-wait */ net_config.max_receivers_wait = atoi(optarg); break; case 'w': /* min-wait */ net_config.min_receivers_wait = atoi(optarg); break; case 'T': /* start timeout */ net_config.startTimeout = atoi(optarg); break; case 'k': /* nokbd */ net_config.flags |= FLAG_NOKBD; break; case 'R': /* retries-until-drop */ net_config.retriesUntilDrop = atoi(optarg); break; case 'D': /* daemon-mode */ daemon_mode++; break; case 'K': doKill = 1; break; case 0x901: pidfile = optarg; break; case 'I': /* bw-period */ stat_config.bwPeriod = atol(optarg); break; #ifdef DL_RATE_GOVERNOR case 'g': /* rate governor */ rgParseRateGovernor(&net_config, optarg); break; #endif case 'Z': net_config.flags |= FLAG_STREAMING; break; case 'Y': net_config.rehelloOffset = atol(optarg); break; default: case '?': usage(argv[0]); } } } #ifdef HAVE_KILL if(doKill) { FILE *p; char line[80]; int pid; if(pidfile == NULL) { fprintf(stderr, "-K only works together with --pidfile\n"); return 1; } p = fopen(pidfile, "r"); if(p == NULL) { perror("Could not read pidfile"); return 1; } if(fgets(line, sizeof(line), p) == NULL) { fprintf(stderr, "Empty pid file\n"); return 1; } fclose(p); pid = atoi(line); if(pid <= 0) { fprintf(stderr, "Negative or null pid\n"); return -1; } if(kill(pid, SIGTERM) < 0) { if(errno == ESRCH) { /* Process does not exist => already killed */ unlink(pidfile); } perror("Kill"); return 1; } return 0; } #endif if(net_config.flags & FLAG_ASYNC) { if(dataMcastSupplied) net_config.flags &= ~FLAG_POINTOPOINT; if(net_config.flags & FLAG_POINTOPOINT) { fprintf(stderr, "Pointopoint supplied together with async, but no dataMcastAddress (-m)\n"); return -1; } } if(optind < argc && !disk_config.fileName) { disk_config.fileName = argv[optind++]; } if(optind < argc) { fprintf(stderr, "Extra argument \"%s\" ignored\n", argv[optind]); } if((net_config.flags & FLAG_POINTOPOINT) && (net_config.flags & FLAG_NOPOINTOPOINT)) { fatal(1,"pointopoint and nopointopoint cannot be set both\n"); } if( (net_config.autostart || (net_config.flags & FLAG_ASYNC)) && net_config.rexmit_hello_interval == 0) net_config.rexmit_hello_interval = 1000; #ifdef LOSSTEST if(!seedSet) srandomTime(printSeed); #endif if(net_config.flags & FLAG_ASYNC) { if(net_config.rateGovernor == 0) { fprintf(stderr, "Async mode chosen but no rate governor ==> unsafe\n"); fprintf(stderr, "Transmission would fail due to buffer overrung\n"); fprintf(stderr, "Add \"--max-bitrate 9500k\" to commandline (for example)\n"); exit(1); } #ifdef BB_FEATURE_UDPCAST_FEC if(! (net_config.flags & FLAG_FEC)) #endif { fprintf(stderr, "Warning: Async mode but no forward error correction\n"); fprintf(stderr, "Transmission may fail due to packet loss\n"); fprintf(stderr, "Add \"--fec 8x8\" to commandline\n"); } } if(net_config.min_slice_size < 1) net_config.min_slice_size = 1; if(net_config.max_slice_size < net_config.min_slice_size) net_config.max_slice_size = net_config.min_slice_size; if(net_config.default_slice_size != 0) { if(net_config.default_slice_size < net_config.min_slice_size) net_config.default_slice_size = net_config.min_slice_size; if(net_config.default_slice_size > net_config.max_slice_size) net_config.default_slice_size = net_config.max_slice_size; } if(daemon_mode < 2) fprintf(stderr, "Udp-sender %s\n", version); /* if(disk_config.fileName == NULL && disk_config.pipeName == NULL) { fatal(1, "You must supply file or pipe\n"); } end of argument parsing */ #ifdef USE_SYSLOG openlog((const char *)"udpcast", LOG_NDELAY|LOG_PID, LOG_SYSLOG); #endif mainSock = openMainSenderSock(&net_config, ifName); if(mainSock < 0) { perror("Make main sock"); exit(1); } #ifdef HAVE_DAEMON if(daemon_mode == 2) { net_config.flags |= FLAG_NOKBD; stat_config.noProgress = 1; if(daemon(1, 0) < 0) { perror("Could not daemonize"); exit(1); } if(pidfile) { FILE *p = fopen(pidfile, "w"); fprintf(p, "%d\n", getpid()); fclose(p); signal(SIGTERM, cleanPidfile); } } #endif do { r= startSender(&disk_config, &net_config, &stat_config, mainSock); } while(daemon_mode); closesocket(mainSock); rgShutdownAll(&net_config); return r; } udpcast-20120424/install-sh0000755000175000017500000002202111745607103014354 0ustar alainalain#!/bin/sh # install - install a program, script, or datafile scriptversion=2005-05-14.22 # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the # following copyright and license. # # Copyright (C) 1994 X Consortium # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name of the X Consortium shall not # be used in advertising or otherwise to promote the sale, use or other deal- # ings in this Software without prior written authorization from the X Consor- # tium. # # # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. It can only install one file at a time, a restriction # shared with many OS's install programs. # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" mkdirprog="${MKDIRPROG-mkdir}" chmodcmd="$chmodprog 0755" chowncmd= chgrpcmd= stripcmd= rmcmd="$rmprog -f" mvcmd="$mvprog" src= dst= dir_arg= dstarg= no_target_directory= usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE or: $0 [OPTION]... SRCFILES... DIRECTORY or: $0 [OPTION]... -t DIRECTORY SRCFILES... or: $0 [OPTION]... -d DIRECTORIES... In the 1st form, copy SRCFILE to DSTFILE. In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. In the 4th, create DIRECTORIES. Options: -c (ignored) -d create directories instead of installing files. -g GROUP $chgrpprog installed files to GROUP. -m MODE $chmodprog installed files to MODE. -o USER $chownprog installed files to USER. -s $stripprog installed files. -t DIRECTORY install into DIRECTORY. -T report an error if DSTFILE is a directory. --help display this help and exit. --version display version info and exit. Environment variables override the default commands: CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG " while test -n "$1"; do case $1 in -c) shift continue;; -d) dir_arg=true shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; --help) echo "$usage"; exit $?;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -s) stripcmd=$stripprog shift continue;; -t) dstarg=$2 shift shift continue;; -T) no_target_directory=true shift continue;; --version) echo "$0 $scriptversion"; exit $?;; *) # When -d is used, all remaining arguments are directories to create. # When -t is used, the destination is already specified. test -n "$dir_arg$dstarg" && break # Otherwise, the last argument is the destination. Remove it from $@. for arg do if test -n "$dstarg"; then # $@ is not empty: it contains at least $arg. set fnord "$@" "$dstarg" shift # fnord fi shift # arg dstarg=$arg done break;; esac done if test -z "$1"; then if test -z "$dir_arg"; then echo "$0: no input file specified." >&2 exit 1 fi # It's OK to call `install-sh -d' without argument. # This can happen when creating conditional directories. exit 0 fi for src do # Protect names starting with `-'. case $src in -*) src=./$src ;; esac if test -n "$dir_arg"; then dst=$src src= if test -d "$dst"; then mkdircmd=: chmodcmd= else mkdircmd=$mkdirprog fi else # Waiting for this to be detected by the "$cpprog $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if test ! -f "$src" && test ! -d "$src"; then echo "$0: $src does not exist." >&2 exit 1 fi if test -z "$dstarg"; then echo "$0: no destination specified." >&2 exit 1 fi dst=$dstarg # Protect names starting with `-'. case $dst in -*) dst=./$dst ;; esac # If destination is a directory, append the input filename; won't work # if double slashes aren't ignored. if test -d "$dst"; then if test -n "$no_target_directory"; then echo "$0: $dstarg: Is a directory" >&2 exit 1 fi dst=$dst/`basename "$src"` fi fi # This sed command emulates the dirname command. dstdir=`echo "$dst" | sed -e 's,/*$,,;s,[^/]*$,,;s,/*$,,;s,^$,.,'` # Make sure that the destination directory exists. # Skip lots of stat calls in the usual case. if test ! -d "$dstdir"; then defaultIFS=' ' IFS="${IFS-$defaultIFS}" oIFS=$IFS # Some sh's can't handle IFS=/ for some reason. IFS='%' set x `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` shift IFS=$oIFS pathcomp= while test $# -ne 0 ; do pathcomp=$pathcomp$1 shift if test ! -d "$pathcomp"; then $mkdirprog "$pathcomp" # mkdir can fail with a `File exist' error in case several # install-sh are creating the directory concurrently. This # is OK. test -d "$pathcomp" || exit fi pathcomp=$pathcomp/ done fi if test -n "$dir_arg"; then $doit $mkdircmd "$dst" \ && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \ && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \ && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \ && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; } else dstfile=`basename "$dst"` # Make a couple of temp file names in the proper directory. dsttmp=$dstdir/_inst.$$_ rmtmp=$dstdir/_rm.$$_ # Trap to clean up those temp files at exit. trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 trap '(exit $?); exit' 1 2 13 15 # Copy the file name to the temp name. $doit $cpprog "$src" "$dsttmp" && # and set any options; do chmod last to preserve setuid bits. # # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $cpprog $src $dsttmp" command. # { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \ && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \ && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \ && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } && # Now rename the file to the real destination. { $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \ || { # The rename failed, perhaps because mv can't rename something else # to itself, or perhaps because mv is so ancient that it does not # support -f. # Now remove or move aside any old file at destination location. # We try this two ways since rm can't unlink itself on some # systems and the destination file might be busy for other # reasons. In this case, the final cleanup might fail but the new # file should still install successfully. { if test -f "$dstdir/$dstfile"; then $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \ || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \ || { echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 (exit 1); exit 1 } else : fi } && # Now rename the file to the real destination. $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" } } fi || { (exit 1); exit 1; } done # The final little trick to "correctly" pass the exit status to the exit trap. { (exit 0); exit 0 } # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-end: "$" # End: udpcast-20120424/Changelog.txt0000444000175000017500000001632211745600246015006 0ustar alainalainv20120424 * In receiver, return correct status if pipe fails * By default, use nosync, even on device files v20110710 * fixed some -Wextra compilation warnings * new --no-progress flag to suppress progress display * print most debug messages to log, if available * properly handle Control-C signal * --receive-timeout parameter for receiver timeout during transmission * "real" daemon mode v20100501 * Merged Michael Schutte's changes v20100417 * Merged Tomas Pospisek's changes v20100130 * In busybox, call the executables udp-receiver and udp-sender, the same as outside of busybox v20091230 * new "--ignore-lost-data" mode * Lift limit in number of supported network interfaces v20091031 * Support for start-timeout also on sender v20090920 * Fixed slice management bug introduced with streaming v20090912 * Restored block alignment enforcement (needed when reading data from a pipe) * Fixed division-by-zero error on zero-sized transmissions * Only make data blocks as big as needed v20090830 * "Streaming" mode * On receiver, make failure to send hello packet not fatal * More efficient transmission on small files * Allow pointopoint mode to be "used" (ignored) together with async, as long as a dataMcastAddress is supplied v20081213 * Compatibility with pre-historic compilers v20081130 * Fixed a couple of compilation warnings v20081116 * Settable statistics printout delay * Print uncompressed size only when it makes sense (pipe used, and seekable output) * Linux lseek bug workaround v20080914 * Added distclean target to make Debian build easier * Adapted to new name of mingw compiler, and other Mingw adaptations * Removed obsolete m486 flag * Fixed parameter types for getsockopt * If there are no participants after autostart delay, do not transmit but exit right away * RpmLint fixes * Adapt to Solaris 9 sparc * Added a lot of short opts (for systems without getopt_long) * pluggable rate governor * Mingw fixes (socket closing) v20071228 * Removed -Wdeclaration-after-statement flag which only exists on gcc4 * Make exit status testing dependant on WIFEXITED rather than MINGW32 (because exit status might be missing on other platforms as well) v20070602 * Adapt to Solaris 10 x86 (added includes and configure checks) * Patch to fix parallel make & make DESTDIR=/tmp/xxx install * Address gcc4 warnings * Remove some #define fn udpc_fn lines v20070323 * Fixed typoes in socklib.c v20070306 * Fix issue with pipes and no destination file on receiver v20070218 * Doc fix v20070205 * Adapt to busybox 1.4.1 (Config.in) v20070131 * Added #include to make it compile under (K)ubuntu (to be confirmed) * Fix uninitialized variable in udp-receiver v20070129 * Adapt to busybox 1.3.2 v20061220 * Adapt to busybox 1.3.0 v20061216 * Darwin patch * Timeout method on receiver * Refactoring to postpone file creation until sender is located * Added start-timeout flag v20060929 * Fix usage message to use full names for --mcast-data-address and mcast-rdv-address v20060921 * Avoid variable name "log", apparently, for older compilers, this shadows the name of a built-in * Include uio.h into socklib.h, needed with older include files for iovec v20060920 * Added missing format string to printMyIp v20060917 * If --rexmit-hello-interval set on sender, still only display prompt once on receiver * Improved logging (on sender, offer option to periodically log instantaneous bandwidth, log retransmission, and added datestamp to all log) * Enable autoconf (configure) in order to make it easier to compile it on other Unices * Reorganized cmd.html file to make it cleaner HTML (all the man stuff now in separate files) * Fix a buffer overrun on Windows v20060619 * Add null-termination to option lists v20060525 * Change copyright into license in RPM spec file * Fix allocation of FEC memory, so that it only happens when needed * Fix udpcast for loopback device (send to "self" address) * In FEC mode make sure we don't get an excessive number of blocks if number of slices is too small * Daemon-mode for udp-sender v20060325 * Fix packaging, so that we now can build an clean rpm with just the command-line programs. The mkimage script for the embedded system is now within another RPM (udpcast-mkimage) which, for the moment, is still constructed the old kludgy way. v20060320 * Fixed signed-ness issues (revealed by gcc4) * By default write files in unsynchronized mode, for better performance * Fix case where data address is the same as rendez-vous address. v20060312 * Added usage message for --nosync option v20060309 * Fix global_client_config handling in udpr-negotiate.c * more intuitive/consistent names for various options v20060208 * Fix compilation issue (variable declaration after code) * Avoid sending connect request twice v20051223 * Phase out of most of the way old endianness backwards compatibility hacks * Mingw compatibility * Commands to do more easier unicast * Fix Case where Control-C is pressed on receiver right when it waits for the "start" keypress v20051204 * Suppress excessive timeout messages (only print message after 5 timeouts have expired...) * use #ifdef i386 instead of ARCH_X86, fix assembler #ifdefs in fec.c * Fix Makefile to use $(CC) everywhere, rather than hardcoding compiler * Fix terminal handling (missing optional_action parameter) v20050226 * Fixed signed/unsigned bug v20050217 * Fixed uninitialized console variable v20050206 * Refactoring in console.c: do away with dedicated keyboard listener thread in udp-receiver * Fixed race condition which may happen at end of FEC transmission * Fixed a couple of typoes (it is sender, not server...) * Refactoring to allow alias interfaces eth0:0 * CYGWIN compatibility * Log key messages (receiver join, etc.) to syslog v20040417 Removed explicit reference to busybox version from Makefile: from now on, we establish a symbolic link v20040222 Minor fixes to v20040221 v20040221 Adapt for busybox 1.00pre7 v20030831 Fix bad assertion in FEC mode v20030706 Applied patch renaming USE_ASSEMBLER into ARCH_X86 Applied DESTDIR patch v20030701 Added exitWait config option to make receiver hang around for a while at end, in order to protect against lost final ACK Make retriesUntilDrop configurable v20030615 Make sender exit if there are no receivers left during transfer v20030611 Added --nokbd support to udp-receiver v20030609 Added COPYING file to source tree detailing the license of fec.c v20030605b Fixed license in udpcast.spec Included license printing in udpcast v20030605 Added missing libbb_udpcast.h file to CVS v20030601 Fix keyboard mode (udp-receiver left terminal in raw state if started from another participant) v20030524 If we send our connectreq as a response to a server's hello message, then send it directly to the server, rather than to the broadcast address v20030518 Robustness against bad packets. Completed Danish language file. Released as 20030517 on web site. Updated doc for new --min-clients type flags v20030517 Merged patches contributed by various users v20030511 Busybox support (make sure all symbols are unique, script to move .c/.h files to busybox, applet templates, usage templates, FEC support optional) v20030502 CVS merge after disk crash of last spring udpcast-20120424/cmd.html0000444000175000017500000005523611606103644014012 0ustar alainalain Udpcast commandline options

Udpcast commandline options

This page describes the options for the command line versions of udpcast. The commandline version of udpcast is 100% compatible with the boot disk version. You can for instance start the sender from the bootdisk, but have a receiver run from commandline on the fileserver, in order to get an archive copy of the sender's disk image. Later you may start a commandline sender on the fileserver, and bootdisk receivers on the client boxes, in order to restore their image from the archived copy. Of course, you may also directly udpcast an image from a master client to copies, in this case bother sender and receiver would run from the boot disk.

The boot disk version's menues only give access to the most common command line option (file name and pipe mode (compressions)). In order to access the other options, use the "Additional parameters" dialog box to enter them, just like you would type them into a shell window.

Udp-sender

Udp-sender is used to broadcast a file (for instance a disk image) to multiple udp-receivers on the local LAN. In order to do this, it uses Ethernet multicast or broadcast, so that all receivers profit from the same physical datastream. Thus, sending to 10 destinations does not take more time than it would take to send just 2.

Basic options

--file file
Reads data to be transmitted from file. If this parameter is not supplied, data to be transmitted is read from stdin instead.
--pipe command
Sends data through pipe before transmitting it. This is useful for compressing/decompressing it, or for stripping out unused blocks. The command gets a direct handle on the input file or device, and thus may seek inside it, if needed. Udpcast itself also keeps a handle on the file, which is used for an informal progress display. The command's stdout is a pipe to udpcast.
--autostart n
Starts transmission after n retransmissions of hello packet, without waiting for a key stroke. Useful for unattended operation, where udp-sender is started from a cron-job for a broadcast/multicast at a scheduled time.

Networking options

The following networking options should be supplied both on the sender and the receivers:

--portbase portbase
Default ports to use for udpcast. Two ports are used: portbase and portbase+1 . Thus, Portbase must be even. Default is 9000. The same portbase must be specified for both udp-sender and udp-receiver.
--interface interface
Network interface used to send out the data. Default is eth0
--ttl time to live
Sets the time-to-live parameter for the multicast packets. Should theoretically allow to use UDPCast beyond the local network, but not tested for lack of a multicast router.
--mcast-rdv-address address

Uses a non-standard multicast address for the control (rendez-vous) connection. This address is used by the sender and receivers to "find" each other. This is not the address that is used to transfer the actual data.

By default mcast-rdv-address is the Ethernet broadcast address if ttl is 1, and 224.0.0.1 otherwise. This setting should not be used except in very special situations, such as when 224.0.0.1 cannot be used for policy reasons.

The following networking options should be supplied only on the sender:

--mcast-data-address address
Uses the given address for multicasting the data. If not specified, the program will automatically derive a multicast address from its own IP (by keeping the last 27 bits of the IP and then prepending 232).
--pointopoint
Point-to-point mode. Only a single receiver is allowed, but the data will be directly send to this receiver (in unicast mode), rather than multicast/broadcast all over the place. If no async mode is chosen, and there happens to be only one receiver, point-to-point is activated automatically.
--nopointopoint
Don't use point-to-point, even if there is only one single receiver.
--full-duplex

Use this option if you use a full-duplex network. T-base-10 or 100 is full duplex if equipped with a switch. Hub based networks, or T-base-2 networks (coaxial cable) are only half-duplex and you should not use this option with these networks, or else you may experience a 10% performance hit.

N.B. On high-latency WAN links, the full-duplex option can lead to substantial performance improvements, because it allows udp-sender to send more data while it is still waiting for the previous batch to get acknowledged.

--half-duplex
Use half duplex mode (needed for Hub based or T-base-2 networks). This is the default behavior in this version of udpcast.
--broadcast

Use Ethernet broadcast, rather than multicast. Useful if you have Ethernet cards which don't support multicast.

By default, udpcast uses multicast. This allows sending the data only to those receivers that requested it. Ethernet cards of machines which don't participate in the transmission automatically block out the packets at the hardware level. Moreover, network switches are able to selectively transmit the packets only to those network ports to which receivers are connected. Both features thus allow a much more efficient operation than broadcast. This option should only be supplied on the sender.

-b blocksize
Choses the packet size. Default (and also maximum) is 1456.

Unidirectional mode (without return channel)

The options described below are useful in situations where no "return channel" is available, or where such a channel is impractical due to high latency. In an unidirectional setup (i.e. without return channel), the sender only sends data but doesn't expect any reply from the receiver.

Unidirectional options must be used together, or else the transfer will not work correctly. You may for example use the following command line:

udp-sender --async --max-bitrate 10m --fec 8x8

--async
Asynchronous mode. Do not request confirmations from the receiver. Best used together with forward error correction and bandwidth limitation, or else the receiver will abort the reception as soon as it misses a packet. When the receiver aborts the reception in such a way, it will print a list of packets lost in the slice causing the problem. You can use this list to tune the forward error correction parameters.
--max-bitrate bitrate
Limits bandwidth used by udpcast. Useful in asynchronous mode, or else the sender may send too fast for the switch and/or receiver to keep up. Bitrate may be expressed in bits per second (--bitrate 5000000), kilobits per second (--bitrate 5000k) or megabits per second (--bitrate 5m). This is the raw bitrate, including packet headers, forward error correction, retransmissions, etc. Actual payload bitrate will be lower.
--fec interleavexredundancy/stripesize

Enables forward error correction. The goal of forward error correction is to transmit redundant data, in order to make up for packets lost in transit. Indeed, in unidirectional mode, the receivers have no way of requesting retransmission of lost packets, thus the only way to address packet loss is to include redundant information to begin with. The algorithm is designed in such a way that if r redundant packets are transmitted, that those can be used to compensate for the loss of any r packets in the same FEC group (stripe).

In order to increase robustness of the FEC algorithm against burst packet losses, each slice is divided in interleave stripes. Each stripe has stripesize blocks (if not specified, stripesize is calculated by diving slice-size by interleave). For each stripe, redundancy FEC packets are added. Stripes are organized in such a fashion that consecutive packets belong to different stripes. This way, we ensure that burst losses affect different stripes, rather than using all FEC packets of a single stripe. Example: --fec 8x8/128

--rate-governor module.so:key1=value1,key2=value2

Applies a dynamically loadable rate governor. module.so is the name of the preloadable module, which is followed by a number of property assignments (key1=value1). The rate governor controls the transmission rate according to various criteria, such as congestion information received from a routing or encapsulating device. See comments in /usr/include/udpcast/rateGovernor.h and example in examples/rateGovernor for more details

--rexmit-hello-interval timeout

If set, rebroadcasts the HELLO packet used for initiating the casting each timeout milliseconds.

This option is useful together with asyc mode, because with async mode the receiver won't send a connection request to the sender (and hence won't get a connection reply). In async mode, the receivers get all needed information from the hello packet instead, and are thus particularly dependant on the reception of this packet, makeing retransmission useful.

This option is also useful on networks where packet loss is so high that even with connection requests, sender and receiver would not find each other otherwise.

--retries-until-drop retries
How many time to send a REQACK until dropping a receiver. Lower retrycounts make udp-sender faster to react to crashed receivers, but they also increase the probability of false alerts (dropping receivers that are not actually crashed, but merely slow to respond for whatever reason)
--streaming
Allows receivers to join an ongoing transmission mid through

Keyboardless mode

The options below help to run a sender in unattended mode.
--min-receivers n
Automatically start as soon as a minimal number of receivers have connected.
--min-wait t
Even when the necessary amount of receivers do have connected, still wait until t seconds since first receiver connection have passed.
--max-wait t
When not enough receivers have connected (but at least one), start anyways when t seconds since first receiver connection have pased.
--nokbd
Do not read start signal from keyboard, and do not display any message telling the user to press any key to start.
--start-timeout sec
sender aborts at start if it doesn't see a receiver within this many seconds. Furthermore, transmission of data needs to start within this delay. Once transmission is started, the timeout no longer applies.
--daemon-mode
Do not exit when done, but instead wait for the next batch of receivers. If this option is given twice, udp-sender puts itself into the background, closes its standard file descriptors, and acts as a real daemon.
--pid-file file
Allow to specify a pid file. If given together with --daemon-mode, udp-sender will write its pid into this file. If given together with --kill, the process with the given pid will be killed.
--kill
Shuts down the udp-sender identified by the pid file (which also must be specified). Kill does not interrupt an ongoing transmission, but instead waits until it is finished.

Example:

udp-sender -f zozo --min-receivers 5 --min-wait 20 --max-wait 80

  • If one receiver connects at 18h00.00, and 4 more within the next 5 minutes, start at 18h00.20. (5 receivers connected, but min-wait not yet pased)
  • If one receiver connects at 18h00.00, and 3 more within the next 5 minutes, then a last one at 18h00.25, start right after.
  • If one receiver connects at 18h00.00, then 3 more within the next 15 minutes, then no one, start at 18h01.20. (not enough receivers, but we start anyways after max-wait).

Logging and statistics options

The options instruct udp-sender to log some additional statistics to a file:
--stat-period seconds
Every so much milliseconds, print some statistics to stderr: how much bytes sent so far log, position in uncompressed file (if applicable), retransmit count... By default, this is printed every half second.
--print-uncompressed-position flag
By default, udp-sender only prints the position in uncompressed file if the 2 following conditions are met:
  • Input is piped via a compressor (-p option).
  • The primary input is seekable (file or device)
With the --print-uncompressed-position, options, you can change this behavior:
  • If flag is 0, uncompressed position will never be printed, even if above conditions are met
  • If flag is 1, uncompressed position will always be printed, even if above conditions are not met
--log file
Logs some stuff into file.
--no-progress
Do not display progress statistics.
--bw-period seconds
Every so much seconds, log instantenous bandwidth seen during that period. Note: this is different from the bandwidth displayed to stderr of the receiver, which is the average since start of transmission.

Udp-receiver

Udp-receiver is used to receive files sent by udp-sender (for instance a disk image).

Basic options

--file file
Writes received data to file. If this parameter is not supplied, received data is written to stdout instead.
--pipe command
Sends data through pipe after receiving it. This is useful for decompressing the data, or for filling in unused filesystem blocks that may have been stripped out by udp-sender. The command gets a direct handle on the output file or device, and thus may seek inside it, if needed. Udpcast itself also keeps a handle on the file, which is used for an informational progress display. The command's stdin is a pipe from udp-receiver. Example: udp-receiver -p "gzip -dc"
--log file
Logs some stuff into file.
--nosync
Do not open target in synchronous mode. This is the default when writing to a file or a pipe.
--sync
Write to target in synchronous mode. This is the default when writing to a device (character or block)
--nokbd
Do not read start signal from keyboard, and do not display any message telling the user to press any key to start.
--start-timeout sec
receiver aborts at start if it doesn't see a sender within this many seconds. Furthermore, the sender needs to start transmission of data within this delay. Once transmission is started, the timeout no longer applies.
--receive-timeout sec
receiver aborts during transmission if it doesn't see a packet from the sender within this many seconds. This timeout only applies once transmission has started.

Networking options

--portbase portbase
Default ports to use for udpcast. Two ports are used: portbase and portbase+1 . Thus, Portbase must be even. Default is 9000. The same portbase must be specified for both udp-sender and udp-receiver.
--interface interface
Network interface used to send out the data. Default is eth0
--ttl ttl
Time to live for connection request packet (by default connection request is broadcast to the LAN's broadcast address. If ttl is set, the connection request is multicast instead to 224.0.0.1 with the given ttl, which should enable udpcast to work between LANs. Not tested though.
--mcast-rdv-address address
Uses a non-standard multicast address for the control connection (which is used by the sender and receivers to "find" each other). This is not the address that is used to transfer the data. By default mcast-rdv-address is the Ethernet broadcast address if ttl is 1, and 224.0.0.1 otherwise. This setting should not be used except in very special situations, such as when 224.0.0.1 cannot be used for policy reasons.
--exit-wait milliseconds
When transmission is over, receiver will wait for this time after receiving the final REQACK. This is done in order to guard against loss of the final ACK. Is 500 milliseconds by default.
--ignore-lost-data
Do not stop reception when data loss is detected, but instead fill with random data. This is useful for multimedia transmission where 100% integrity is not need.

Statistics options

--stat-period seconds
Every so much milliseconds, print some statistics to stderr: how much bytes received so far log, position in uncompressed file (if applicable), overall bitrate... By default, this is printed every half second.
--print-uncompressed-position flag
By default, udp-receiver only prints the position in uncompressed file if the 2 following conditions are met:
  • Output is piped via a compressor (-p option).
  • The final output is seekable (file or device)
With the --print-uncompressed-position, options, you can change this behavior:
  • If flag is 0, uncompressed position will never be printed, even if above conditions are met
  • If flag is 1, uncompressed position will always be printed, even if above conditions are not met

Tuning options (sender)

The following tuning options are all about slice size. Udpcast groups its data in slices, which are a series of blocks (UDP packets). These groups are relevant for

  • data retransmission: after each slice, the server asks the receivers whether they have received all blocks, and if needed retransmits what has been missing
  • forward error correction: each slice has its set of data blocks, and matching FEC blocks.
--min-slice-size size
minimum slice size (expressed in blocks). Default is 16. When dynamically adjusting slice size (only in non-duplex mode), never use smaller slices than this. Ignored in duplex mode (default).
--max-slice-size size
maximum slice size (expressed in blocks). Default is 1024. When dynamically adjusting slice size (only in non-duplex mode), never use larger slices than this. Ignored in duplex mode (default).
--default-slice-size size
Slice size used (starting slice size in half-duplex mode).
--rehello-offset offs
in streaming mode, how many packets before end of slice the hello packet will be transferred (default 50). Chose larger values if you notice that receivers are excessively slow to pick up running transmission

Tuning the forward error correction

There are three parameters on which to act:

redundancy
This influences how much extra packets are included per stripe. The higher this is, the more redundancy there is, which means that the transmission becomes more robust against loss. However, CPU time necessary is also proportional to redundancy (a factor to consider on slow PC's), and of course, a higher redundancy augments the amount of data to be transmitted.
interleave
This influences among how many stripes the data is divided. Higher interleave improves robustness against burst loss (for example, 64 packets in a row...). It doesn't increase robustness against randomly spread packet loss. Note: interleave bigger than 8 will force a smaller stripesize, due to the fact that slicesize is limited to 1024.
stripesize
How many data blocks there are in a stripe. Due to the algorithm used, this cannot be more than 128. Reducing stripe size is an indirect way of augmenting (relative) redundancy, without incurring the CPU penalty of larger (absolute) redundancy. However, a larger absolute redundancy is still preferable over a smaller stripesize, because it improves robustness against clustered losses. For instance, if 8/128 is preferable over 4/64, because with 8/128 the 8 FEC packets can be used to compensate for the loss of any of the 128 data packets, whereas with 4/64, each group of 4 FEC packets can only be used against its own set of 64 data packets. If for instance the first 8 packets were lost, they would be recoverable with 8/128, but not with 4/64.
Considering these, change parameters as follows:
  • If you observe long stretches of lost packets, increase interleave
  • If you observe that transfer is slowed down by CPU saturation, decrease redundancy and stripesize proportionnally.
  • If you observe big variations in packet loss rate, increase redundancy and stripesize proportionnally.
  • If you just observe high loss, but not necessarily clustered in any special way, increase redundancy or decrease stripesize
  • Be aware that network equipment or the receiver may be dropping packets because of a bandwidth which is too high. Try limiting it using max-bitrate
  • The receiver may also be dropping packets because it cannot write the data to disk fast enough. Use hdparm to optimize disk access on the receiver. Try playing with the settings in /proc/sys/net/core/rmem_default and /proc/sys/net/core/rmem_max, i.e. setting them to a higher value.

udpcast-20120424/fec.h0000444000175000017500000000156511603173117013262 0ustar alainalain#ifndef FEC_H #define FEC_H #ifdef BB_FEATURE_UDPCAST_FEC #undef HAVE_STDINT_H #include "libbb_udpcast.h" typedef struct fec_parms *fec_code_t; /* * create a new encoder, returning a descriptor. This contains k,n and * the encoding matrix. * n is the number of data blocks + fec blocks (matrix height) * k is just the data blocks (matrix width) */ void fec_init(void); void fec_encode(unsigned int blockSize, unsigned char **data_blocks, unsigned int nrDataBlocks, unsigned char **fec_blocks, unsigned int nrFecBlocks); void fec_decode(unsigned int blockSize, unsigned char **data_blocks, unsigned int nr_data_blocks, unsigned char **fec_blocks, unsigned int *fec_block_nos, unsigned int *erased_blocks, unsigned short nr_fec_blocks /* how many blocks per stripe */); void fec_print(fec_code_t code, int width); void fec_license(void); #endif #endif udpcast-20120424/libbb_udpcast.h0000444000175000017500000000072610542162053015316 0ustar alainalain/* libbb_udhcp.h - busybox compatability wrapper */ #ifndef _LIBBB_UDPCAST_H #define _LIBBB_UDPCAST_H #ifndef UDPCAST_CONFIG_H # define UDPCAST_CONFIG_H # include "config.h" #endif #ifndef NO_BB #undef HAVE_STDINT_H #include "libbb.h" #include "busybox.h" #define COMBINED_BINARY #else /* ! BB_BT */ #define TRUE 1 #define FALSE 0 #ifdef HAVE_MALLOC_H #include #endif #define xmalloc malloc #endif /* BB_VER */ #endif /* _LIBBB_UDPCAST_H */ udpcast-20120424/rate-limit.h0000444000175000017500000000017511065117357014576 0ustar alainalain#ifndef RATE_LIMIT_H #define RATE_LIMIT_H extern struct rateGovernor_t maxBitrate; #define MAX_BITRATE "maxBitrate" #endif udpcast-20120424/udpcast.spec0000444000175000017500000001355111745600246014676 0ustar alainalain%define _binary_payload w9.gzdio %global _binary_filedigest_algorithm 1 %global _source_filedigest_algorithm 1 Name: udpcast Summary: UDP broadcast file distribution and installation Version: 20120424 Release: 1 License: GPLv2+ and BSD Group: Applications/System URL: http://udpcast.linux.lu/ Source: http://udpcast.linux.lu/download/%{name}-%{version}.tar.gz Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) BuildRequires: m4 BuildRequires: perl %description Command-line client for UDP sender and receiver. Udpcast is an application for multicasting data to multiple targets. %prep %setup -q # Don't pass -s (strip) option to ld sed -i -e '/override LDFLAGS +=-s/d' Makefile.in %configure \ --prefix=%{buildroot}%{_prefix} \ --mandir=%{buildroot}%{_mandir} \ --libdir=%{buildroot}%{_libdir} \ %build make %clean echo rm -rf $RPM_BUILD_ROOT %install make install %files %defattr(-,root,root) %{_sbindir}/udp-sender %{_sbindir}/udp-receiver %{_mandir}/man1/udp-sender.1.gz %{_mandir}/man1/udp-receiver.1.gz %{_includedir}/udpcast/rateGovernor.h %doc Changelog.txt cmd.html COPYING %changelog * Tue Apr 24 2012 Alain Knaff - In receiver, return correct status if pipe fails - By default, use nosync, even on device files * Sun Jul 10 2011 Alain Knaff - fixed some -Wextra compilation warnings - new --no-progress flag to suppress progress display - print most debug messages to log, if available - properly handle Control-C signal - --receive-timeout parameter for receiver timeout during transmission - "real" daemon mode * Sat Jan 30 2010 Alain Knaff - In busybox, call the executables udp-receiver and udp-sender, the same as outside of busybox * Wed Dec 30 2009 Alain Knaff - new "--ignore-lost-data" mode - Lift limit in number of supported network interfaces * Sat Oct 31 2009 Alain Knaff - Support for start-timeout also on sender * Sun Sep 20 2009 Alain Knaff - Fixed slice management bug introduced with streaming * Sat Sep 12 2009 Alain Knaff - Restored block alignment enforcement (needed when reading data from a pipe) - Fixed division-by-zero error on zero-sized transmissions - only make data blocks as big as needed * Tue Sep 01 2009 Alain Knaff - "Streaming" mode - On receiver, make failure to send hello packet not fatal - More efficient transmission on small files - Allow pointopoint mode to be "used" (ignored) together with async, as long as a dataMcastAddress is supplied * Sat Dec 13 2008 Alain Knaff - Fixed compilation on pre-historic compilers * Sun Nov 30 2008 Alain Knaff - Fix a couple of compiler warnings * Sun Nov 16 2008 Alain Knaff - Configurable statistics printout period - Do not print uncompressed offset is pipe is in use, or offset not seekable * Thu Sep 11 2008 Alain Knaff - Added distclean target to make Debian build easier - Adapted to new name of mingw compiler, and other Mingw adaptations - Removed obsolete m486 flag - Fixed parameter types for getsockopt - If there are no participants after autostart delay, do not transmit but exit right away * Fri May 2 2008 Richard W.M. Jones - 20071228-3 - Remove '-s' flag from Makefile. - Remove unused udpcast_version macro. - Use configure macro. - Fix the license, GPLv2+ and BSD. - BuildRequires perl. * Mon Apr 21 2008 Richard W.M. Jones - 20071228-2 - BR m4. * Mon Apr 21 2008 Richard W.M. Jones - 20071228-1 - Initial packaging for Fedora. * Fri Jun 1 2007 Alain Knaff - Patch to fix parallel make & make DESTDIR=/tmp/xxx install - Address gcc4 warnings - Remove some #define fn udpc_fn lines * Thu May 30 2007 Jan Oelschlaegel - Adapt to Solaris 10 x86 (added includes and configure checks) - Tested on Linux and Solaris 10 (maybe some other OS are broken now...) * Fri Mar 23 2007 Alain Knaff - Fixed typoes in socklib.c * Tue Mar 6 2007 Alain Knaff - Fix issue with pipes and no destination file on receiver * Sun Feb 18 2007 Alain Knaff - Documentation fix * Mon Feb 5 2007 Alain Knaff - Adapt to busybox 1.4.1 (Config.in) * Wed Jan 31 2007 Alain Knaff - Added #include to make it compile under (K)ubuntu - Fix uninitialized variable in udp-receiver * Mon Jan 29 2007 Alain Knaff - Adapt to busybox 1.3.2 * Wed Dec 20 2006 Alain Knaff - Adapt to new busybox 1.3.0 * Sat Dec 16 2006 Alain Knaff - Added startTimeout flag: abort if sender does not start within specified time - Darwin build fixes patch - Refactoring to postpone file creation until sender is located * Fri Oct 20 2006 Alain Knaff - Fix usage message to use full names for --mcast-data-address and mcast-rdv-address * Thu Sep 21 2006 Alain Knaff - Include uio.h into socklib.h, needed with older include files for iovec - Avoid variable name "log", apparently, for older compilers, this shadows the name of a built-in * Wed Sep 20 2006 Alain Knaff - Added missing format string to printMyIp * Sun Sep 17 2006 Alain Knaff - If --rexmit-hello-interval set on sender, still only display prompt once on receiver - Improved logging (on sender, offer option to periodically log instantaneous bandwidth, log retransmission, and added datestamp to all log) - Enable autoconf (configure) in order to make it easier to compile it on other Unices - Reorganized cmd.html file to make it cleaner HTML (all the man stuff now in separate files) - Fix a buffer overrun on Windows * Sat Mar 25 2006 Alain Knaff - Separate commandline spec file and mkimage spec file udpcast-20120424/busyboxUsage0000444000175000017500000000505311331061131014741 0ustar alainalain#define udp_receiver_trivial_usage \ "[--file file] [--pipe pipe] [--portbase portbase] [--interface net-interface] [--log file] [--ttl time-to-live] [--mcast-all-addr mcast-all-address] [--rcvbuf buf]" #define udp_receiver_full_usage \ "Receives a file via UDP multicast\n\n" \ "Options:\n" \ "\t--file\tfile where to store received data\n" \ "\t--pipe\tprogram through which to pipe the data (for example, for uncompressing)\n" \ "\t--portbase\tUDP ports to use\n" \ "\t--interface\tnetwork interface to use (eth0, eth1, ...)\n" \ "\t--log\tlogfile\n" \ "\t--ttl\tIP \"time to live\". Only needed when attempting to udpcast accross routers\n" \ "\t--mcast-all-addr\tmulticast address\n" \ "\t--rcvbuf\tsize of receive buffer\n" #define udp_sender_trivial_usage \ "[--file file] [--full-duplex] [--pipe pipe] [--portbase portbase] [--blocksize size] [--interface net-interface] [--mcast-addr data-mcast-address] [--mcast-all-addr mcast-all-address] [--max-bitrate bitrate] [--pointopoint] [--async] [--log file] [--min-slice-size min] [--max-slice-size max] [--slice-size] [--ttl time-to-live] [--fec x/] [--print-seed] [--rexmit-hello-interval interval] [--autostart autostart] [--broadcast]" #define udp_sender_full_usage \ "Sends a file via UDP multicast\n\n" \ "\t--file\tfile to be transmitted\n" \ "\t--full-duplex\toptimize for full duplex network (equipped with a switch, rather than a hub)\n" \ "\t--pipe\tprogram through which to pipe the data before sending (for instance, a compressor)\n" \ "\t--portbase\tUDP ports to use\n" \ "\t--blocksize\tpacket size\n" \ "\t--interface\tnetwork interface to use (eth0, eth1, ...)\n" \ "\t--mcast-addr\taddress on which to multicast the data\n" \ "\t--mcast-all-addr\taddress on which to multicast the control information\n" \ "\t--max-bitrate\tmaximal bitrate with which to send the data\n" \ "\t--pointopoint\tpointopoint (unicast) mode, suitable for a single receiver\n" \ "\t--async\taynchronous mode (do not expect confirmation messages from receivers)\n" \ "\t--log\tlog file\n" \ "\t--min-slice-size\tminimal size of a \"slice\"\n" \ "\t--max-slice-size\tmaximal size of a \"slice\"\n" \ "\t--slice-sice\tinitial slice size\n" \ "\t--ttl\tIP \"time to live\". Only needed when attempting to udpcast accross routers\n" \ "\t--fec\tForward error correction\n" \ "\t--print-seed\t\n" \ "\t--rexmit-hello-interval\thow often to retransmit \"hello\" packets\n" \ "\t--autostart\tafter how much hello packets to autostart\n" \ "\t--broadcast\tuse broadcast rather than multicast\n" udpcast-20120424/udpc_version.c0000444000175000017500000000007311745600246015216 0ustar alainalain#include "udpc_version.h" const char *version="20120424"; udpcast-20120424/buildMingw.sh0000555000175000017500000000053211063010510014770 0ustar alainalain#!/bin/sh # Build Mingw (Windows) executable # # For this you meed the mingw cross-compiler to be installed # # You may download the RPMs from http://mirzam.it.vu.nl/mingw/ # All 4 RPM's are needed: # mingw-binutils # mingw-gcc-core # mingw-runtime # mingw-w32api dir=`dirname $0` $dir/configure --srcdir $dir --host i586-mingw32msvc make udpcast-20120424/util.h0000444000175000017500000000073007464045035013502 0ustar alainalain#ifndef UTIL_H #define UTIL_H #include #define MALLOC(type) ((type*)calloc(1, sizeof(type))) /* bitmap manipulation */ #define BITS_PER_ITEM(map) (sizeof(map[0])*8) #define MASK(pos,map) (1 << ((pos) % (BITS_PER_ITEM(map)))) #define POS(pos,map) ((pos) / BITS_PER_ITEM(map)) #define SET_BIT(x, map) (map[POS(x,map)] |= MASK(x,map)) #define CLR_BIT(x, map) (map[POS(x,map)] &= ~MASK(x,map)) #define BIT_ISSET(x, map) (map[POS(x,map)] & MASK(x,map)) #endif udpcast-20120424/debian/0000755000175000017500000000000011745607102013574 5ustar alainalainudpcast-20120424/debian/source/0000755000175000017500000000000011745607102015074 5ustar alainalainudpcast-20120424/debian/source/format0000444000175000017500000000001411606251265016301 0ustar alainalain3.0 (quilt) udpcast-20120424/debian/rules0000555000175000017500000000003711606247735014662 0ustar alainalain#!/usr/bin/make -f %: dh $@ udpcast-20120424/debian/control0000444000175000017500000000125311606250370015173 0ustar alainalainSource: udpcast Section: utils Priority: optional Maintainer: Alain Knaff Build-Depends: debhelper (>> 7.0.50~), m4 Standards-Version: 3.8.4 Homepage: http://www.udpcast.linux.lu/ Package: udpcast Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends} Description: multicast file transfer tool UDPcast can send data simultaneously to many destinations on a LAN. This can be used, for example, to install entire classrooms of PCs at once. The advantage of UDPcast over other methods (such as NFS, FTP, etc.) is that UDPcast uses Ethernet's multicast abilities, which means it won't take longer to install 15 machines than it would to install just two. udpcast-20120424/debian/copyright0000444000175000017500000000533711745600257015541 0ustar alainalainFormat-Specification: http://svn.debian.org/wsvn/dep/web/deps/dep5.mdwn?op=file&rev=135 Name: udpcast Maintainer: Alain Knaff Source: http://udpcast.linux.lu/ Files: * Copyright: © 2001–2012 Alain Knaff License: GPL-2 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License, version two, as published by the Free Software Foundation. . On Debian systems, the full text of the GNU General Public License version 2 can be found in the file “/usr/share/common-licenses/GPL-2”. Files: fec.c Copyright: © 1997–1998 Luigi Rizzo © 2001 Alain Knaff Portions derived from August 1995 code by: Phil Karn Robert Morelos-Zaragoza Hari Thirumoorthy License: BSD Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: . 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. . THIS SOFTWARE IS PROVIDED BY THE AUTHORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Files: debian/* Copyright: © 2001–2010 Tomas Pospisek © 2010 Michael Schutte © 2011-2012 Alain Knaff License: GPL-2+ 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. . On Debian systems, the full text of the earliest applicable version of the GNU General Public License can be found in the file “/usr/share/common-licenses/GPL-2”. udpcast-20120424/debian/changelog0000444000175000017500000001013011745600256015442 0ustar alainalainudpcast (20120424) stable; urgency=low * In receiver, return correct status if pipe fails * By default, use nosync, even on device files -- Alain Knaff Tue, 24 Apr 2012 21:16:41 +0200 udpcast (20110710)stable; urgency=low * fixed some -Wextra compilation warnings * new --no-progress flag to suppress progress display * print most debug messages to log, if available * properly handle Control-C signal * --receive-timeout parameter for receiver timeout during transmission * "real" daemon mode -- Alain Knaff Sun, 10 Jul 2011 08:45:57 +0200 udpcast (20100501)unstable; urgency=low * Merged Michael's changes -- Alain Knaff Sat, 1 May 2010 17:53:19 +0200 udpcast (20100417) unstable; urgency=low * Adopt this package, closes: #575167. * New upstream release, closes: #375682. - printMyIp() in socklib.c now uses a proper format string to udpc_flprintf(), closes: #387169. - Build-depend on m4. * Use debhelper 7, change build-dependency, update debian/compat and greatly shorten debian/rules. * Add ${misc:Depends}. * Bump Standards-Version to 3.8.4, no changes needed. * Convert package to the 3.0 (quilt) format. * Provide a debian/watch file. * Convert debian/copyright to the machine-readable format as proposed in DEP 5 and update the information. * Upload package to a collab-maint Git repository and add Vcs-* fields in debian/control. * Point to the project homepage in debian/control. [Tomas Pospisek] * thanks to Alain Knaff for providing Debian packages for all these years -- Michael Schutte Sat, 17 Apr 2010 14:03:19 +0200 udpcast (20100130) stable; urgency=low * In busybox, call the executables udp-receiver and udp-sender, the same as outside of busybox -- Alain Knaff Sat, 30 Jan 2010 17:40:12 +0100 udpcast (20091230)stable; urgency=low * new "--ignore-lost-data" mode * Lift limit in number of supported network interfaces -- Alain Knaff Wed, 30 Dec 2009 18:54:33 +0100 udpcast (20091031)stable; urgency=low * Support for start-timeout also on sender -- Alain Knaff Sat, 31 Oct 2009 15:37:55 +0100 udpcast (20090920)stable; urgency=low * Fixed slice management bug introduced with streaming -- Alain Knaff Sun, 20 Sep 2009 09:57:38 +0200 udpcast (20090912)stable; urgency=low * Restored block alignment enforcement (needed when reading data from a pipe) * Fixed division-by-zero error on zero-sized transmissions * only make data blocks as big as needed -- Alain Knaff Sat, 12 Sep 2009 10:34:49 +0200 udpcast (20090830) stable; urgency=low * "Streaming" mode * On receiver, make failure to send hello packet not fatal * More efficient transmission on small files * Allow pointopoint mode to be "used" (ignored) together with async, as long as a dataMcastAddress is supplied -- Alain Knaff Tue, 1 Sep 2009 20:23:24 +0200 udpcast (20081213) stable; urgency=low * Fixed compilation on pre-historic compilers -- Alain Knaff Sat, 13 Dec 2008 09:48:01 +0100 udpcast (20081130) stable; urgency=low * Fixed a couple of compilation warnings -- Alain Knaff Sun, 30 Nov 2008 17:14:56 +0100 udpcast (20081116) stable; urgency=low * Settable statistics printout delay * Print uncompressed size only when it makes sense (pipe used, and seekable output) -- Alain Knaff Sun, 16 Nov 2008 17:20:56 +0100 udpcast (20080914) stable; urgency=low * Added distclean target to make Debian build easier * Removed obsolete m486 flag * Fixed parameter types for getsockopt * If there are no participants after autostart delay, do not transmit but exit right away * Added a lot of short opts (for systems without getopt_long) * pluggable rate governor * Mingw fixes (socket closing) -- Alain Knaff Sat, 20 Sep 2008 11:54:41 +0200 udpcast (20071228) stable; urgency=low * first release of debian package -- Alain Knaff Thu, 26 Dec 2007 12:23:37 +0100 udpcast-20120424/debian/compat0000444000175000017500000000000211606251251014764 0ustar alainalain7 udpcast-20120424/Config.in0000444000175000017500000000025411063020611014071 0ustar alainalainmenu "Udpcast" config UDPRECEIVER bool "UDPRECEIVER" default y help Udpcast receiver config UDPSENDER bool "UDPSENDER" default y help Udpcast sender endmenu udpcast-20120424/usage.h0000444000175000017500000000517311331065300013620 0ustar alainalain#define udp_receiver_trivial_usage \ "[--file file] [--pipe pipe] [--portbase portbase] [--interface net-interface] [--log file] [--ttl time-to-live] [--mcast-all-addr mcast-all-address] [--rcvbuf buf]" #define udp_receiver_full_usage \ "Receives a file via UDP multicast\n\n" \ "Options:\n" \ "\t--file\tfile where to store received data\n" \ "\t--pipe\tprogram through which to pipe the data (for example, for uncompressing)\n" \ "\t--portbase\tUDP ports to use\n" \ "\t--interface\tnetwork interface to use (eth0, eth1, ...)\n" \ "\t--log\tlogfile\n" \ "\t--ttl\tIP \"time to live\". Only needed when attempting to udpcast accross routers\n" \ "\t--mcast-all-addr\tmulticast address\n" \ "\t--rcvbuf\tsize of receive buffer\n" #define udp_sender_trivial_usage \ "[--file file] [--full-duplex] [--pipe pipe] [--portbase portbase] [--blocksize size] [--interface net-interface] [--mcast-addr data-mcast-address] [--mcast-all-addr mcast-all-address] [--max-bitrate bitrate] [--pointopoint] [--async] [--log file] [--min-slice-size min] [--max-slice-size max] [--slice-size] [--ttl time-to-live] [--print-seed] [--rexmit-hello-interval interval] [--autostart autostart] [--broadcast]" #define udp_sender_full_usage \ "Sends a file via UDP multicast\n\n" \ "\t--file\tfile to be transmitted\n" \ "\t--full-duplex\toptimize for full duplex network (equipped with a switch, rather than a hub)\n" \ "\t--pipe\tprogram through which to pipe the data before sending (for instance, a compressor)\n" \ "\t--portbase\tUDP ports to use\n" \ "\t--blocksize\tpacket size\n" \ "\t--interface\tnetwork interface to use (eth0, eth1, ...)\n" \ "\t--mcast-addr\taddress on which to multicast the data\n" \ "\t--mcast-all-addr\taddress on which to multicast the control information\n" \ "\t--max-bitrate\tmaximal bitrate with which to send the data\n" \ "\t--pointopoint\tpointopoint (unicast) mode, suitable for a single receiver\n" \ "\t--async\taynchronous mode (do not expect confirmation messages from receivers)\n" \ "\t--log\tlog file\n" \ "\t--min-slice-size\tminimal size of a \"slice\"\n" \ "\t--max-slice-size\tmaximal size of a \"slice\"\n" \ "\t--slice-size\tinitial slice size\n" \ "\t--ttl\tIP \"time to live\". Only needed when attempting to udpcast accross routers\n" \ "\t--print-seed\t\n" \ "\t--rexmit-hello-interval\thow often to retransmit \"hello\" packets\n" \ "\t--autostart\tafter how much hello packets to autostart\n" \ "\t--broadcast\tuse broadcast rather than multicast\n" udpcast-20120424/console.h0000444000175000017500000000142110352627706014166 0ustar alainalain#ifndef CONSOLE_H #define CONSOLE_H #ifdef __MINGW32__ #include #include #endif /* __MINGW32__ */ #define prepareConsole udpc_prepareConsole #define getConsoleFd udpc_getConsoleFd #define restoreConsole udpc_restoreConsole typedef struct console_t console_t; /** * Prepares a console on given fd. If fd = -1, opens /dev/tty instead */ console_t *prepareConsole(int fd); /** * Select on the console in addition to the read_set * If character available on console, stuff it into c */ int selectWithConsole(console_t *con, int maxFd, fd_set *read_set, struct timeval *tv, int *keyPressed); /** * Restores console into its original state, and restores everything as it was * before */ void restoreConsole(console_t **, int); #endif udpcast-20120424/udp-receiver.c0000444000175000017500000001533011606103566015111 0ustar alainalain#include #include #include #include #include #include #include "log.h" #include "udpcast.h" #include "udp-receiver.h" #include "socklib.h" #include "udpc_version.h" #ifdef HAVE_GETOPT_H #include #endif #ifdef USE_SYSLOG #include #endif #ifdef BB_FEATURE_UDPCAST_FEC #include "fec.h" #endif #define MAXBLOCK 1024 #ifdef HAVE_GETOPT_LONG static struct option options[] = { { "file", 1, NULL, 'f' }, { "pipe", 1, NULL, 'p' }, { "port", 1, NULL, 'P' }, { "portbase", 1, NULL, 'P' }, { "interface", 1, NULL, 'i' }, { "ttl", 1, NULL, 't' }, { "mcast_all_address", 1, NULL, 'M' }, /* Obsolete name */ { "mcast-all-address", 1, NULL, 'M' }, /* Obsolete name */ { "mcast_rdv_address", 1, NULL, 'M' }, { "mcast-rdv-address", 1, NULL, 'M' }, #ifdef LOSSTEST /* simulating packet loss */ { "write-loss", 1, NULL, 0x601 }, { "read-loss", 1, NULL, 0x602 }, { "seed", 1, NULL, 0x603 }, { "print-seed", 0, NULL, 0x604 }, { "read-swap", 1, NULL, 0x605 }, #endif { "passive", 0, NULL, 'd' }, { "nosync", 0, NULL, 'n' }, { "sync", 0, NULL, 'y' }, { "rcvbuf", 1, NULL, 'b' }, { "nokbd", 0, NULL, 'k' }, { "exitWait", 1, NULL, 'w' }, /* Obsolete name */ { "exit-wait", 1, NULL, 'w' }, { "start-timeout", 1, NULL, 's' }, { "receive-timeout", 1, NULL, 0x801 }, #ifdef BB_FEATURE_UDPCAST_FEC { "license", 0, NULL, 'L' }, #endif { "log", 1, NULL, 'l' }, { "no-progress", 0, NULL, 0x701 }, { "print-uncompressed-position", 1, NULL, 'x' }, { "statistics-period", 1, NULL, 'z' }, { "stat-period", 1, NULL, 'z' }, { "ignore-lost-data", 0, NULL, 'Z' }, { NULL, 0, NULL, 0 } }; # define getopt_l(c,v,o) getopt_long(c, v, o, options, NULL) #else /* HAVE_GETOPT_LONG */ # define getopt_l(c,v,o) getopt(c, v, o) #endif /* HAVE_GETOPT_LONG */ static int signalNumber=0; #ifdef SIG_UNBLOCK static void signalForward(void) { if(signalNumber != 0) { sigset_t sig; signal(signalNumber, SIG_DFL); sigemptyset(&sig); sigaddset(&sig, signalNumber); sigprocmask(SIG_UNBLOCK, &sig, NULL); raise(signalNumber); perror("raise"); } } #endif static void intHandler(int nr) { signalNumber=nr; udpc_fatal(1, "Signal %d: Cancelled by user\n", nr); } #ifdef NO_BB static void usage(char *progname) { #ifdef HAVE_GETOPT_LONG fprintf(stderr, "%s [--file file] [--pipe pipe] [--portbase portbase] [--interface net-interface] [--log file] [--no-progress] [--ttl time-to-live] [--mcast-rdv-address mcast-rdv-address] [--rcvbuf buf] [--nokbd] [--exit-wait milliseconds] [--nosync] [--sync] [--start-timeout sto] [--receive-timeout rct] [--license] [-x uncomprStatPrint] [-z statPeriod] [--print-uncompressed-position flag] [--stat-period millis] [--ignore-lost-data]\n", progname); #else /* HAVE_GETOPT_LONG */ fprintf(stderr, "%s [--f file] [--p pipe] [-P portbase] [-i net-interface] [-l logfile] [-t time-to-live] [-M mcast-rdv-address] [-b rcvbuf] [-k] [-w exit-wait-milliseconds] [-n] [-y] [-s start-timeout] [-L] [-x uncomprStatPrint] [-z statPeriod] [-Z]\n", progname); #endif /* HAVE_GETOPT_LONG */ exit(1); } #endif #ifndef NO_BB int udp_receiver_main(int argc, char **argv); int udp_receiver_main(int argc, char **argv) #else int main(int argc, char **argv) #endif { int ret; char *ptr; struct net_config net_config; struct disk_config disk_config; struct stat_config stat_config; int c; int doWarn=0; char *ifName=NULL; #ifdef LOSSTEST int seedSet = 0; int printSeed = 0; #endif #ifdef SIG_UNBLOCK atexit(signalForward); #endif disk_config.fileName=NULL; disk_config.pipeName=NULL; disk_config.flags = 0; net_config.portBase = 9000; net_config.ttl = 1; net_config.flags = 0; net_config.mcastRdv = NULL; net_config.exitWait = 500; net_config.startTimeout = 0; net_config.receiveTimeout = 0; stat_config.statPeriod = DEFLT_STAT_PERIOD; stat_config.printUncompressedPos = -1; stat_config.noProgress = 0; #ifdef WINDOWS /* windows is basically unusable with its default buffer size of 8k...*/ net_config.requestedBufSize = 1024*1024; #else net_config.requestedBufSize = 0; #endif ptr = strrchr(argv[0], '/'); if(!ptr) ptr = argv[0]; else ptr++; net_config.net_if = NULL; if (strcmp(ptr, "init") == 0) { doWarn = 1; disk_config.pipeName = strdup("/bin/gzip -dc"); disk_config.fileName = "/dev/hda"; } while( (c=getopt_l(argc, argv, "b:f:p:P:i:l:M:s:t:w:x:z:dkLnyZ")) != EOF ) { switch(c) { case 'f': disk_config.fileName=optarg; break; case 'i': ifName=optarg; break; case 'p': disk_config.pipeName=optarg; break; case 'P': net_config.portBase = atoi(optarg); break; case 'l': udpc_log = fopen(optarg, "a"); break; case 0x701: stat_config.noProgress = 1; break; case 't': /* ttl */ net_config.ttl = atoi(optarg); break; case 'M': net_config.mcastRdv = strdup(optarg); break; #ifdef BB_FEATURE_UDPCAST_FEC case 'L': fec_license(); break; #endif #ifdef LOSSTEST case 0x601: setWriteLoss(optarg); break; case 0x602: setReadLoss(optarg); break; case 0x603: seedSet=1; srandom(strtoul(optarg,0,0)); break; case 0x604: printSeed=1; break; case 0x605: setReadSwap(optarg); break; #endif case 'd': /* passive */ net_config.flags|=FLAG_PASSIVE; break; case 'n': /* nosync */ disk_config.flags|=FLAG_NOSYNC; break; case 'y': /* sync */ disk_config.flags|=FLAG_SYNC; break; case 'b': /* rcvbuf */ net_config.requestedBufSize=parseSize(optarg); break; case 'k': /* nokbd */ net_config.flags |= FLAG_NOKBD; break; case 'w': /* exit-wait */ net_config.exitWait = atoi(optarg); break; case 's': /* start-timeout */ net_config.startTimeout = atoi(optarg); break; case 0x801: /* receive-timeout */ net_config.receiveTimeout = atoi(optarg); break; case 'z': stat_config.statPeriod = atoi(optarg) * 1000; break; case 'x': stat_config.printUncompressedPos = atoi(optarg); break; case 'Z': net_config.flags |= FLAG_IGNORE_LOST_DATA; break; case '?': #ifndef NO_BB bb_show_usage(); #else usage(argv[0]); #endif } } fprintf(stderr, "Udp-receiver %s\n", version); #ifdef LOSSTEST if(!seedSet) srandomTime(printSeed); #endif signal(SIGINT, intHandler); #ifdef USE_SYSLOG openlog((const char *)"udpcast", LOG_NDELAY|LOG_PID, LOG_SYSLOG); #endif ret= startReceiver(doWarn, &disk_config, &net_config, &stat_config, ifName); if(ret < 0) { fprintf(stderr, "Receiver error\n"); } return ret; } udpcast-20120424/udpc_version.h0000444000175000017500000000015610625532027015222 0ustar alainalain#ifndef UDPC_VERSION_H #define UDPC_VERSION_H #include "libbb_udpcast.h" extern const char *version; #endif udpcast-20120424/udp-sender.h0000444000175000017500000000501211606103753014564 0ustar alainalain#ifndef UDP_SENDER_H #define UDP_SENDER_H #include "udp-sender.h" #include "udpcast.h" #include "participants.h" #include "statistics.h" #include "socklib.h" extern FILE *udpc_log; struct fifo; #define openFile udpc_openFile #define openPipe udpcs_openPipe #define localReader udpc_localReader #define spawnNetSender udpc_spawnNetSender #define sendHello udpc_sendHello #define openMainSenderSock udpc_openMainSenderSock #define startSender udpc_startSender #define doSend udpc_doSend int openFile(struct disk_config *config); int openPipe(struct disk_config *config, int in, int *pid); int localReader(struct fifo *fifo, int in); int spawnNetSender(struct fifo *fifo, int sock, struct net_config *config, participantsDb_t db, sender_stats_t stats); void sendHello(struct net_config *net_config, int sock, int streaming); int openMainSenderSock(struct net_config *net_config, const char *ifName); int startSender(struct disk_config *disk_config, struct net_config *net_config, struct stat_config *stat_config, int mainSock); #define BCAST_DATA(s, msg) \ doSend(s, &msg, sizeof(msg), &net_config->dataMcastAddr) /** * "switched network" mode: server already starts sending next slice before * first one is acknowledged. Do not use on old coax networks */ #define FLAG_SN 0x0001 /** * "not switched network" mode: network is known not to be switched */ #define FLAG_NOTSN 0x0002 /** * Asynchronous mode: do not any confirmation at all from clients. * Useful in situations where no return channel is available */ #define FLAG_ASYNC 0x0004 /** * Point-to-point transmission mode: use unicast in the (frequent) * special case where there is only one receiver. */ #define FLAG_POINTOPOINT 0x0008 /** * Do automatic rate limitation by monitoring socket's send buffer * size. Not very useful, as this still doesn't protect against the * switch dropping packets because its queue (which might be slightly slower) * overruns */ #ifndef WINDOWS #define FLAG_AUTORATE 0x0008 #endif #ifdef BB_FEATURE_UDPCAST_FEC /** * Forward error correction */ #define FLAG_FEC 0x0010 #endif /** * Use broadcast rather than multicast (useful for cards that don't support * multicast correctly */ #define FLAG_BCAST 0x0020 /** * Never use point-to-point, even if only one receiver */ #define FLAG_NOPOINTOPOINT 0x0040 /* * Don't ask for keyboard input on sender end. */ #define FLAG_NOKBD 0x0080 /** * Streaming mode: allow receiver to join a running transmission */ #define FLAG_STREAMING 0x0100 #endif udpcast-20120424/produconsum.c0000444000175000017500000001103010625532027015064 0ustar alainalain#include #include "threads.h" #include #include "log.h" #include "produconsum.h" #include "util.h" #define DEBUG 0 /** * Simple implementation of producer-consumer pattern */ struct produconsum { unsigned int size; volatile unsigned int produced; unsigned int consumed; volatile int atEnd; pthread_mutex_t mutex; volatile int consumerIsWaiting; pthread_cond_t cond; const char *name; }; produconsum_t pc_makeProduconsum(int size, const char *name) { produconsum_t pc = MALLOC(struct produconsum); pc->size = size; pc->produced = 0; pc->consumed = 0; pc->atEnd = 0; pthread_mutex_init(&pc->mutex, NULL); pc->consumerIsWaiting = 0; pthread_cond_init(&pc->cond, NULL); pc->name = name; return pc; } static void wakeConsumer(produconsum_t pc) { if(pc->consumerIsWaiting) { pthread_mutex_lock(&pc->mutex); pthread_cond_signal(&pc->cond); pthread_mutex_unlock(&pc->mutex); } } /** * We assume here that the producer never ever produces more than fits into * the buffer. To ensure this, use a second buffer, oriented in the other * direction */ void pc_produce(produconsum_t pc, unsigned int amount) { unsigned int produced = pc->produced; unsigned int consumed = pc->consumed; /* sanity checks: * 1. should not produce more than size * 2. do not pass consumed+size */ if(amount > pc->size) { udpc_fatal(1, "Buffer overflow in produce %s: %d > %d \n", pc->name, amount, pc->size); } produced += amount; if(produced >= 2*pc->size) produced -= 2*pc->size; if(produced > consumed + pc->size || (produced < consumed && produced > consumed - pc->size)) { udpc_fatal(1, "Buffer overflow in produce %s: %d > %d [%d] \n", pc->name, produced, consumed, pc->size); } pc->produced = produced; wakeConsumer(pc); } void pc_produceEnd(produconsum_t pc) { pc->atEnd = 1; wakeConsumer(pc); } static int getProducedAmount(produconsum_t pc) { unsigned int produced = pc->produced; unsigned int consumed = pc->consumed; if(produced < consumed) return produced + 2 * pc->size - consumed; else return produced - consumed; } unsigned int pc_getWaiting(produconsum_t pc) { return getProducedAmount(pc); } static int _consumeAny(produconsum_t pc, unsigned int minAmount, struct timespec *ts) { unsigned int amount; #if DEBUG flprintf("%s: Waiting for %d bytes (%d:%d)\n", pc->name, minAmount, pc->consumed, pc->produced); #endif pc->consumerIsWaiting=1; amount = getProducedAmount(pc); if(amount >= minAmount || pc->atEnd) { pc->consumerIsWaiting=0; #if DEBUG flprintf("%s: got %d bytes\n",pc->name, amount); #endif return amount; } pthread_mutex_lock(&pc->mutex); while((amount=getProducedAmount(pc)) < minAmount && !pc->atEnd) { #if DEBUG flprintf("%s: ..Waiting for %d bytes (%d:%d)\n", pc->name, minAmount, pc->consumed, pc->produced); #endif if(ts == 0) pthread_cond_wait(&pc->cond, &pc->mutex); else { int r; #if DEBUG flprintf("Before timed wait\n"); #endif r=pthread_cond_timedwait(&pc->cond, &pc->mutex, ts); #if DEBUG flprintf("After timed wait %d\n", r); #endif if(r == ETIMEDOUT) { amount=getProducedAmount(pc); break; } } } pthread_mutex_unlock(&pc->mutex); #if DEBUG flprintf("%s: Got them %d (for %d) %d\n", pc->name, amount, minAmount, pc->atEnd); #endif pc->consumerIsWaiting=0; return amount; } int pc_consumed(produconsum_t pc, int amount) { unsigned int consumed = pc->consumed; if(consumed >= 2*pc->size - amount) { consumed += amount - 2 *pc->size; } else { consumed += amount; } pc->consumed = consumed; return amount; } int pc_consumeAny(produconsum_t pc) { return _consumeAny(pc, 1, 0); } int pc_consumeAnyWithTimeout(produconsum_t pc, struct timespec *ts) { return _consumeAny(pc, 1, ts); } int pc_consumeAnyContiguous(produconsum_t pc) { return pc_consumeContiguousMinAmount(pc, 1); } int pc_consumeContiguousMinAmount(produconsum_t pc, int amount) { int n = _consumeAny(pc, amount, 0); int l = pc->size - (pc->consumed % pc->size); if(n > l) n = l; return n; } int pc_consume(produconsum_t pc, int amount) { return _consumeAny(pc, amount, 0); } unsigned int pc_getConsumerPosition(produconsum_t pc) { return pc->consumed % pc->size; } unsigned int pc_getProducerPosition(produconsum_t pc) { return pc->produced % pc->size; } unsigned int pc_getSize(produconsum_t pc) { return pc->size; } udpcast-20120424/receiver-diskio.c0000444000175000017500000000342510502347406015602 0ustar alainalain#include #include #include #include #include #include "log.h" #include "udpcast.h" #include "fifo.h" #include "udp-receiver.h" #include "udpc_process.h" #define BLOCKSIZE 4096 #ifdef O_BINARY # include #endif int writer(struct fifo *fifo, int outFile) { int fifoSize = pc_getSize(fifo->data); if(fifoSize % BLOCKSIZE) udpc_fatal(1, "Fifo size not a multiple of block size\n"); while(1) { int pos=pc_getConsumerPosition(fifo->data); int bytes = pc_consumeContiguousMinAmount(fifo->data, BLOCKSIZE); if (bytes == 0) { return 0; } /* * If we have more than blocksize, round down to nearest blocksize * multiple */ if(pos + bytes != fifoSize && bytes > (pos + bytes) % BLOCKSIZE) bytes -= (pos + bytes) % BLOCKSIZE; #if DEBUG flprintf("writing at pos=%p\n", fifo->dataBuffer + pos); #endif /* make sure we don't write to big a chunk... Better to * liberate small chunks one by one rather than attempt to * write out a bigger chunk and block reception for too * long */ if (bytes > 128 * 1024) bytes = 64 * 1024; bytes = write(outFile, fifo->dataBuffer + pos, bytes); if(bytes < 0) { perror("write"); exit(1); } pc_consumed(fifo->data, bytes); pc_produce(fifo->freeMemQueue, bytes); } } int openPipe(int outFile, struct disk_config *disk_config, int *pipePid) { if(disk_config->pipeName != NULL) { char *arg[256]; int filedes[2]; udpc_parseCommand(disk_config->pipeName, arg); if(pipe(filedes) < 0) { perror("pipe"); exit(1); } #ifdef O_BINARY setmode(filedes[0], O_BINARY); setmode(filedes[1], O_BINARY); #endif *pipePid=open2(filedes[0], outFile, arg, filedes[1]); close(filedes[0]); outFile = filedes[1]; } return outFile; } udpcast-20120424/config.sub0000644000175000017500000007740511745607103014350 0ustar alainalain#! /bin/sh # Configuration validation subroutine script. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, # Inc. timestamp='2006-08-14' # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software # can handle that machine. It does not imply ALL GNU software can. # # This file 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., 51 Franklin Street - Fifth Floor, Boston, MA # 02110-1301, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Please send patches to . Submit a context # diff and a properly formatted ChangeLog entry. # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS $0 [OPTION] ALIAS Canonicalize a configuration name. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.sub ($timestamp) Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" exit 1 ;; *local*) # First pass through any local machine types. echo $1 exit ;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \ uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \ storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; *) basic_machine=`echo $1 | sed 's/-[^-]*$//'` if [ $basic_machine != $1 ] then os=`echo $1 | sed 's/.*-/-/'` else os=; fi ;; esac ### Let's recognize common machines as not being operating systems so ### that things like config.sub decstation-3100 work. We also ### recognize some manufacturers as not being operating systems, so we ### can provide default operating systems below. case $os in -sun*os*) # Prevent following clause from handling this invalid input. ;; -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ -apple | -axis | -knuth | -cray) os= basic_machine=$1 ;; -sim | -cisco | -oki | -wec | -winbond) os= basic_machine=$1 ;; -scout) ;; -wrs) os=-vxworks basic_machine=$1 ;; -chorusos*) os=-chorusos basic_machine=$1 ;; -chorusrdb) os=-chorusrdb basic_machine=$1 ;; -hiux*) os=-hiuxwe2 ;; -sco6) os=-sco5v6 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5) os=-sco3.2v5 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco4) os=-sco3.2v4 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5v6*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -udk*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -lynx*) os=-lynxos ;; -ptx*) basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` ;; -windowsnt*) os=`echo $os | sed -e 's/windowsnt/winnt/'` ;; -psos*) os=-psos ;; -mint | -mint[0-9]*) basic_machine=m68k-atari os=-mint ;; esac # Decode aliases for certain CPU-COMPANY combinations. case $basic_machine in # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. 1750a | 580 \ | a29k \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ | bfin \ | c4x | clipper \ | d10v | d30v | dlx | dsp16xx \ | fr30 | frv \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ | m32c | m32r | m32rle | m68000 | m68k | m88k \ | maxq | mb | microblaze | mcore \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ | mips64vr | mips64vrel \ | mips64orion | mips64orionel \ | mips64vr4100 | mips64vr4100el \ | mips64vr4300 | mips64vr4300el \ | mips64vr5000 | mips64vr5000el \ | mips64vr5900 | mips64vr5900el \ | mipsisa32 | mipsisa32el \ | mipsisa32r2 | mipsisa32r2el \ | mipsisa64 | mipsisa64el \ | mipsisa64r2 | mipsisa64r2el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ | mt \ | msp430 \ | nios | nios2 \ | ns16k | ns32k \ | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ | pyramid \ | sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ | spu | strongarm \ | tahoe | thumb | tic4x | tic80 | tron \ | v850 | v850e \ | we32k \ | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \ | z8k) basic_machine=$basic_machine-unknown ;; m6811 | m68hc11 | m6812 | m68hc12) # Motorola 68HC11/12. basic_machine=$basic_machine-unknown os=-none ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) ;; ms1) basic_machine=mt-unknown ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i*86 | x86_64) basic_machine=$basic_machine-pc ;; # Object if more than one company name word. *-*-*) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; # Recognize the basic CPU types with company name. 580-* \ | a29k-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* | avr32-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | elxsi-* \ | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* | iq2000-* \ | m32c-* | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | m88110-* | m88k-* | maxq-* | mcore-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ | mips64vr-* | mips64vrel-* \ | mips64orion-* | mips64orionel-* \ | mips64vr4100-* | mips64vr4100el-* \ | mips64vr4300-* | mips64vr4300el-* \ | mips64vr5000-* | mips64vr5000el-* \ | mips64vr5900-* | mips64vr5900el-* \ | mipsisa32-* | mipsisa32el-* \ | mipsisa32r2-* | mipsisa32r2el-* \ | mipsisa64-* | mipsisa64el-* \ | mipsisa64r2-* | mipsisa64r2el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipstx39-* | mipstx39el-* \ | mmix-* \ | mt-* \ | msp430-* \ | nios-* | nios2-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ | pyramid-* \ | romp-* | rs6000-* \ | sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ | sparclite-* \ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \ | tahoe-* | thumb-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ | tron-* \ | v850-* | v850e-* | vax-* \ | we32k-* \ | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \ | xstormy16-* | xtensa-* \ | ymp-* \ | z8k-*) ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 386bsd) basic_machine=i386-unknown os=-bsd ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) basic_machine=m68000-att ;; 3b*) basic_machine=we32k-att ;; a29khif) basic_machine=a29k-amd os=-udi ;; abacus) basic_machine=abacus-unknown ;; adobe68k) basic_machine=m68010-adobe os=-scout ;; alliant | fx80) basic_machine=fx80-alliant ;; altos | altos3068) basic_machine=m68k-altos ;; am29k) basic_machine=a29k-none os=-bsd ;; amd64) basic_machine=x86_64-pc ;; amd64-*) basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; amdahl) basic_machine=580-amdahl os=-sysv ;; amiga | amiga-*) basic_machine=m68k-unknown ;; amigaos | amigados) basic_machine=m68k-unknown os=-amigaos ;; amigaunix | amix) basic_machine=m68k-unknown os=-sysv4 ;; apollo68) basic_machine=m68k-apollo os=-sysv ;; apollo68bsd) basic_machine=m68k-apollo os=-bsd ;; aux) basic_machine=m68k-apple os=-aux ;; balance) basic_machine=ns32k-sequent os=-dynix ;; c90) basic_machine=c90-cray os=-unicos ;; convex-c1) basic_machine=c1-convex os=-bsd ;; convex-c2) basic_machine=c2-convex os=-bsd ;; convex-c32) basic_machine=c32-convex os=-bsd ;; convex-c34) basic_machine=c34-convex os=-bsd ;; convex-c38) basic_machine=c38-convex os=-bsd ;; cray | j90) basic_machine=j90-cray os=-unicos ;; craynv) basic_machine=craynv-cray os=-unicosmp ;; cr16c) basic_machine=cr16c-unknown os=-elf ;; crds | unos) basic_machine=m68k-crds ;; crisv32 | crisv32-* | etraxfs*) basic_machine=crisv32-axis ;; cris | cris-* | etrax*) basic_machine=cris-axis ;; crx) basic_machine=crx-unknown os=-elf ;; da30 | da30-*) basic_machine=m68k-da30 ;; decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) basic_machine=mips-dec ;; decsystem10* | dec10*) basic_machine=pdp10-dec os=-tops10 ;; decsystem20* | dec20*) basic_machine=pdp10-dec os=-tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) basic_machine=m68k-motorola ;; delta88) basic_machine=m88k-motorola os=-sysv3 ;; djgpp) basic_machine=i586-pc os=-msdosdjgpp ;; dpx20 | dpx20-*) basic_machine=rs6000-bull os=-bosx ;; dpx2* | dpx2*-bull) basic_machine=m68k-bull os=-sysv3 ;; ebmon29k) basic_machine=a29k-amd os=-ebmon ;; elxsi) basic_machine=elxsi-elxsi os=-bsd ;; encore | umax | mmax) basic_machine=ns32k-encore ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson os=-ose ;; fx2800) basic_machine=i860-alliant ;; genix) basic_machine=ns32k-ns ;; gmicro) basic_machine=tron-gmicro os=-sysv ;; go32) basic_machine=i386-pc os=-go32 ;; h3050r* | hiux*) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; h8300hms) basic_machine=h8300-hitachi os=-hms ;; h8300xray) basic_machine=h8300-hitachi os=-xray ;; h8500hms) basic_machine=h8500-hitachi os=-hms ;; harris) basic_machine=m88k-harris os=-sysv3 ;; hp300-*) basic_machine=m68k-hp ;; hp300bsd) basic_machine=m68k-hp os=-bsd ;; hp300hpux) basic_machine=m68k-hp os=-hpux ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) basic_machine=m68000-hp ;; hp9k3[2-9][0-9]) basic_machine=m68k-hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) basic_machine=hppa1.1-hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) basic_machine=hppa1.1-hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; hppa-next) os=-nextstep3 ;; hppaosf) basic_machine=hppa1.1-hp os=-osf ;; hppro) basic_machine=hppa1.1-hp os=-proelf ;; i370-ibm* | ibm*) basic_machine=i370-ibm ;; # I'm not sure what "Sysv32" means. Should this be sysv3.2? i*86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; i*86v4*) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; i*86v) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv ;; i*86sol2) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; i386mach) basic_machine=i386-mach os=-mach ;; i386-vsta | vsta) basic_machine=i386-unknown os=-vsta ;; iris | iris4d) basic_machine=mips-sgi case $os in -irix*) ;; *) os=-irix4 ;; esac ;; isi68 | isi) basic_machine=m68k-isi os=-sysv ;; m88k-omron*) basic_machine=m88k-omron ;; magnum | m3230) basic_machine=mips-mips os=-sysv ;; merlin) basic_machine=ns32k-utek os=-sysv ;; mingw32) basic_machine=i386-pc os=-mingw32 ;; miniframe) basic_machine=m68000-convergent ;; *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) basic_machine=m68k-atari os=-mint ;; mips3*-*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ;; mips3*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; monitor) basic_machine=m68k-rom68k os=-coff ;; morphos) basic_machine=powerpc-unknown os=-morphos ;; msdos) basic_machine=i386-pc os=-msdos ;; ms1-*) basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` ;; mvs) basic_machine=i370-ibm os=-mvs ;; ncr3000) basic_machine=i486-ncr os=-sysv4 ;; netbsd386) basic_machine=i386-unknown os=-netbsd ;; netwinder) basic_machine=armv4l-rebel os=-linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony os=-newsos ;; news1000) basic_machine=m68030-sony os=-newsos ;; news-3600 | risc-news) basic_machine=mips-sony os=-newsos ;; necv70) basic_machine=v70-nec os=-sysv ;; next | m*-next ) basic_machine=m68k-next case $os in -nextstep* ) ;; -ns2*) os=-nextstep2 ;; *) os=-nextstep3 ;; esac ;; nh3000) basic_machine=m68k-harris os=-cxux ;; nh[45]000) basic_machine=m88k-harris os=-cxux ;; nindy960) basic_machine=i960-intel os=-nindy ;; mon960) basic_machine=i960-intel os=-mon960 ;; nonstopux) basic_machine=mips-compaq os=-nonstopux ;; np1) basic_machine=np1-gould ;; nsr-tandem) basic_machine=nsr-tandem ;; op50n-* | op60c-*) basic_machine=hppa1.1-oki os=-proelf ;; openrisc | openrisc-*) basic_machine=or32-unknown ;; os400) basic_machine=powerpc-ibm os=-os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson os=-ose ;; os68k) basic_machine=m68k-none os=-os68k ;; pa-hitachi) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; paragon) basic_machine=i860-intel os=-osf ;; pbd) basic_machine=sparc-tti ;; pbb) basic_machine=m68k-tti ;; pc532 | pc532-*) basic_machine=ns32k-pc532 ;; pc98) basic_machine=i386-pc ;; pc98-*) basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc ;; pentiumpro | p6 | 6x86 | athlon | athlon_*) basic_machine=i686-pc ;; pentiumii | pentium2 | pentiumiii | pentium3) basic_machine=i686-pc ;; pentium4) basic_machine=i786-pc ;; pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | 6x86-* | athlon-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium4-*) basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould ;; power) basic_machine=power-ibm ;; ppc) basic_machine=powerpc-unknown ;; ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle | ppc-le | powerpc-little) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64) basic_machine=powerpc64-unknown ;; ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64le | powerpc64little | ppc64-le | powerpc64-little) basic_machine=powerpc64le-unknown ;; ppc64le-* | powerpc64little-*) basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm ;; pw32) basic_machine=i586-unknown os=-pw32 ;; rdos) basic_machine=i386-pc os=-rdos ;; rom68k) basic_machine=m68k-rom68k os=-coff ;; rm[46]00) basic_machine=mips-siemens ;; rtpc | rtpc-*) basic_machine=romp-ibm ;; s390 | s390-*) basic_machine=s390-ibm ;; s390x | s390x-*) basic_machine=s390x-ibm ;; sa29200) basic_machine=a29k-amd os=-udi ;; sb1) basic_machine=mipsisa64sb1-unknown ;; sb1el) basic_machine=mipsisa64sb1el-unknown ;; sde) basic_machine=mipsisa32-sde os=-elf ;; sei) basic_machine=mips-sei os=-seiux ;; sequent) basic_machine=i386-sequent ;; sh) basic_machine=sh-hitachi os=-hms ;; sh64) basic_machine=sh64-unknown ;; sparclite-wrs | simso-wrs) basic_machine=sparclite-wrs os=-vxworks ;; sps7) basic_machine=m68k-bull os=-sysv2 ;; spur) basic_machine=spur-unknown ;; st2000) basic_machine=m68k-tandem ;; stratus) basic_machine=i860-stratus os=-sysv4 ;; sun2) basic_machine=m68000-sun ;; sun2os3) basic_machine=m68000-sun os=-sunos3 ;; sun2os4) basic_machine=m68000-sun os=-sunos4 ;; sun3os3) basic_machine=m68k-sun os=-sunos3 ;; sun3os4) basic_machine=m68k-sun os=-sunos4 ;; sun4os3) basic_machine=sparc-sun os=-sunos3 ;; sun4os4) basic_machine=sparc-sun os=-sunos4 ;; sun4sol2) basic_machine=sparc-sun os=-solaris2 ;; sun3 | sun3-*) basic_machine=m68k-sun ;; sun4) basic_machine=sparc-sun ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; sv1) basic_machine=sv1-cray os=-unicos ;; symmetry) basic_machine=i386-sequent os=-dynix ;; t3e) basic_machine=alphaev5-cray os=-unicos ;; t90) basic_machine=t90-cray os=-unicos ;; tic54x | c54x*) basic_machine=tic54x-unknown os=-coff ;; tic55x | c55x*) basic_machine=tic55x-unknown os=-coff ;; tic6x | c6x*) basic_machine=tic6x-unknown os=-coff ;; tx39) basic_machine=mipstx39-unknown ;; tx39el) basic_machine=mipstx39el-unknown ;; toad1) basic_machine=pdp10-xkl os=-tops20 ;; tower | tower-32) basic_machine=m68k-ncr ;; tpf) basic_machine=s390x-ibm os=-tpf ;; udi29k) basic_machine=a29k-amd os=-udi ;; ultra3) basic_machine=a29k-nyu os=-sym1 ;; v810 | necv810) basic_machine=v810-nec os=-none ;; vaxv) basic_machine=vax-dec os=-sysv ;; vms) basic_machine=vax-dec os=-vms ;; vpp*|vx|vx-*) basic_machine=f301-fujitsu ;; vxworks960) basic_machine=i960-wrs os=-vxworks ;; vxworks68) basic_machine=m68k-wrs os=-vxworks ;; vxworks29k) basic_machine=a29k-wrs os=-vxworks ;; w65*) basic_machine=w65-wdc os=-none ;; w89k-*) basic_machine=hppa1.1-winbond os=-proelf ;; xbox) basic_machine=i686-pc os=-mingw32 ;; xps | xps100) basic_machine=xps100-honeywell ;; ymp) basic_machine=ymp-cray os=-unicos ;; z8k-*-coff) basic_machine=z8k-unknown os=-sim ;; none) basic_machine=none-none os=-none ;; # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) basic_machine=hppa1.1-winbond ;; op50n) basic_machine=hppa1.1-oki ;; op60c) basic_machine=hppa1.1-oki ;; romp) basic_machine=romp-ibm ;; mmix) basic_machine=mmix-knuth ;; rs6000) basic_machine=rs6000-ibm ;; vax) basic_machine=vax-dec ;; pdp10) # there are many clones, so DEC is not a safe bet basic_machine=pdp10-unknown ;; pdp11) basic_machine=pdp11-dec ;; we32k) basic_machine=we32k-att ;; sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) basic_machine=sparc-sun ;; cydra) basic_machine=cydra-cydrome ;; orion) basic_machine=orion-highlevel ;; orion105) basic_machine=clipper-highlevel ;; mac | mpw | mac-mpw) basic_machine=m68k-apple ;; pmac | pmac-mpw) basic_machine=powerpc-apple ;; *-unknown) # Make sure to match an already-canonicalized machine name. ;; *) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; esac # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` ;; *-commodore*) basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if [ x"$os" != x"" ] then case $os in # First match some system type aliases # that might get confused with valid system types. # -solaris* is a basic system type, with this one exception. -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; -solaris) os=-solaris2 ;; -svr4*) os=-sysv4 ;; -unixware*) os=-sysv4.2uw ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; # First accept the basic system types. # The portable systems comes first. # Each alternative MUST END IN A *, to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ | -openbsd* | -solidbsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* \ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \ | -uxpv* | -beos* | -mpeix* | -udk* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ | -skyos* | -haiku* | -rdos* | -toppers*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) case $basic_machine in x86-* | i*86-*) ;; *) os=-nto$os ;; esac ;; -nto-qnx*) ;; -nto*) os=`echo $os | sed -e 's|nto|nto-qnx|'` ;; -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ;; -mac*) os=`echo $os | sed -e 's|mac|macos|'` ;; -linux-dietlibc) os=-linux-dietlibc ;; -linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; -sunos5*) os=`echo $os | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) os=`echo $os | sed -e 's|sunos6|solaris3|'` ;; -opened*) os=-openedition ;; -os400*) os=-os400 ;; -wince*) os=-wince ;; -osfrose*) os=-osfrose ;; -osf*) os=-osf ;; -utek*) os=-bsd ;; -dynix*) os=-bsd ;; -acis*) os=-aos ;; -atheos*) os=-atheos ;; -syllable*) os=-syllable ;; -386bsd) os=-bsd ;; -ctix* | -uts*) os=-sysv ;; -nova*) os=-rtmk-nova ;; -ns2 ) os=-nextstep2 ;; -nsk*) os=-nsk ;; # Preserve the version number of sinix5. -sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` ;; -sinix*) os=-sysv4 ;; -tpf*) os=-tpf ;; -triton*) os=-sysv3 ;; -oss*) os=-sysv3 ;; -svr4) os=-sysv4 ;; -svr3) os=-sysv3 ;; -sysvr4) os=-sysv4 ;; # This must come after -sysvr4. -sysv*) ;; -ose*) os=-ose ;; -es1800*) os=-ose ;; -xenix) os=-xenix ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) os=-mint ;; -aros*) os=-aros ;; -kaos*) os=-kaos ;; -zvmoe) os=-zvmoe ;; -none) ;; *) # Get rid of the `-' at the beginning of $os. os=`echo $os | sed 's/[^-]*-//'` echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 exit 1 ;; esac else # Here we handle the default operating systems that come with various machines. # The value should be what the vendor currently ships out the door with their # machine or put another way, the most popular os provided with the machine. # Note that if you're going to try to match "-MANUFACTURER" here (say, # "-sun"), then you have to tell the case statement up towards the top # that MANUFACTURER isn't an operating system. Otherwise, code above # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. case $basic_machine in spu-*) os=-elf ;; *-acorn) os=-riscix1.2 ;; arm*-rebel) os=-linux ;; arm*-semi) os=-aout ;; c4x-* | tic4x-*) os=-coff ;; # This must come before the *-dec entry. pdp10-*) os=-tops20 ;; pdp11-*) os=-none ;; *-dec | vax-*) os=-ultrix4.2 ;; m68*-apollo) os=-domain ;; i386-sun) os=-sunos4.0.2 ;; m68000-sun) os=-sunos3 # This also exists in the configure program, but was not the # default. # os=-sunos4 ;; m68*-cisco) os=-aout ;; mips*-cisco) os=-elf ;; mips*-*) os=-elf ;; or32-*) os=-coff ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 ;; sparc-* | *-sun) os=-sunos4.1.1 ;; *-be) os=-beos ;; *-haiku) os=-haiku ;; *-ibm) os=-aix ;; *-knuth) os=-mmixware ;; *-wec) os=-proelf ;; *-winbond) os=-proelf ;; *-oki) os=-proelf ;; *-hp) os=-hpux ;; *-hitachi) os=-hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) os=-sysv ;; *-cbm) os=-amigaos ;; *-dg) os=-dgux ;; *-dolphin) os=-sysv3 ;; m68k-ccur) os=-rtu ;; m88k-omron*) os=-luna ;; *-next ) os=-nextstep ;; *-sequent) os=-ptx ;; *-crds) os=-unos ;; *-ns) os=-genix ;; i370-*) os=-mvs ;; *-next) os=-nextstep3 ;; *-gould) os=-sysv ;; *-highlevel) os=-bsd ;; *-encore) os=-bsd ;; *-sgi) os=-irix ;; *-siemens) os=-sysv4 ;; *-masscomp) os=-rtu ;; f30[01]-fujitsu | f700-fujitsu) os=-uxpv ;; *-rom68k) os=-coff ;; *-*bug) os=-coff ;; *-apple) os=-macos ;; *-atari*) os=-mint ;; *) os=-none ;; esac fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. vendor=unknown case $basic_machine in *-unknown) case $os in -riscix*) vendor=acorn ;; -sunos*) vendor=sun ;; -aix*) vendor=ibm ;; -beos*) vendor=be ;; -hpux*) vendor=hp ;; -mpeix*) vendor=hp ;; -hiux*) vendor=hitachi ;; -unos*) vendor=crds ;; -dgux*) vendor=dg ;; -luna*) vendor=omron ;; -genix*) vendor=ns ;; -mvs* | -opened*) vendor=ibm ;; -os400*) vendor=ibm ;; -ptx*) vendor=sequent ;; -tpf*) vendor=ibm ;; -vxsim* | -vxworks* | -windiss*) vendor=wrs ;; -aux*) vendor=apple ;; -hms*) vendor=hitachi ;; -mpw* | -macos*) vendor=apple ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) vendor=atari ;; -vos*) vendor=stratus ;; esac basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac echo $basic_machine$os exit # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: udpcast-20120424/socklib.h0000444000175000017500000001363211064536603014155 0ustar alainalain#ifndef SOCKLIB_H #define SOCKLIB_H #ifndef UDPCAST_CONFIG_H # define UDPCAST_CONFIG_H # include "config.h" #endif #include #include #ifdef HAVE_SYS_SOCKET_H #include #endif #ifdef HAVE_SYS_SELECT_H #include #endif #ifdef HAVE_SYS_SOCKIO_H #include #endif #ifdef HAVE_NETINET_IN_H #include #endif #ifdef HAVE_NETDB_H #include #endif #ifdef HAVE_WINSOCK2_H #include #endif #ifdef HAVE_SYS_UIO_H #include #endif #ifdef __MINGW32__ #define WINDOWS #undef USE_SYSLOG #endif /* __MINGW32__ */ #ifdef __CYGWIN__ /* Untested so far ... */ #define WINDOWS #endif #define RECEIVER_PORT(x) (x) #define SENDER_PORT(x) ((x)+1) #define loseSendPacket udpc_loseSendPacket #define loseRecvPacket udpc_loseRecvPacket #define setWriteLoss udpc_setWriteLoss #define setReadLoss udpc_setReadLoss #define setReadSwap udpc_setReadSwap #define srandomTime udpc_srandomTime #define RecvMsg udpc_RecvMsg #define doAutoRateLimit udpc_doAutoRateLimit #define makeSockAddr udpc_makeSockAddr #define getMyAddress udpc_getMyAddress #define getBroadCastAddress udpc_getBroadCastAddress #define getMcastAllAddress udpc_getMcastAllAddress #define doSend udpc_doSend #define doReceive udpc_doReceive #define printMyIp udpc_printMyIp #define makeSocket udpc_makeSocket #define setSocketToBroadcast udpc_setSocketToBroadcast #define setTtl udpc_setTtl #define setMcastDestination udpc_setMcastDestination #define isFullDuplex udpc_isFullDuplex #define getNetIf udpc_getNetIf #define getSendBuf udpc_getSendBuf #define setSendBuf udpc_setSendBuf #define getRcvBuf udpc_getRcvBuf #define setRcvBuf udpc_setRcvBuf #define getPort udpc_getPort #define setPort udpc_setPort #define getIpString udpc_getIpString #define ipIsEqual udpc_ipIsEqual #define ipIsZero udpc_ipIsZero #define clearIp udpc_clearIp #define setIpFromString udpc_setIpFromString #define copyIpFrom udpc_copyIpFrom #define getDefaultMcastAddress udpc_getDefaultMcastAddress #define copyToMessage udpc_copyToMessage #define copyFromMessage udpc_copyFromMessage #define isAddressEqual udpc_isAddressEqual #define parseSize udpc_parseSize #define zeroSockArray udpc_zeroSockArray #define selectSock udpc_selectSock #define prepareForSelect udpc_prepareForSelect #define getSelectedSock udpc_getSelectedSock #define closeSock udpc_closeSock #ifdef LOSSTEST int loseSendPacket(void); void loseRecvPacket(int s); void setWriteLoss(char *l); void setReadLoss(char *l); void setReadSwap(char *l); void srandomTime(int printSeed); int RecvMsg(int s, struct msghdr *msg, int flags); #endif struct net_if { struct in_addr addr; struct in_addr bcast; const char *name; #ifdef SIOCGIFINDEX int index; #endif }; typedef struct net_if net_if_t; typedef enum addr_type_t { ADDR_TYPE_UCAST, ADDR_TYPE_MCAST, ADDR_TYPE_BCAST } addr_type_t; void doAutoRateLimit(int sock, int dir, int qsize, int size); int makeSockAddr(char *hostname, short port, struct sockaddr_in *addr); int getMyAddress(net_if_t *net_if, struct sockaddr_in *addr); int getBroadCastAddress(net_if_t *net_if, struct sockaddr_in *addr, short port); int getMcastAllAddress(struct sockaddr_in *addr, const char *address, short port); int doSend(int s, void *message, size_t len, struct sockaddr_in *to); int doReceive(int s, void *message, size_t len, struct sockaddr_in *from, int portBase); void printMyIp(net_if_t *net_if); int makeSocket(addr_type_t addr_type, net_if_t *net_if, struct sockaddr_in *tmpl, int port); int setSocketToBroadcast(int sock); int setTtl(int sock, int ttl); int setMcastDestination(int,net_if_t *,struct sockaddr_in *); int isFullDuplex(int sock, const char *ifName); net_if_t *getNetIf(const char *ifName); int getSendBuf(int sock); void setSendBuf(int sock, unsigned int bufsize); unsigned int getRcvBuf(int sock); void setRcvBuf(int sock, unsigned int bufsize); #define SEND(s, msg, to) \ doSend(s, &msg, sizeof(msg), &to) #define RECV(s, msg, from, portBase ) \ doReceive((s), &msg, sizeof(msg), &from, (portBase) ) #define BCAST_CONTROL(s, msg) \ doSend(s, &msg, sizeof(msg), &net_config->controlMcastAddr) unsigned short getPort(struct sockaddr_in *addr); void setPort(struct sockaddr_in *addr, unsigned short port); char *getIpString(struct sockaddr_in *addr, char *buffer); int ipIsEqual(struct sockaddr_in *left, struct sockaddr_in *right); int ipIsZero(struct sockaddr_in *ip); void clearIp(struct sockaddr_in *addr); void setIpFromString(struct sockaddr_in *addr, char *ip); void copyIpFrom(struct sockaddr_in *dst, struct sockaddr_in *src); void getDefaultMcastAddress(net_if_t *net_if, struct sockaddr_in *mcast); void copyToMessage(unsigned char *dst, struct sockaddr_in *src); void copyFromMessage(struct sockaddr_in *dst, unsigned char *src); int isAddressEqual(struct sockaddr_in *a, struct sockaddr_in *b); unsigned long parseSize(char *sizeString); void zeroSockArray(int *socks, int nr); int selectSock(int *socks, int nr, int startTimeout); int prepareForSelect(int *socks, int nr, fd_set *read_set); int getSelectedSock(int *socks, int nr, fd_set *read_set); void closeSock(int *socks, int nr, int target); int isMcastAddress(struct sockaddr_in *addr); int udpc_socklibFatal(int code); #ifdef __MINGW32__ /* __MINGW32__ */ struct iovec { void *iov_base; int iov_len; }; struct msghdr { void *msg_name; int msg_namelen; struct iovec *msg_iov; int msg_iovlen; }; ssize_t sendmsg(int s, const struct msghdr *msg, int flags); ssize_t recvmsg (int fd, struct msghdr *msg, int flags); #define usleep(x) Sleep((x)/1000) #define sleep(x) Sleep(1000L*(x)) #endif /* __MINGW32__ */ static inline void initMsgHdr(struct msghdr *hdr) { #ifndef WINDOWS hdr->msg_control = 0; hdr->msg_controllen = 0; hdr->msg_flags = 0; #endif } #ifndef __MINGW32__ #undef closesocket #define closesocket(x) close(x) #endif #ifndef HAVE_IN_ADDR_T typedef unsigned long in_addr_t; #endif #endif udpcast-20120424/html2man.pl0000555000175000017500000001476111110214664014434 0ustar alainalain#!/usr/bin/perl # # See COPYRIGHT # # Script to generate a pod file from an html source (the same one as for text files too) # and later this pod file it passed through pod2man # # Use: # html2man [ [] ] is the directory where the man pages will be created # (current directory by default). If a file name is given instead of # directory then the directory of that file is used. # is the directory containing the ttf2pt1 files version.h # and CHANGES.html which are used to generate the release name and date # for the man page (by default looks in current directory and then in up to # 5 ancestor directories). # If the version files can not be found then the release defaults to # "current" and the date defaults to today. # # Special formatting in the html file is: # All controls are hidden within HTML comments that must occupy a whole separate line # Such a line looks like: # # # Any sort of directive must be followed by a space. The pod directives are # automatically surrounded by empty lines in the output file. # The html2man directives are: # # # Define a man page. Multiple man pages can be defined in the same HTML # file. is a short name by which this man page will be referred in the # other directives. is the name of the man page, and
is the # section of the manual (do not confuse with sections within a man page). # # # All the text following this directive is copied (with translation) # into the specified section of the specified man page. The sections # may appear in arbitrary order, they will be rearranged to the standard # order before output. Only standard section names are permitted (see @stdsect # below). The pod directives which occur outside of man sections are ignored, # just like the common text. The translation of HTML tags is: # #
- to paragraph break # - to B<> # - to I<> # - to C<> # - to F<> #
    ,
  • ,
- to =over 2, =item *, =back #  , &, <, > - to their symbols, appropriately encoded # # The rest of HTML tags is removed # # If the same section is started more than once, the text from the # second appearance will be added to the first, etc. # # # Stop copying text to the man page. # # # Continue copying text to the man page, same section as before. # # # Insert this into the man page (works only when copying is enabled). # Characters <, >, & are converted as usual. use strict; use Getopt::Std; use vars qw($opt_d $opt_m); my @mons = qw(January February March April May June July August September October November December); getopts('d:m:'); my $dir = $opt_d; my $maindir = $opt_m; if($dir eq "") { $dir = "."; } elsif( ! -d $dir ) { if( ! ($dir =~ s|\/[^/]*$||) ) { $dir = "."; } } if($maindir eq "") { $maindir = "."; for(my $i=0; $i<5; $i++) { if(-f "$maindir/version.h") { last; } $maindir = "../$maindir"; } } my $release; my $date; if( open(VERFILE, "<$maindir/version.h") ) { while() { if( /^\s*\#define\s+TTF2PT1_VERSION\s+\"(.*)\"/ ) { $release = "version $1"; } } close(VERFILE); if( $release =~ /SNAP-([0-9][0-9])([0-9][0-9])([0-9][0-9])/ ) { $date = sprintf("%s %d, 20%02d", $mons[$2-1], $3, $1); } elsif( open(CFILE, "<$maindir/CHANGES.html") ) { while() { if( /\/) { last; } } $_ = ; chomp; if( $_ =~ s/^.*?-- // ) { $date = $_; } close(CFILE); } } if($release eq "") { $release = "current"; } if($date eq "") { my @lt = localtime(time); $date = sprintf("%s %d, %d", $mons[$lt[4]], $lt[3], 1900+$lt[5]); } #printf(STDERR "date=%s release=%s\n", $date, $release); my $writemode = 0; my %text; my @allids; my $tosect; my %file; my %mansect; if($ARGV[0] =~ /\.pl$/) { # print "Ignoring $ARGV[0]\n"; shift; } while(<>) { if( s/^\<\!\-\- \=(\S+)\s+//) { my $cmd = $1; s/\s*--\>\s*$//; #printf(STDERR "cmd=%s args=%s\n", $cmd, $_); if($cmd =~ /^=/) { if($writemode) { $text{$tosect} .= "\n\n$cmd $_\n\n"; } } elsif($cmd eq "defdoc") { my @sl = split; push(@allids, $sl[0]); $file{$sl[0]} = $sl[1]; $mansect{$sl[0]} = $sl[2]; } elsif($cmd eq "section") { # tosect includes the file id $tosect = $_; $text{$tosect} .= "\n\n"; $writemode = 1; } elsif($cmd eq "stop") { $writemode = 0; $text{$tosect} .= "\n"; } elsif($cmd eq "cont") { $writemode = 1; } elsif($cmd eq "text") { if($writemode) { s/\<\;//gi; s/\&\;/\&/gi; $text{$tosect} .= "$_\n"; } } } elsif($writemode) { s/^\s+//; s/\{/\&lbr;/g; s/\}/\&rbr;/g; s/\/\n\n/gi; #s/\/\n\n=over 4\n\n/gi; #s/\<\/blockquote\>/\n\n=back\n\n/gi; s/\/\n\n=over 4\n\n/gi; s/\<\/ul\>/\n\n=back\n\n/gi; s/\/\n\n=over 4\n\n/gi; s/\/\n\n/gi; s/\<\/dl\>/\n\n=back\n\n/gi; s/\\s*/\n\n=item \*\n\n/gi; s/\\s*(.*)/\n\n=item $1\n\n/gi; s/\(.*)\<\/h2\>/\n\n=head2 $1\n\n/gi; s/\(.*?)\<\/i\>/I\{$1\}/gi; s/\(.*?)\<\/b\>/B\{$1\}/gi; s/\(.*?)\<\/tt\>/C\{$1\}/gi; s/\
(.*?)\<\/a\>/F\{$1\}/gi; s/\<.*?\>//g; s/\{/\/g; s/\ \;/S< >/gi; s/\&\;/\&/gi; s/\<\;/E/gi; s/\>\;/E/gi; #s/\|/E/g; #s/\//E/g; s/\&lbr\;/\{/g; s/\&rbr\;/\}/g; s/ %s\n", fn, strerror(errno)); } #else #ifdef HAVE_LSEEK64 loff_t offset = lseek64(fd, 0, SEEK_CUR); if(offset != -1) printLongNum(offset); #else off_t offset = lseek(fd, 0, SEEK_CUR); if(offset != -1) fprintf(stderr, "%10d", offset); #endif #endif } } int udpc_shouldPrintUncompressedPos(int deflt, int fd, int ref) { if(deflt != -1) return deflt; if(ref == fd) return 0; /* No pipe used => printing "uncompressed" statistics would be redundant */ { #ifdef HAVE_LSEEK64 loff_t offset = lseek64(fd, 0, SEEK_CUR); #else off_t offset = lseek(fd, 0, SEEK_CUR); #endif if(offset != -1) return 1; } return 0; } void displayReceiverStats(receiver_stats_t rs, int isFinal) { long long timePassed; struct timeval tv_now; if(rs == NULL || rs->s.noProgress) return; gettimeofday(&tv_now, 0); if(!shouldPrint(&rs->s, &tv_now, isFinal)) return; fprintf(stderr, "bytes="); printLongNum(rs->totalBytes); fprintf(stderr, " ("); timePassed = tv_now.tv_sec - rs->tv_start.tv_sec; timePassed *= 1000000; timePassed += tv_now.tv_usec - rs->tv_start.tv_usec; if (timePassed != 0) { int mbps = (int) (rs->totalBytes * 800 / timePassed); fprintf(stderr, "%3d.%02d", mbps / 100, mbps % 100); } else { fprintf(stderr, "***.**"); } fprintf(stderr, " Mbps)"); if(rs->s.printUncompressedPos) printFilePosition(rs->s.fd); fprintf(stderr, "\r"); fflush(stderr); } struct sender_stats { FILE *log; unsigned long long totalBytes; unsigned long long retransmissions; int clNo; unsigned long periodBytes; struct timeval periodStart; long bwPeriod; struct stats s; }; sender_stats_t allocSenderStats(int fd, FILE *logfile, long bwPeriod, long statPeriod, int printUncompressedPos, int noProgress) { sender_stats_t ss = MALLOC(struct sender_stats); ss->log = logfile; ss->bwPeriod = bwPeriod; gettimeofday(&ss->periodStart, 0); initStats(&ss->s, fd, statPeriod, printUncompressedPos, noProgress); return ss; } void senderStatsAddBytes(sender_stats_t ss, long bytes) { if(ss != NULL) { ss->totalBytes += bytes; if(ss->bwPeriod) { double tdiff, bw; struct timeval tv; gettimeofday(&tv, 0); ss->periodBytes += bytes; if(tv.tv_sec - ss->periodStart.tv_sec < ss->bwPeriod-1) return; tdiff = (tv.tv_sec-ss->periodStart.tv_sec) * 1000000.0 + tv.tv_usec - ss->periodStart.tv_usec; if(tdiff < ss->bwPeriod * 1000000.0) return; bw = ss->periodBytes * 8.0 / tdiff; ss->periodBytes=0; ss->periodStart = tv; logprintf(ss->log, "Inst BW=%f\n", bw); fflush(ss->log); } } } void senderStatsAddRetransmissions(sender_stats_t ss, int retransmissions) { if(ss != NULL) { ss->retransmissions += retransmissions; logprintf(ss->log, "RETX %9lld %4d\n", ss->retransmissions, retransmissions); } } void displaySenderStats(sender_stats_t ss, int blockSize, int sliceSize, int isFinal) { unsigned int blocks, percent; struct timeval tv_now; if(ss == NULL || ss->s.noProgress) return; gettimeofday(&tv_now, 0); if(!shouldPrint(&ss->s, &tv_now, isFinal)) return; blocks = (ss->totalBytes + blockSize - 1) / blockSize; if(blocks == 0) percent = 0; else percent = (1000L * ss->retransmissions) / blocks; fprintf(stderr, "bytes="); printLongNum(ss->totalBytes); fprintf(stderr, " re-xmits=%07llu (%3u.%01u%%) slice=%04d ", ss->retransmissions, percent / 10, percent % 10, sliceSize); if(ss->s.printUncompressedPos) printFilePosition(ss->s.fd); fprintf(stderr, "- %3d\r", ss->clNo); fflush(stderr); } void senderSetAnswered(sender_stats_t ss, int clNo) { if(ss != NULL) ss->clNo = clNo; } udpcast-20120424/udpcast.c0000444000175000017500000000264210734432562014166 0ustar alainalain#include "log.h" #include "udpcast.h" #include "udpc_process.h" FILE *udpc_log; int udpc_parseCommand(char *pipeName, char **arg) { char *ptr; int i; int haveSpace; haveSpace=1; i=0; for(ptr=pipeName; *ptr; ptr++) { if(*ptr == ' ') { haveSpace=1; *ptr = '\0'; } else if(haveSpace) { arg[i++] = ptr; haveSpace=0; } if(i==256) { udpc_fatal(1, "Too many arguments for pipe command\n"); } } arg[i] = 0; return 0; } static int printProcessStatus(const char *message, int status) { #ifdef WIFEXITED if (WIFEXITED(status)) { if(WEXITSTATUS(status)) { udpc_flprintf("%s process died with code %d\n", message, WEXITSTATUS(status)); return(WEXITSTATUS(status)); } } else { if(WIFSIGNALED(status)) { udpc_flprintf("%s process caught signal %d\n", message, WTERMSIG(status)); return 1; } udpc_flprintf("%s process did not cleanly exit\n", message); return 1; } #else /* WIFEXITED */ if(status != 0) udpc_flprintf("%s process died with code %d\n", message, status); #endif /* WIFEXITED */ return 0; } /* wait for process. If process returned abnormally, print message, and * exit too. */ int udpc_waitForProcess(int pid, const char *message) { int status; /* wait for the writer to exit */ if(waitpid(pid,&status,0) < 0) { return 0; } return printProcessStatus(message, status); } udpcast-20120424/log.c0000444000175000017500000000547011606056250013301 0ustar alainalain#include #include #include #include #include #include #include #include #include "log.h" static int needNewline=0; static void printNewlineIfNeeded(void) { if (needNewline) { fprintf(stderr, "\n"); } needNewline=0; } static int vlogprintf(FILE *logfile, const char *fmt, va_list ap); /** * Print message to the log, if not null */ int logprintf(FILE *logfile, const char *fmt, ...) { va_list ap; va_start(ap, fmt); return vlogprintf(logfile, fmt, ap); } static int newlineSeen=1; static int vlogprintf(FILE *logfile, const char *fmt, va_list ap) { if(logfile != NULL) { char buf[9]; struct timeval tv; int r; if(newlineSeen) { gettimeofday(&tv, NULL); strftime(buf, sizeof(buf), "%H:%M:%S", localtime(&tv.tv_sec)); fprintf(logfile, "%s.%06ld ", buf, tv.tv_usec); } newlineSeen = (strchr(fmt, '\n') != NULL); r= vfprintf(logfile, fmt, ap); if(newlineSeen) fflush(logfile); return r; } else return -1; } /** * Print message to stdout, adding a newline "if needed" * A newline is needed if this function has not yet been invoked * since last statistics printout */ int flprintf(const char *fmt, ...) { va_list ap; va_start(ap, fmt); if(udpc_log) return vlogprintf(udpc_log, fmt, ap); else { printNewlineIfNeeded(); return vfprintf(stderr, fmt, ap); } } volatile int quitting = 0; /** * Print message to stdout, adding a newline "if needed" * A newline is needed if this function has not yet been invoked * since last statistics printout */ int fatal(int code, const char *fmt, ...) { va_list ap; va_start(ap, fmt); if(quitting) _exit(code); quitting=1; printNewlineIfNeeded(); vfprintf(stderr, fmt, ap); #if 0 assert(0); /* make it easyer to use a debugger to see where this came * from */ #endif exit(code); } int printLongNum(unsigned long long x) { /* fprintf(stderr, "%03d ", (int) ( x / 1000000000000LL ));*/ long long divisor; long long minDivisor; int nonzero; char suffix=' '; if(x > 1000000000000LL) { minDivisor = 1048576L; suffix='M'; } else if(x >= 1000000000) { minDivisor = 1024L; suffix='K'; } else { minDivisor = 1; suffix=' '; } divisor = minDivisor * 1000000LL; nonzero = 0; while(divisor >= minDivisor) { int digits; const char *format; digits = (int) ((x / divisor) % 1000); if (nonzero) { format = "%03d"; } else { format = "%3d"; } if (digits || nonzero) fprintf(stderr, format, digits); else fprintf(stderr, " "); if(digits) { nonzero = 1; } divisor = divisor / 1000; if(divisor >= minDivisor) fprintf(stderr, " "); else fprintf(stderr, "%c", suffix); } needNewline = 1; return 0; } udpcast-20120424/socklib.c0000444000175000017500000006542011606253565014157 0ustar alainalain#include "config.h" #include #include #include #include #include #include #include #ifdef HAVE_ARPA_INET_H # include #endif #ifdef HAVE_NETDB_H # include #endif #ifdef HAVE_NET_IF_H # include #endif #ifdef HAVE_SYS_IOCTL_H # include #endif #ifdef __MINGW32__ #include #define ioctl ioctlsocket #include #include #endif /* __MINGW32__ */ #include "log.h" #include "socklib.h" #include "util.h" #ifndef SOL_IP #define SOL_IP IPPROTO_IP #endif #ifdef __linux__ #include typedef unsigned long long u64; typedef unsigned int u32; typedef unsigned short u16; typedef unsigned char u8; #include #include #endif // for Darwin #ifdef _SIZEOF_ADDR_IFREQ #define IFREQ_SIZE(a) _SIZEOF_ADDR_IFREQ(a) #endif #ifndef DEBUG # define DEBUG 0 #endif #ifdef LOSSTEST /** * Packet loss/swap testing... */ long int write_loss = 0; long int read_loss = 0; long int read_swap = 0; unsigned int seed=0; int loseSendPacket(void) { if(write_loss) { long r = random(); if(r < write_loss) return 1; } return 0; } #define STASH_SIZE 64 static int stashed; static struct packetStash { unsigned char data[4092]; int size; } packetStash[STASH_SIZE]; /** * Lose a packet */ void loseRecvPacket(int s) { if(read_loss) { while(random() < read_loss) { int x; flprintf("Losing packet\n"); recv(s, (void *) &x, sizeof(x),0); } } if(read_swap) { while(stashed < STASH_SIZE && random() < read_swap) { int size; flprintf("Stashing packet %d\n", stashed); size = recv(s, packetStash[stashed].data, sizeof(packetStash[stashed].data),0); packetStash[stashed].size = size; stashed++; } } } /** * bring stored packet back up... */ int RecvMsg(int s, struct msghdr *msg, int flags) { if(read_swap && stashed) { if(random() / stashed < read_swap) { int slot = random() % stashed; int iovnr; char *data = packetStash[slot].data; int totalLen = packetStash[slot].size; int retBytes=0; flprintf("Bringing out %d\n", slot); for(iovnr=0; iovnr < msg->msg_iovlen; iovnr++) { int len = msg->msg_iov[iovnr].iov_len; if(len > totalLen) len = totalLen; memcpy(msg->msg_iov[iovnr].iov_base, data, len); totalLen -= len; data += len; retBytes += len; if(totalLen == 0) break; } packetStash[slot]=packetStash[stashed]; stashed--; return retBytes; } } return recvmsg(s, msg, flags); } void setWriteLoss(char *l) { write_loss = (long) (atof(l) * RAND_MAX); } void setReadLoss(char *l) { read_loss = (long) (atof(l) * RAND_MAX); } void setReadSwap(char *l) { read_swap = (long) (atof(l) * RAND_MAX); } void srandomTime(int printSeed) { struct timeval tv; long seed; gettimeofday(&tv, 0); seed = (tv.tv_usec * 2000) ^ tv.tv_sec; if(printSeed) flprintf("seed=%ld\n", seed); srandom(seed); } #endif /* makes a socket address */ int makeSockAddr(char *hostname, short port, struct sockaddr_in *addr) { struct hostent *host; memset ((char *) addr, 0, sizeof(struct sockaddr_in)); if (hostname && *hostname) { char *inaddr; int len; host = gethostbyname(hostname); if (host == NULL) { udpc_fatal(1, "Unknown host %s\n", hostname); } inaddr = host->h_addr_list[0]; len = host->h_length; memcpy((void *)&((struct sockaddr_in *)addr)->sin_addr, inaddr, len); } ((struct sockaddr_in *)addr)->sin_family = AF_INET; ((struct sockaddr_in *)addr)->sin_port = htons(port); return 0; } #ifdef HAVE_PTON # define INET_ATON(a,i) inet_pton(AF_INET,a,i) #else # ifdef HAVE_ATON # define INET_ATON(a,i) inet_aton(a,i) # else #ifndef INADDR_NONE #define INADDR_NONE ((in_addr_t)-1) #endif static inline int INET_ATON(const char *a, struct in_addr *i) { i->s_addr=inet_addr(a); if(i->s_addr == INADDR_NONE && strcmp(a, "255.255.255.255")) return 0; /* Address invalid */ return 1; /* Address valid */ } # endif #endif static int initSockAddress(addr_type_t addr_type, net_if_t *net_if, in_addr_t ip, unsigned short port, struct sockaddr_in *addr) { memset ((char *) addr, 0, sizeof(struct sockaddr_in)); addr->sin_family = AF_INET; addr->sin_port = htons(port); if(!net_if && addr_type != ADDR_TYPE_MCAST) udpc_fatal(1, "initSockAddr without ifname\n"); switch(addr_type) { case ADDR_TYPE_UCAST: addr->sin_addr = net_if->addr; break; case ADDR_TYPE_BCAST: addr->sin_addr = net_if->bcast; break; case ADDR_TYPE_MCAST: addr->sin_addr.s_addr = ip; break; } return 0; } int getMyAddress(net_if_t *net_if, struct sockaddr_in *addr) { return initSockAddress(ADDR_TYPE_UCAST, net_if, INADDR_ANY, 0, addr); } int getBroadCastAddress(net_if_t *net_if, struct sockaddr_in *addr, short port){ int r= initSockAddress(ADDR_TYPE_BCAST, net_if, INADDR_ANY, port, addr); if(addr->sin_addr.s_addr == 0) { /* Quick hack to make it work for loopback */ struct sockaddr_in ucast; initSockAddress(ADDR_TYPE_UCAST, net_if, INADDR_ANY, port, &ucast); if((ntohl(ucast.sin_addr.s_addr) & 0xff000000) == 0x7f000000) addr->sin_addr.s_addr = ucast.sin_addr.s_addr; } return r; } static int mcastListen(int sock, net_if_t *net_if, struct sockaddr_in *addr); static int safe_inet_aton(const char *address, struct in_addr *ip) { if(!INET_ATON(address, ip)) udpc_fatal(-1, "Bad address %s", address); return 0; } int getMcastAllAddress(struct sockaddr_in *addr, const char *address, short port){ struct in_addr ip; int ret; if(address == NULL || address[0] == '\0') safe_inet_aton("224.0.0.1", &ip); else { if((ret=safe_inet_aton(address, &ip))<0) return ret; } return initSockAddress(ADDR_TYPE_MCAST, NULL, ip.s_addr, port, addr); } int doSend(int s, void *message, size_t len, struct sockaddr_in *to) { /* flprintf("sent: %08x %d\n", *(int*) message, len);*/ #ifdef LOSSTEST loseSendPacket(); #endif return sendto(s, message, len, 0, (struct sockaddr*) to, sizeof(*to)); } int doReceive(int s, void *message, size_t len, struct sockaddr_in *from, int portBase) { socklen_t slen; int r; unsigned short port; char ipBuffer[16]; slen = sizeof(*from); #ifdef LOSSTEST loseRecvPacket(s); #endif r = recvfrom(s, message, len, 0, (struct sockaddr *)from, &slen); if (r < 0) return r; port = ntohs(from->sin_port); if(port != RECEIVER_PORT(portBase) && port != SENDER_PORT(portBase)) { udpc_flprintf("Bad message from port %s.%d\n", getIpString(from, ipBuffer), ntohs(((struct sockaddr_in *)from)->sin_port)); return -1; } /* flprintf("recv: %08x %d\n", *(int*) message, r);*/ return r; } int getSendBuf(int sock) { int bufsize; socklen_t len=sizeof(int); if(getsockopt(sock, SOL_SOCKET, SO_SNDBUF, (char*)&bufsize, &len) < 0) return -1; return bufsize; } void setSendBuf(int sock, unsigned int bufsize) { if(setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (char*)&bufsize, sizeof(bufsize))< 0) perror("Set send buffer"); } unsigned int getRcvBuf(int sock) { unsigned int bufsize; socklen_t len=sizeof(int); if(getsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char *)&bufsize, &len) < 0) return -1; return bufsize; } void setRcvBuf(int sock, unsigned int bufsize) { if(setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char*) &bufsize, sizeof(bufsize))< 0) perror("Set receiver buffer"); } int setSocketToBroadcast(int sock) { /* set the socket to broadcast */ int p = 1; return setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char *)&p, sizeof(int)); } int setTtl(int sock, int ttl) { /* set the socket to broadcast */ return setsockopt(sock, SOL_IP, IP_MULTICAST_TTL, (char*)&ttl, sizeof(int)); } #ifdef HAVE_STRUCT_IP_MREQN_IMR_IFINDEX # define IP_MREQN ip_mreqn #else # define IP_MREQN ip_mreq #endif #define getSinAddr(addr) (((struct sockaddr_in *) addr)->sin_addr) /** * Fill in the mreq structure with the given interface and address */ static int fillMreq(net_if_t *net_if, struct in_addr addr, struct IP_MREQN *mreq) { #ifdef HAVE_STRUCT_IP_MREQN_IMR_IFINDEX mreq->imr_ifindex = net_if->index; mreq->imr_address.s_addr = 0; #else mreq->imr_interface = net_if->addr; #endif mreq->imr_multiaddr = addr; return 0; } /** * Perform a multicast operation */ static int mcastOp(int sock, net_if_t *net_if, struct in_addr addr, int code, const char *message) { struct IP_MREQN mreq; int r; fillMreq(net_if, addr, &mreq); r = setsockopt(sock, SOL_IP, code, (char*)&mreq, sizeof(mreq)); if(r < 0) { perror(message); exit(1); } return 0; } /* struct in_addr getSinAddr(struct sockaddr_in *addr) { return ((struct sockaddr_in *) addr)->sin_addr; } */ /** * Set socket to listen on given multicast address Not 100% clean, it * would be preferable to make a new socket, and not only subscribe it * to the multicast address but also _bind_ to it. Indeed, subscribing * alone is not enough, as we may get traffic destined to multicast * address subscribed to by other apps on the machine. However, for * the moment, we skip this concern, as udpcast's main usage is * software installation, and in that case it runs on an otherwise * quiet system. */ static int mcastListen(int sock, net_if_t *net_if, struct sockaddr_in *addr) { return mcastOp(sock, net_if, getSinAddr(addr), IP_ADD_MEMBERSHIP, "Subscribe to multicast group"); } int setMcastDestination(int sock, net_if_t *net_if, struct sockaddr_in *addr) { #ifdef WINDOWS int r; struct sockaddr_in interface_addr; struct in_addr if_addr; getMyAddress(net_if, &interface_addr); if_addr = getSinAddr(&interface_addr); r = setsockopt (sock, IPPROTO_IP, IP_MULTICAST_IF, (char *) &if_addr, sizeof(if_addr)); if(r < 0) fatal(1, "Set multicast send interface"); return 0; #else /* IP_MULTICAST_IF not correctly supported on Cygwin */ return mcastOp(sock, net_if, getSinAddr(addr), IP_MULTICAST_IF, "Set multicast send interface"); #endif } #ifdef __MINGW32__ static MIB_IFROW *getIfRow(MIB_IFTABLE *iftab, DWORD dwIndex) { int j; /* Find the corresponding interface row (for name and * MAC address) */ for(j=0; jdwNumEntries; j++) { MIB_IFROW *ifrow = &iftab->table[j]; /* eth0, eth1, ... */ if(ifrow->dwIndex == dwIndex) return ifrow; } return NULL; } static char *fmtName(MIB_IFROW *ifrow) { char *out; int l = ifrow->dwDescrLen+1; if(ifrow->dwPhysAddrLen) l+=2+3*ifrow->dwPhysAddrLen; out = malloc(ifrow->dwDescrLen+l+1); if(!out) return NULL; memcpy(out, ifrow->bDescr, ifrow->dwDescrLen); out[ifrow->dwDescrLen]='\0'; if(ifrow->dwPhysAddrLen) { int k; char *ptr=out+strlen(out); strcpy(ptr, " ("); ptr+=2; for(k=0; kdwPhysAddrLen; k++) { if(k) *ptr++='-'; sprintf(ptr, "%02x", 255 & ifrow->bPhysAddr[k]); ptr += 2; } strcpy(ptr, ")"); } return out; } #endif /* __MINGW32__ */ #ifndef __MINGW32__ /** * Tests whether the given card has link * 0 no * 1 yes * -1 unknown */ static int hasLink(int s, const char *ifname) { #ifdef ETHTOOL_GLINK struct ifreq ifr; struct ethtool_value edata; edata.cmd = ETHTOOL_GLINK; strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)-1); ifr.ifr_data = (char *) &edata; if(ioctl(s, SIOCETHTOOL, &ifr) == -1) { /* Operation not supported */ return -1; } else { return edata.data; } #else return -1; #endif } #endif /** * Tests whether the given card operates in full duplex mode * 0 no * 1 yes * -1 unknown */ int isFullDuplex(int s, const char *ifname) { #ifdef ETHTOOL_GLINK struct ifreq ifr; struct ethtool_cmd ecmd; ecmd.cmd = ETHTOOL_GSET; strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)-1); ifr.ifr_data = (char *) &ecmd; if(ioctl(s, SIOCETHTOOL, &ifr) == -1) { /* Operation not supported */ return -1; } else { return ecmd.duplex; } #else return -1; #endif } /** * Canonize interface name. If attempt is not NULL, pick the interface * which has that address. * If attempt is NULL, pick interfaces in the following order of preference * 1. eth0 * 2. Anything starting with eth0: * 3. Anything starting with eth * 4. Anything else * 5. localhost * 6. zero address */ net_if_t *getNetIf(const char *wanted) { #ifndef __MINGW32__ struct ifreq *ifrp, *ifend, *chosen; struct ifconf ifc; int s; #else /* __MINGW32__ */ int i; int etherNo=-1; int wantedEtherNo=-2; /* Wanted ethernet interface */ MIB_IPADDRTABLE *iptab=NULL; MIB_IFTABLE *iftab=NULL; MIB_IPADDRROW *iprow, *chosen=NULL; MIB_IFROW *chosenIf=NULL; WORD wVersionRequested; /* Version of Winsock to load */ WSADATA wsaData; /* Winsock implementation details */ ULONG a; int r; #endif /* __MINGW32__ */ int lastGoodness=0; struct in_addr wantedAddress; int isAddress=0; int wantedLen=0; net_if_t *net_if; if(wanted == NULL) { wanted = getenv("IFNAME"); } if(wanted && INET_ATON(wanted, &wantedAddress)) isAddress=1; else wantedAddress.s_addr=0; if(wanted) wantedLen=strlen(wanted); net_if = MALLOC(net_if_t); if(net_if == NULL) udpc_fatal(1, "Out of memory error"); #ifndef __MINGW32__ s = socket(PF_INET, SOCK_DGRAM, 0); if (s < 0) { perror("make socket"); exit(1); } ifc.ifc_len = sizeof(struct ifreq) * 10; while(1) { int len = ifc.ifc_len; ifc.ifc_buf = (caddr_t) malloc(ifc.ifc_len); if(ifc.ifc_buf == NULL) { udpc_fatal(1, "Out of memory error"); } if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0 || ifc.ifc_len < (signed int)sizeof(struct ifreq)) { perror("udpcast: SIOCGIFCONF: "); exit(1); } if(len == ifc.ifc_len) { ifc.ifc_len += sizeof(struct ifreq) * 10; free(ifc.ifc_buf); } else break; } ifend = (struct ifreq *)((char *)ifc.ifc_buf + ifc.ifc_len); chosen=NULL; for (ifrp = (struct ifreq *) ifc.ifc_buf ; ifrp < ifend; #ifdef IFREQ_SIZE ifrp = IFREQ_SIZE(*ifrp) + (char *)ifrp #else ifrp++ #endif ) { unsigned long iaddr = getSinAddr(&ifrp->ifr_addr).s_addr; int goodness; if(ifrp->ifr_addr.sa_family != PF_INET) continue; if(wanted) { if(isAddress && iaddr == wantedAddress.s_addr) { goodness=8; } else if(strcmp(wanted, ifrp->ifr_name) ==0) { /* perfect match on interface name */ goodness=12; } else if(wanted != NULL && strncmp(wanted, ifrp->ifr_name, wantedLen) ==0) { /* prefix match on interface name */ goodness=7; } else { /* no match, try next */ continue; } } else { if(iaddr == 0) { /* disregard interfaces whose address is zero */ goodness = 1; } else if(iaddr == htonl(0x7f000001)) { /* disregard localhost type devices */ goodness = 2; } else if(strcmp("eth0", ifrp->ifr_name) == 0 || strcmp("en0", ifrp->ifr_name) == 0) { /* prefer first ethernet interface */ goodness = 6; } else if(strncmp("eth0:", ifrp->ifr_name, 5) == 0) { /* second choice: any secondary addresses of first ethernet */ goodness = 5; } else if(strncmp("eth", ifrp->ifr_name, 3) == 0 || strncmp("en", ifrp->ifr_name, 2) == 0) { /* and, if not available, any other ethernet device */ goodness = 4; } else { goodness = 3; } } if(hasLink(s, ifrp->ifr_name)) /* Good or unknown link status privileged over known * disconnected */ goodness += 3; /* If all else is the same, prefer interfaces that * have broadcast */ goodness = goodness * 2; if(goodness >= lastGoodness) { /* Privilege broadcast-enabled interfaces */ if(ioctl(s, SIOCGIFBRDADDR, ifrp) < 0) udpc_fatal(-1, "Error getting broadcast address for %s: %s", ifrp->ifr_name, strerror(errno)); if(getSinAddr(&ifrp->ifr_ifru.ifru_broadaddr).s_addr) goodness++; } if(goodness > lastGoodness) { chosen = ifrp; lastGoodness = goodness; net_if->addr.s_addr = iaddr; } } if(!chosen) { fprintf(stderr, "No suitable network interface found\n"); fprintf(stderr, "The following interfaces are available:\n"); for (ifrp = (struct ifreq *) ifc.ifc_buf ; ifrp < ifend; #ifdef IFREQ_SIZE ifrp = IFREQ_SIZE(*ifrp) + (char *)ifrp #else ifrp++ #endif ) { char buffer[16]; if(ifrp->ifr_addr.sa_family != PF_INET) continue; fprintf(stderr, "\t%s\t%s\n", ifrp->ifr_name, udpc_getIpString((struct sockaddr_in *)&ifrp->ifr_addr, buffer)); } exit(1); } net_if->name = strdup(chosen->ifr_name); #ifdef HAVE_STRUCT_IP_MREQN_IMR_IFINDEX /* Index for multicast subscriptions */ if(ioctl(s, SIOCGIFINDEX, chosen) < 0) udpc_fatal(-1, "Error getting index for %s: %s", net_if->name, strerror(errno)); net_if->index = chosen->ifr_ifindex; #endif /* Broadcast */ if(ioctl(s, SIOCGIFBRDADDR, chosen) < 0) udpc_fatal(-1, "Error getting broadcast address for %s: %s", net_if->name, strerror(errno)); net_if->bcast = getSinAddr(&chosen->ifr_ifru.ifru_broadaddr); close(s); free(ifc.ifc_buf); #else /* __MINGW32__ */ /* WINSOCK initialization */ wVersionRequested = MAKEWORD(2, 0); /* Request Winsock v2.0 */ if (WSAStartup(wVersionRequested, &wsaData) != 0) /* Load Winsock DLL */ { fprintf(stderr,"WSAStartup() failed"); exit(1); } /* End WINSOCK initialization */ a=0; r=GetIpAddrTable(iptab, &a, TRUE); iptab=malloc(a); r=GetIpAddrTable(iptab, &a, TRUE); a=0; r=GetIfTable(iftab, &a, TRUE); iftab=malloc(a); r=GetIfTable(iftab, &a, TRUE); if(wanted && !strncmp(wanted, "eth", 3) && wanted[3]) { char *ptr; int n = strtoul(wanted+3, &ptr, 10); if(!*ptr) wantedEtherNo=n; } for(i=0; idwNumEntries; i++) { int goodness=-1; unsigned long iaddr; int isEther=0; MIB_IFROW *ifrow; iprow = &iptab->table[i]; iaddr = iprow->dwAddr; ifrow = getIfRow(iftab, iprow->dwIndex); if(ifrow && ifrow->dwPhysAddrLen == 6 && iprow->dwBCastAddr) { isEther=1; etherNo++; } if(wanted) { if(isAddress && iaddr == wantedAddress.s_addr) { goodness=8; } else if(isEther && wantedEtherNo == etherNo) { goodness=9; } else if(ifrow->dwPhysAddrLen) { int j; const char *ptr=wanted; for(j=0; *ptr && jdwPhysAddrLen; j++) { int digit = strtoul(ptr, (char**)&ptr, 16); if(digit != ifrow->bPhysAddr[j]) break; /* Digit mismatch */ if(*ptr == '-' || *ptr == ':') { ptr++; } } if(!*ptr && j == ifrow->dwPhysAddrLen) { goodness=9; } } } else { if(iaddr == 0) { /* disregard interfaces whose address is zero */ goodness = 1; } else if(iaddr == htonl(0x7f000001)) { /* disregard localhost type devices */ goodness = 2; } else if(isEther) { /* prefer ethernet */ goodness = 6; } else if(ifrow->dwPhysAddrLen) { /* then prefer interfaces which have a physical address */ goodness = 4; } else { goodness = 3; } } goodness = goodness * 2; /* If all else is the same, prefer interfaces that * have broadcast */ if(goodness >= lastGoodness) { /* Privilege broadcast-enabled interfaces */ if(iprow->dwBCastAddr) goodness++; } if(goodness > lastGoodness) { chosen = iprow; chosenIf = ifrow; lastGoodness = goodness; } } if(!chosen) { fprintf(stderr, "No suitable network interface found%s%s\n", wanted ? " for " : "", wanted ? wanted : ""); fprintf(stderr, "The following interfaces are available:\n"); for(i=0; idwNumEntries; i++) { char buffer[16]; struct sockaddr_in addr; MIB_IFROW *ifrow; char *name=NULL; iprow = &iptab->table[i]; addr.sin_addr.s_addr = iprow->dwAddr; ifrow = getIfRow(iftab, iprow->dwIndex); name = fmtName(ifrow); fprintf(stderr, " %15s %s\n", udpc_getIpString(&addr, buffer), name ? name : ""); if(name) free(name); } exit(1); } net_if->bcast.s_addr = net_if->addr.s_addr = chosen->dwAddr; if(chosen->dwBCastAddr) net_if->bcast.s_addr |= ~chosen->dwMask; if(chosenIf) { net_if->name = fmtName(chosenIf); } else { net_if->name = "*"; } free(iftab); free(iptab); #endif /* __MINGW32__ */ return net_if; } /** * @param addr_type * UCAST - my unicast address attached to this device * BCAST - my broadcast addres attached to this device * MCAST - multicast address * @param ifname * Interface name * @param mcast * Multicast address (only used if type MCAST) * @param port * Port to bind address to */ int makeSocket(addr_type_t addr_type, net_if_t *net_if, struct sockaddr_in *tmpl, int port) { int ret, s; struct sockaddr_in myaddr; in_addr_t ip=0; #ifdef WINDOWS static int lastSocket=-1; /* Very ugly hack, but hey!, this is for Windows */ if(addr_type == ADDR_TYPE_MCAST) { mcastListen(lastSocket, net_if, tmpl); return -1; } else if(addr_type != ADDR_TYPE_UCAST) return -1; #endif s = socket(PF_INET, SOCK_DGRAM, 0); if (s < 0) { perror("make socket"); exit(1); } if(addr_type == ADDR_TYPE_MCAST && tmpl != NULL) { ip = tmpl->sin_addr.s_addr; } ret = initSockAddress(addr_type, net_if, ip, port, &myaddr); if(ret < 0) udpc_fatal(1, "Could not get socket address fot %d/%s", addr_type, net_if->name); if(addr_type == ADDR_TYPE_BCAST && myaddr.sin_addr.s_addr == 0) { /* Attempting to bind to broadcast address on not-broadcast media ... */ closesocket(s); return -1; } ret = bind(s, (struct sockaddr *) &myaddr, sizeof(myaddr)); if (ret < 0) { char buffer[16]; udpc_fatal(1, "bind socket to %s:%d (%s)\n", udpc_getIpString(&myaddr, buffer), udpc_getPort(&myaddr), strerror(errno)); } if(addr_type == ADDR_TYPE_MCAST) mcastListen(s, net_if, &myaddr); #ifdef WINDOWS lastSocket=s; #endif return s; } void printMyIp(net_if_t *net_if) { char buffer[16]; struct sockaddr_in myaddr; getMyAddress(net_if, &myaddr); udpc_flprintf("%s", udpc_getIpString(&myaddr,buffer)); } char *udpc_getIpString(struct sockaddr_in *addr, char *buffer) { long iaddr = htonl(getSinAddr(addr).s_addr); sprintf(buffer,"%ld.%ld.%ld.%ld", (iaddr >> 24) & 0xff, (iaddr >> 16) & 0xff, (iaddr >> 8) & 0xff, iaddr & 0xff); return buffer; } int ipIsEqual(struct sockaddr_in *left, struct sockaddr_in *right) { return getSinAddr(left).s_addr == getSinAddr(right).s_addr; } int ipIsZero(struct sockaddr_in *ip) { return getSinAddr(ip).s_addr == 0; } unsigned short udpc_getPort(struct sockaddr_in *addr) { return ntohs(((struct sockaddr_in *) addr)->sin_port); } void setPort(struct sockaddr_in *addr, unsigned short port) { ((struct sockaddr_in *) addr)->sin_port = htons(port); } void clearIp(struct sockaddr_in *addr) { addr->sin_addr.s_addr = 0; addr->sin_family = AF_INET; } void setIpFromString(struct sockaddr_in *addr, char *ip) { safe_inet_aton(ip, &addr->sin_addr); addr->sin_family = AF_INET; } void copyIpFrom(struct sockaddr_in *dst, struct sockaddr_in *src) { dst->sin_addr = src->sin_addr; dst->sin_family = src->sin_family; } void getDefaultMcastAddress(net_if_t *net_if, struct sockaddr_in *mcast) { getMyAddress(net_if, mcast); mcast->sin_addr.s_addr &= htonl(0x07ffffff); mcast->sin_addr.s_addr |= htonl(0xe8000000); } void copyToMessage(unsigned char *dst, struct sockaddr_in *src) { memcpy(dst, (char *) &((struct sockaddr_in *)src)->sin_addr, sizeof(struct in_addr)); } void copyFromMessage(struct sockaddr_in *dst, unsigned char *src) { memcpy((char *) &dst->sin_addr, src, sizeof(struct in_addr)); } int isAddressEqual(struct sockaddr_in *a, struct sockaddr_in *b) { return !memcmp((char *) a, (char *)b, 8); } unsigned long parseSize(char *sizeString) { char *eptr; unsigned long size = strtoul(sizeString, &eptr, 10); if(eptr && *eptr) { switch(*eptr) { case 'm': case 'M': size *= 1024 * 1024; break; case 'k': case 'K': size *= 1024; break; case '\0': break; default: udpc_fatal(1, "Unit %c unsupported\n", *eptr); } } return size; } void zeroSockArray(int *socks, int nr) { int i; for(i=0; i maxFd) maxFd = socks[i]; } return maxFd; } int getSelectedSock(int *socks, int nr, fd_set *read_set) { int i; for(i=0; isin_addr.s_addr) >> 24; return ip >= 0xe0 && ip < 0xf0; } #ifdef __MINGW32__ static ssize_t getLength(const struct msghdr *msg) { ssize_t size=0; int i; for(i=0; imsg_iovlen; i++) { size += msg->msg_iov[i].iov_len; } return size; } static void doCopy(const struct msghdr *msg, char *ptr, int n, int dir) { int i; for(i=0; n >=0 && imsg_iovlen; i++) { int l = msg->msg_iov[i].iov_len; if(l > n) l = n; if(dir) { memcpy(msg->msg_iov[i].iov_base, ptr, l); } else { memcpy(ptr, msg->msg_iov[i].iov_base, l); } n -= l; ptr += l; } } ssize_t recvmsg(int s, struct msghdr *msg, int flags) { ssize_t size=getLength(msg); char *buffer = malloc(size); int n; /* bytes left to copy */ if(buffer == NULL) { /* Out of memory */ errno = ENOMEM; return -1; } n = recvfrom(s, buffer, size, flags, msg->msg_name, &msg->msg_namelen); doCopy(msg, buffer, n, 1); free(buffer); return n; } ssize_t sendmsg (int fd, const struct msghdr *msg, int flags) { ssize_t size=getLength(msg); char *buffer = malloc(size); int n; if(buffer == NULL) { /* Out of memory */ errno = ENOMEM; return -1; } doCopy(msg, buffer, size, 0); n = sendto(fd, buffer, size, flags, msg->msg_name, msg->msg_namelen); free(buffer); return n; } #endif /* __MINGW32__ */ udpcast-20120424/config.guess0000644000175000017500000012626011745607103014677 0ustar alainalain#! /bin/sh # Attempt to guess a canonical system name. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, # Inc. timestamp='2006-07-02' # This file 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., 51 Franklin Street - Fifth Floor, Boston, MA # 02110-1301, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Per Bothner . # Please send patches to . Submit a context # diff and a properly formatted ChangeLog entry. # # This script attempts to guess a canonical system name similar to # config.sub. If it succeeds, it prints the system name on stdout, and # exits with 0. Otherwise, it exits with 1. # # The plan is that this can be called by configure scripts if you # don't specify an explicit build system type. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; * ) break ;; esac done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi trap 'exit 1' 1 2 15 # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. # Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still # use `HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. set_cc_for_build=' trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; : ${TMPDIR=/tmp} ; { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; dummy=$tmp/dummy ; tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; case $CC_FOR_BUILD,$HOST_CC,$CC in ,,) echo "int x;" > $dummy.c ; for c in cc gcc c89 c99 ; do if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then CC_FOR_BUILD="$c"; break ; fi ; done ; if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found ; fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; esac ; set_cc_for_build= ;' # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) if (test -f /.attbin/uname) >/dev/null 2>&1 ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ /usr/sbin/$sysctl 2>/dev/null || echo unknown)` case "${UNAME_MACHINE_ARCH}" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; *) machine=${UNAME_MACHINE_ARCH}-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently, or will in the future. case "${UNAME_MACHINE_ARCH}" in arm*|i386|m68k|ns32k|sh3*|sparc|vax) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep __ELF__ >/dev/null then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi ;; *) os=netbsd ;; esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. case "${UNAME_VERSION}" in Debian*) release='-gnu' ;; *) release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. echo "${machine}-${os}${release}" exit ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} exit ;; *:ekkoBSD:*:*) echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} exit ;; *:SolidBSD:*:*) echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} exit ;; macppc:MirBSD:*:*) echo powerpc-unknown-mirbsd${UNAME_RELEASE} exit ;; *:MirBSD:*:*) echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} exit ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` ;; *5.*) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case "$ALPHA_CPU_TYPE" in "EV4 (21064)") UNAME_MACHINE="alpha" ;; "EV4.5 (21064)") UNAME_MACHINE="alpha" ;; "LCA4 (21066/21068)") UNAME_MACHINE="alpha" ;; "EV5 (21164)") UNAME_MACHINE="alphaev5" ;; "EV5.6 (21164A)") UNAME_MACHINE="alphaev56" ;; "EV5.6 (21164PC)") UNAME_MACHINE="alphapca56" ;; "EV5.7 (21164PC)") UNAME_MACHINE="alphapca57" ;; "EV6 (21264)") UNAME_MACHINE="alphaev6" ;; "EV6.7 (21264A)") UNAME_MACHINE="alphaev67" ;; "EV6.8CB (21264C)") UNAME_MACHINE="alphaev68" ;; "EV6.8AL (21264B)") UNAME_MACHINE="alphaev68" ;; "EV6.8CX (21264D)") UNAME_MACHINE="alphaev68" ;; "EV6.9A (21264/EV69A)") UNAME_MACHINE="alphaev69" ;; "EV7 (21364)") UNAME_MACHINE="alphaev7" ;; "EV7.9 (21364A)") UNAME_MACHINE="alphaev79" ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` exit ;; Alpha\ *:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # Should we change UNAME_MACHINE based on the output of uname instead # of the specific Alpha model? echo alpha-pc-interix exit ;; 21064:Windows_NT:50:3) echo alpha-dec-winnt3.5 exit ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 exit ;; *:[Aa]miga[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-amigaos exit ;; *:[Mm]orph[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-morphos exit ;; *:OS/390:*:*) echo i370-ibm-openedition exit ;; *:z/VM:*:*) echo s390-ibm-zvmoe exit ;; *:OS400:*:*) echo powerpc-ibm-os400 exit ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit ;; arm:riscos:*:*|arm:RISCOS:*:*) echo arm-unknown-riscos exit ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) echo hppa1.1-hitachi-hiuxmpp exit ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. if test "`(/bin/universe) 2>/dev/null`" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd fi exit ;; NILE*:*:*:dcosx) echo pyramid-pyramid-svr4 exit ;; DRS?6000:unix:4.0:6*) echo sparc-icl-nx6 exit ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) case `/usr/bin/uname -p` in sparc) echo sparc-icl-nx7; exit ;; esac ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; i86pc:SunOS:5.*:*) echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` exit ;; sun3*:SunOS:*:*) echo m68k-sun-sunos${UNAME_RELEASE} exit ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) echo m68k-sun-sunos${UNAME_RELEASE} ;; sun4) echo sparc-sun-sunos${UNAME_RELEASE} ;; esac exit ;; aushp:SunOS:*:*) echo sparc-auspex-sunos${UNAME_RELEASE} exit ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) echo m68k-milan-mint${UNAME_RELEASE} exit ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) echo m68k-hades-mint${UNAME_RELEASE} exit ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) echo m68k-unknown-mint${UNAME_RELEASE} exit ;; m68k:machten:*:*) echo m68k-apple-machten${UNAME_RELEASE} exit ;; powerpc:machten:*:*) echo powerpc-apple-machten${UNAME_RELEASE} exit ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit ;; RISC*:ULTRIX:*:*) echo mips-dec-ultrix${UNAME_RELEASE} exit ;; VAX*:ULTRIX*:*:*) echo vax-dec-ultrix${UNAME_RELEASE} exit ;; 2020:CLIX:*:* | 2430:CLIX:*:*) echo clipper-intergraph-clix${UNAME_RELEASE} exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && SYSTEM_NAME=`$dummy $dummyarg` && { echo "$SYSTEM_NAME"; exit; } echo mips-mips-riscos${UNAME_RELEASE} exit ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax exit ;; Motorola:*:4.3:PL8-*) echo powerpc-harris-powermax exit ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) echo powerpc-harris-powermax exit ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix exit ;; m88k:CX/UX:7*:*) echo m88k-harris-cxux7 exit ;; m88k:*:4*:R4*) echo m88k-motorola-sysv4 exit ;; m88k:*:3*:R3*) echo m88k-motorola-sysv3 exit ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] then if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ [ ${TARGET_BINARY_INTERFACE}x = x ] then echo m88k-dg-dgux${UNAME_RELEASE} else echo m88k-dg-dguxbcs${UNAME_RELEASE} fi else echo i586-dg-dgux${UNAME_RELEASE} fi exit ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit ;; M88*:*:R3*:*) # Delta 88k system running SVR3 echo m88k-motorola-sysv3 exit ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) echo m88k-tektronix-sysv3 exit ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) echo m68k-tektronix-bsd exit ;; *:IRIX*:*:*) echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` exit ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) echo i386-ibm-aix exit ;; ia64:AIX:*:*) if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` then echo "$SYSTEM_NAME" else echo rs6000-ibm-aix3.2.5 fi elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 else echo rs6000-ibm-aix3.2 fi exit ;; *:AIX:*:[45]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${IBM_ARCH}-ibm-aix${IBM_REV} exit ;; *:AIX:*:*) echo rs6000-ibm-aix exit ;; ibmrt:4.4BSD:*|romp-ibm:BSD:*) echo romp-ibm-bsd4.4 exit ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to exit ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx exit ;; DPX/2?00:B.O.S.:*:*) echo m68k-bull-sysv3 exit ;; 9000/[34]??:4.3bsd:1.*:*) echo m68k-hp-bsd exit ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 exit ;; 9000/[34678]??:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` case "${UNAME_MACHINE}" in 9000/31? ) HP_ARCH=m68000 ;; 9000/[34]?? ) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case "${sc_cpu_version}" in 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case "${sc_kernel_bits}" in 32) HP_ARCH="hppa2.0n" ;; 64) HP_ARCH="hppa2.0w" ;; '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 esac ;; esac fi if [ "${HP_ARCH}" = "" ]; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #define _HPUX_SOURCE #include #include int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac if [ ${HP_ARCH} = "hppa2.0w" ] then eval $set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler # generating 64-bit code. GNU and HP use different nomenclature: # # $ CC_FOR_BUILD=cc ./config.guess # => hppa2.0w-hp-hpux11.23 # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | grep __LP64__ >/dev/null then HP_ARCH="hppa2.0w" else HP_ARCH="hppa64" fi fi echo ${HP_ARCH}-hp-hpux${HPUX_REV} exit ;; ia64:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` echo ia64-hp-hpux${HPUX_REV} exit ;; 3050*:HI-UX:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } echo unknown-hitachi-hiuxwe2 exit ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) echo hppa1.1-hp-bsd exit ;; 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) echo hppa1.1-hp-osf exit ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf exit ;; i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then echo ${UNAME_MACHINE}-unknown-osf1mk else echo ${UNAME_MACHINE}-unknown-osf1 fi exit ;; parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd exit ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd exit ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd exit ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*[A-Z]90:*:*:*) echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*T3E:*:*:*) echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*SV1:*:*:*) echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; *:UNICOS/mp:*:*) echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} exit ;; sparc*:BSD/OS:*:*) echo sparc-unknown-bsdi${UNAME_RELEASE} exit ;; *:BSD/OS:*:*) echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit ;; *:FreeBSD:*:*) case ${UNAME_MACHINE} in pc98) echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; amd64) echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; *) echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; esac exit ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit ;; i*:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit ;; i*:windows32*:*) # uname -m includes "-pc" on this system. echo ${UNAME_MACHINE}-mingw32 exit ;; i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit ;; x86:Interix*:[3456]*) echo i586-pc-interix${UNAME_RELEASE} exit ;; EM64T:Interix*:[3456]*) echo x86_64-unknown-interix${UNAME_RELEASE} exit ;; [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) echo i${UNAME_MACHINE}-pc-mks exit ;; i*:Windows_NT*:* | Pentium*:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we # UNAME_MACHINE based on the output of uname instead of i386? echo i586-pc-interix exit ;; i*:UWIN*:*) echo ${UNAME_MACHINE}-pc-uwin exit ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) echo x86_64-unknown-cygwin exit ;; p*:CYGWIN*:*) echo powerpcle-unknown-cygwin exit ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; *:GNU:*:*) # the GNU system echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu exit ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit ;; arm*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; avr32*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; cris:Linux:*:*) echo cris-axis-linux-gnu exit ;; crisv32:Linux:*:*) echo crisv32-axis-linux-gnu exit ;; frv:Linux:*:*) echo frv-unknown-linux-gnu exit ;; ia64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; m32r*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; m68*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; mips:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef mips #undef mipsel #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=mipsel #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=mips #else CPU= #endif #endif EOF eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' /^CPU/{ s: ::g p }'`" test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } ;; mips64:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef mips64 #undef mips64el #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=mips64el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=mips64 #else CPU= #endif #endif EOF eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' /^CPU/{ s: ::g p }'`" test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } ;; or32:Linux:*:*) echo or32-unknown-linux-gnu exit ;; ppc:Linux:*:*) echo powerpc-unknown-linux-gnu exit ;; ppc64:Linux:*:*) echo powerpc64-unknown-linux-gnu exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; PCA57) UNAME_MACHINE=alphapca56 ;; EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in PA7*) echo hppa1.1-unknown-linux-gnu ;; PA8*) echo hppa2.0-unknown-linux-gnu ;; *) echo hppa-unknown-linux-gnu ;; esac exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) echo hppa64-unknown-linux-gnu exit ;; s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-ibm-linux exit ;; sh64*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; sh*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; vax:Linux:*:*) echo ${UNAME_MACHINE}-dec-linux-gnu exit ;; x86_64:Linux:*:*) echo x86_64-unknown-linux-gnu exit ;; i*86:Linux:*:*) # The BFD linker knows what the default object file format is, so # first see if it will tell us. cd to the root directory to prevent # problems with other programs or directories called `ld' in the path. # Set LC_ALL=C to ensure ld outputs messages in English. ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ | sed -ne '/supported targets:/!d s/[ ][ ]*/ /g s/.*supported targets: *// s/ .*// p'` case "$ld_supported_targets" in elf32-i386) TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" ;; a.out-i386-linux) echo "${UNAME_MACHINE}-pc-linux-gnuaout" exit ;; coff-i386) echo "${UNAME_MACHINE}-pc-linux-gnucoff" exit ;; "") # Either a pre-BFD a.out linker (linux-gnuoldld) or # one that does not give us useful --help. echo "${UNAME_MACHINE}-pc-linux-gnuoldld" exit ;; esac # Determine whether the default compiler is a.out or elf eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include #ifdef __ELF__ # ifdef __GLIBC__ # if __GLIBC__ >= 2 LIBC=gnu # else LIBC=gnulibc1 # endif # else LIBC=gnulibc1 # endif #else #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) LIBC=gnu #else LIBC=gnuaout #endif #endif #ifdef __dietlibc__ LIBC=dietlibc #endif EOF eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' /^LIBC/{ s: ::g p }'`" test x"${LIBC}" != x && { echo "${UNAME_MACHINE}-pc-linux-${LIBC}" exit } test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; } ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. echo i386-sequent-sysv4 exit ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} exit ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. echo ${UNAME_MACHINE}-pc-os2-emx exit ;; i*86:XTS-300:*:STOP) echo ${UNAME_MACHINE}-unknown-stop exit ;; i*86:atheos:*:*) echo ${UNAME_MACHINE}-unknown-atheos exit ;; i*86:syllable:*:*) echo ${UNAME_MACHINE}-pc-syllable exit ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) echo i386-unknown-lynxos${UNAME_RELEASE} exit ;; i*86:*DOS:*:*) echo ${UNAME_MACHINE}-pc-msdosdjgpp exit ;; i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} else echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} fi exit ;; i*86:*:5:[678]*) # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} exit ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 echo ${UNAME_MACHINE}-pc-sco$UNAME_REL else echo ${UNAME_MACHINE}-pc-sysv32 fi exit ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i386. echo i386-pc-msdosdjgpp exit ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit ;; paragon:*:*:*) echo i860-intel-osf1 exit ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 fi exit ;; mini*:CTIX:SYS*5:*) # "miniframe" echo m68010-convergent-sysv exit ;; mc68k:UNIX:SYSTEM5:3.51m) echo m68k-convergent-sysv exit ;; M680?0:D-NIX:5.3:*) echo m68k-diab-dnix exit ;; M68*:*:R3V[5678]*:*) test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) echo m68k-unknown-lynxos${UNAME_RELEASE} exit ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit ;; TSUNAMI:LynxOS:2.*:*) echo sparc-unknown-lynxos${UNAME_RELEASE} exit ;; rs6000:LynxOS:2.*:*) echo rs6000-unknown-lynxos${UNAME_RELEASE} exit ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) echo powerpc-unknown-lynxos${UNAME_RELEASE} exit ;; SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv${UNAME_RELEASE} exit ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 exit ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 exit ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` echo ${UNAME_MACHINE}-sni-sysv4 else echo ns32k-sni-sysv fi exit ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says echo i586-unisys-sysv4 exit ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm echo hppa1.1-stratus-sysv4 exit ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. echo i860-stratus-sysv4 exit ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. echo ${UNAME_MACHINE}-stratus-vos exit ;; *:VOS:*:*) # From Paul.Green@stratus.com. echo hppa1.1-stratus-vos exit ;; mc68*:A/UX:*:*) echo m68k-apple-aux${UNAME_RELEASE} exit ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then echo mips-nec-sysv${UNAME_RELEASE} else echo mips-unknown-sysv${UNAME_RELEASE} fi exit ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos exit ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. echo powerpc-apple-beos exit ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos exit ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux${UNAME_RELEASE} exit ;; SX-5:SUPER-UX:*:*) echo sx5-nec-superux${UNAME_RELEASE} exit ;; SX-6:SUPER-UX:*:*) echo sx6-nec-superux${UNAME_RELEASE} exit ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody${UNAME_RELEASE} exit ;; *:Rhapsody:*:*) echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} exit ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown case $UNAME_PROCESSOR in unknown) UNAME_PROCESSOR=powerpc ;; esac echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = "x86"; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} exit ;; *:QNX:*:4*) echo i386-pc-qnx exit ;; NSE-?:NONSTOP_KERNEL:*:*) echo nse-tandem-nsk${UNAME_RELEASE} exit ;; NSR-?:NONSTOP_KERNEL:*:*) echo nsr-tandem-nsk${UNAME_RELEASE} exit ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux exit ;; BS2000:POSIX*:*:*) echo bs2000-siemens-sysv exit ;; DS/*:UNIX_System_V:*:*) echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} exit ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. if test "$cputype" = "386"; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" fi echo ${UNAME_MACHINE}-unknown-plan9 exit ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 exit ;; *:TENEX:*:*) echo pdp10-unknown-tenex exit ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) echo pdp10-dec-tops20 exit ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) echo pdp10-xkl-tops20 exit ;; *:TOPS-20:*:*) echo pdp10-unknown-tops20 exit ;; *:ITS:*:*) echo pdp10-unknown-its exit ;; SEI:*:*:SEIUX) echo mips-sei-seiux${UNAME_RELEASE} exit ;; *:DragonFly:*:*) echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` case "${UNAME_MACHINE}" in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; V*) echo vax-dec-vms ; exit ;; esac ;; *:XENIX:*:SysV) echo i386-pc-xenix exit ;; i*86:skyos:*:*) echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' exit ;; i*86:rdos:*:*) echo ${UNAME_MACHINE}-pc-rdos exit ;; esac #echo '(No uname command or uname output not recognized.)' 1>&2 #echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 eval $set_cc_for_build cat >$dummy.c < # include #endif main () { #if defined (sony) #if defined (MIPSEB) /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, I don't know.... */ printf ("mips-sony-bsd\n"); exit (0); #else #include printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 "4" #else "" #endif ); exit (0); #endif #endif #if defined (__arm) && defined (__acorn) && defined (__unix) printf ("arm-acorn-riscix\n"); exit (0); #endif #if defined (hp300) && !defined (hpux) printf ("m68k-hp-bsd\n"); exit (0); #endif #if defined (NeXT) #if !defined (__ARCHITECTURE__) #define __ARCHITECTURE__ "m68k" #endif int version; version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; if (version < 4) printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); else printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); exit (0); #endif #if defined (MULTIMAX) || defined (n16) #if defined (UMAXV) printf ("ns32k-encore-sysv\n"); exit (0); #else #if defined (CMU) printf ("ns32k-encore-mach\n"); exit (0); #else printf ("ns32k-encore-bsd\n"); exit (0); #endif #endif #endif #if defined (__386BSD__) printf ("i386-pc-bsd\n"); exit (0); #endif #if defined (sequent) #if defined (i386) printf ("i386-sequent-dynix\n"); exit (0); #endif #if defined (ns32000) printf ("ns32k-sequent-dynix\n"); exit (0); #endif #endif #if defined (_SEQUENT_) struct utsname un; uname(&un); if (strncmp(un.version, "V2", 2) == 0) { printf ("i386-sequent-ptx2\n"); exit (0); } if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ printf ("i386-sequent-ptx1\n"); exit (0); } printf ("i386-sequent-ptx\n"); exit (0); #endif #if defined (vax) # if !defined (ultrix) # include # if defined (BSD) # if BSD == 43 printf ("vax-dec-bsd4.3\n"); exit (0); # else # if BSD == 199006 printf ("vax-dec-bsd4.3reno\n"); exit (0); # else printf ("vax-dec-bsd\n"); exit (0); # endif # endif # else printf ("vax-dec-bsd\n"); exit (0); # endif # else printf ("vax-dec-ultrix\n"); exit (0); # endif #endif #if defined (alliant) && defined (i860) printf ("i860-alliant-bsd\n"); exit (0); #endif exit (1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } # Apollos put the system type in the environment. test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } # Convex versions that predate uname can use getsysinfo(1) if [ -x /usr/convex/getsysinfo ] then case `getsysinfo -f cpu_type` in c1*) echo c1-convex-bsd exit ;; c2*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; c34*) echo c34-convex-bsd exit ;; c38*) echo c38-convex-bsd exit ;; c4*) echo c4-convex-bsd exit ;; esac fi cat >&2 < in order to provide the needed information to handle your system. config.guess timestamp = $timestamp uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` /bin/uname -X = `(/bin/uname -X) 2>/dev/null` hostinfo = `(hostinfo) 2>/dev/null` /bin/universe = `(/bin/universe) 2>/dev/null` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` /bin/arch = `(/bin/arch) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` UNAME_MACHINE = ${UNAME_MACHINE} UNAME_RELEASE = ${UNAME_RELEASE} UNAME_SYSTEM = ${UNAME_SYSTEM} UNAME_VERSION = ${UNAME_VERSION} EOF exit 1 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: udpcast-20120424/rateGovernor.c0000444000175000017500000000507611065120461015172 0ustar alainalain#ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #include #include #include #include #include #include #include "log.h" #include "fifo.h" #include "socklib.h" #include "udpcast.h" #include "rateGovernor.h" #ifdef HAVE_DLFCN_H #include #endif #if defined HAVE_DLSYM && defined NO_BB #define DL_RATE_GOVERNOR #endif void *rgInitGovernor(struct net_config *cfg, struct rateGovernor_t *gov) { if(cfg->nrGovernors == MAX_GOVERNORS) { fprintf(stderr, "Too many rate governors\n"); exit(1); } cfg->rateGovernor[cfg->nrGovernors] = gov; return cfg->rateGovernorData[cfg->nrGovernors++] = gov->rgInitialize(); } #ifdef DL_RATE_GOVERNOR void rgParseRateGovernor(struct net_config *net_config, char *rg) { char *pos = strchr(rg, ':'); char *dlname; char *params; char *error; void *rgdl; struct rateGovernor_t *gov; void *data; if(pos) { dlname = strndup(rg, pos-rg); params = pos+1; } else { dlname = rg; params = NULL; } rgdl = dlopen(dlname, RTLD_LAZY); if(rgdl == NULL) { fprintf(stderr, "Library load error %s\n", dlerror()); exit(1); } dlerror(); /* Clear any existing error */ gov = dlsym(rgdl, "governor"); if ((error = dlerror()) != NULL) { fprintf(stderr, "Symbol resolve error: %s\n", error); exit(1); } if(pos) free(dlname); data = rgInitGovernor(net_config, gov); if(net_config->rateGovernorData == NULL) { fprintf(stderr, "Rate governor initialization error\n"); exit(1); } if(gov->rgSetProp) { while(params && *params) { char *eqPos; /* Position of the equal sign */ const char *key; /* Property name */ const char *value; /* property value */ pos = strchr(params, ','); if(pos == NULL) pos = params + strlen(params); eqPos = strchr(params, '='); if(eqPos == NULL || eqPos >= pos) { key = strndup(params, pos-params); value = NULL; } else { key = strndup(params, eqPos-params); value = strndup(eqPos+1, pos-(eqPos+1)); } gov->rgSetProp(data, key, value); if(*pos) pos++; params=pos; } } if(gov->rgEndConfig) { gov->rgEndConfig(data); } } #endif void rgWaitAll(struct net_config *cfg, int sock, in_addr_t ip, int size) { int i=0; for(i=0; inrGovernors; i++) { cfg->rateGovernor[i]->rgWait(cfg->rateGovernorData[i], sock, ip, size); } } void rgShutdownAll(struct net_config *cfg) { int i=0; for(i=0; inrGovernors; i++) { if(cfg->rateGovernor[i]->rgShutdown) cfg->rateGovernor[i]->rgShutdown(cfg->rateGovernorData[i]); } } udpcast-20120424/auto-rate.c0000444000175000017500000000343111247135567014426 0ustar alainalain#include #include #include #include #include "socklib.h" #include "udp-sender.h" #include "auto-rate.h" #include "util.h" #include "rateGovernor.h" #ifdef HAVE_SYS_IOCTL_H #include #endif #ifdef FLAG_AUTORATE struct auto_rate_t { int isInitialized; /* has this already been initialized? */ int dir; /* 1 if TIOCOUTQ is remaining space, * 0 if TIOCOUTQ is consumed space */ int sendbuf; /* sendbuf */ }; static int getCurrentQueueLength(int sock) { #ifdef TIOCOUTQ int length; if(ioctl(sock, TIOCOUTQ, &length) < 0) return -1; return length; #else return -1; #endif } static void *allocAutoRate(void) { struct auto_rate_t *autoRate_l = MALLOC(struct auto_rate_t); if(autoRate_l == NULL) return NULL; autoRate_l->isInitialized = 0; return autoRate_l; } static void initialize(struct auto_rate_t *autoRate_l, int sock) { int q = getCurrentQueueLength(sock); if(q == 0) { autoRate_l->dir = 0; autoRate_l->sendbuf = getSendBuf(sock); } else { autoRate_l->dir = 1; autoRate_l->sendbuf = q; } autoRate_l->isInitialized=1; } /** * If queue gets almost full, slow down things */ static void doAutoRate(void *data, int sock, in_addr_t ip, long size) { struct auto_rate_t *autoRate_l = (struct auto_rate_t*) data; (void) ip; if(!autoRate_l->isInitialized) initialize(autoRate_l, sock); while(1) { int r = getCurrentQueueLength(sock); if(autoRate_l->dir) r = autoRate_l->sendbuf - r; if(r < autoRate_l->sendbuf / 2 - size) return; #if DEBUG flprintf("Queue full %d/%d... Waiting\n", r, autoRate_l->sendbuf); #endif usleep(2500); } } rateGovernor_t autoRate = { allocAutoRate, NULL, NULL, doAutoRate, NULL }; #endif udpcast-20120424/udp-receiver.txt0000444000175000017500000000140311110214720015463 0ustar alainalaindefine(`UDPRECEIVER',` ')dnl udpcast-20120424/produconsum.h0000444000175000017500000000272710625532027015106 0ustar alainalain#ifndef PRODUCONSUM_H #define PRODUCONSUM_H typedef struct produconsum *produconsum_t; produconsum_t pc_makeProduconsum(int size, const char *name); void pc_produce(produconsum_t pc, unsigned int amount); void pc_produceEnd(produconsum_t pc); int pc_consumeAny(produconsum_t pc); int pc_consumeAnyWithTimeout(produconsum_t pc, struct timespec *tv); /** * Get contiguous chunk of data */ int pc_consumeAnyContiguous(produconsum_t pc); /** * Get contiguous chunk of data, of at least amount x */ int pc_consumeContiguousMinAmount(produconsum_t pc, int amount); /** * Consume minimum amount bytes. Wait until at least amount is * available, or end of file reached. This only makes sure that amount * bytes are available. It does not actually remove them from the queue * To remove bytes from the queue (i.e. move the consumer position), call * pc_consumed */ int pc_consume(produconsum_t pc, int amount); /** * Get current position of consumer (moved by pc_consued) */ unsigned int pc_getConsumerPosition(produconsum_t pc); /** * Get current position of producer (moved by pc_produced) */ unsigned int pc_getProducerPosition(produconsum_t pc); /** * Get total size of circular buffer */ unsigned int pc_getSize(produconsum_t pc); /** * Get total amount of data currently waiting to be consumed, without * blocking */ unsigned int pc_getWaiting(produconsum_t pc); /** * Signal that data has been consumed */ int pc_consumed(produconsum_t pc, int amount); #endif udpcast-20120424/threads.h0000444000175000017500000000535411064536641014165 0ustar alainalain#ifndef UDPCTHREADS_H #define UDPCTHREADS_H #ifdef __MINGW32__ #include "socklib.h" #include #include #include typedef HANDLE pthread_t; typedef CRITICAL_SECTION pthread_mutex_t; typedef HANDLE pthread_cond_t; struct timespec { unsigned long tv_sec; unsigned long tv_nsec; }; static inline int pthread_create(pthread_t *thread, void *dummy1, LPTHREAD_START_ROUTINE start_routine, void *arg) { /* Start thread ... * see http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/createthread.asp */ *thread = CreateThread(NULL, /* lpThreadAttributes */ 0, /* dwStackSize */ start_routine, arg, /* lpParameter */ 0, /* dwCreationFlags */ NULL /* lpThreadId */); return *thread != NULL ? 0 : -1; } static inline int pthread_join(pthread_t th, void **thread_return) { return WaitForSingleObject(th, INFINITE) == WAIT_OBJECT_0 ? 0 : -1; } static inline int pthread_mutex_init(pthread_mutex_t *mutex, void *dummy) { InitializeCriticalSection(mutex); return 0; } static inline int pthread_mutex_lock(pthread_mutex_t *mutex) { EnterCriticalSection(mutex); return 0; } static inline int pthread_mutex_unlock(pthread_mutex_t *mutex) { LeaveCriticalSection(mutex); return 0; } static inline int pthread_cond_init(pthread_cond_t *cond, void *dummy) { *cond = CreateEvent(NULL, TRUE, TRUE, NULL); if(*cond == NULL) return -1; else return 0; } static inline int pthread_cond_signal(pthread_cond_t *cond) { return SetEvent(*cond) ? 0 : -1; } static inline int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) { int r; ResetEvent(*cond); LeaveCriticalSection(mutex); r= WaitForSingleObject(*cond, INFINITE) == WAIT_OBJECT_0 ? 0 : -1; EnterCriticalSection(mutex); return r; } static inline void pthread_cancel(pthread_t *thread) { TerminateThread(thread, 0); } #define ETIMEDOUT -2 #define MILLION 1000000 #define BILLION 1000000000 static inline int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, struct timespec *ts) { int r; struct timeval tv; long delta; gettimeofday(&tv, NULL); delta = (ts->tv_sec - tv.tv_sec) * 1000 + (ts->tv_nsec / BILLION - tv.tv_usec / MILLION); if(delta < 0) delta = 0; ResetEvent(*cond); LeaveCriticalSection(mutex); switch(WaitForSingleObject(*cond, delta )) { case WAIT_OBJECT_0: r=0; break; case WAIT_TIMEOUT: r=ETIMEDOUT; break; default: r=-1; break; } EnterCriticalSection(mutex); return r; } #define THREAD_RETURN DWORD WINAPI #else /* __MINGW32__ */ #include #define THREAD_RETURN void * #endif /* __MINGW32__ */ #endif udpcast-20120424/udpcast.h0000444000175000017500000000651611606074530014173 0ustar alainalain#ifndef UDPCAST_H #define UDPCAST_H #ifdef __GNUC__ #define UNUSED __attribute__((unused)) #endif #include "socklib.h" #include #include #define BITS_PER_INT (sizeof(int) * 8) #define BITS_PER_CHAR 8 #define MAP_ZERO(l, map) (memset(map, 0, ((l) + BITS_PER_INT - 1)/ BIT_PER_INT)) #define BZERO(data) (memset((void *)&data, 0, sizeof(data))) #define RDATABUFSIZE (2*(MAX_SLICE_SIZE + 1)* MAX_BLOCK_SIZE) #define DATABUFSIZE (RDATABUFSIZE + 4096 - RDATABUFSIZE % 4096) int udpc_writeSize(void); int udpc_largeReadSize(void); int udpc_smallReadSize(void); int udpc_makeDataBuffer(int blocksize); int udpc_parseCommand(char *pipeName, char **arg); int udpc_printLongNum(unsigned long long x); int udpc_waitForProcess(int pid, const char *message); struct disk_config { int origOutFile; const char *fileName; char *pipeName; int flags; struct timeval stats_last_printed; }; #define MAX_GOVERNORS 10 struct net_config { net_if_t *net_if; /* Network interface (eth0, isdn0, etc.) on which to * multicast */ int portBase; /* Port base */ int blockSize; int sliceSize; struct sockaddr_in controlMcastAddr; struct sockaddr_in dataMcastAddr; const char *mcastRdv; int ttl; int nrGovernors; struct rateGovernor_t *rateGovernor[MAX_GOVERNORS]; void *rateGovernorData[MAX_GOVERNORS]; /*int async;*/ /*int pointopoint;*/ struct timeval ref_tv; enum discovery { DSC_DOUBLING, DSC_REDUCING } discovery; /* int autoRate; do queue watching using TIOCOUTQ, to avoid overruns */ int flags; /* non-capability command line flags */ int capabilities; int min_slice_size; int default_slice_size; int max_slice_size; unsigned int rcvbuf; int rexmit_hello_interval; /* retransmission interval between hello's. * If 0, hello message won't be retransmitted */ int autostart; /* autostart after that many retransmits */ int requestedBufSize; /* requested receiver buffer */ /* sender-specific parameters */ int min_receivers; int max_receivers_wait; int min_receivers_wait; int retriesUntilDrop; /* receiver-specif parameters */ int exitWait; /* How many milliseconds to wait on program exit */ int startTimeout; /* Timeout at start */ int receiveTimeout; /* Receive timeout */ /* FEC config */ #ifdef BB_FEATURE_UDPCAST_FEC int fec_redundancy; /* how much fec blocks are added per group */ int fec_stripesize; /* size of FEC group */ int fec_stripes; /* number of FEC stripes per slice */ #endif int rehelloOffset; /* how far before end will rehello packet will be retransmitted */ }; struct stat_config { FILE *log; /* Log file for statistics */ long bwPeriod; /* How often are bandwidth estimations logged? */ int statPeriod; int printUncompressedPos; int noProgress; }; void *rgInitGovernor(struct net_config *cfg, struct rateGovernor_t *gov); void rgParseRateGovernor(struct net_config *net_config, char *rg); void rgWaitAll(struct net_config *cfg, int sock, in_addr_t ip, int size); void rgShutdownAll(struct net_config *cfg); /** * Answers whether given fd is seekable */ int udpc_shouldPrintUncompressedPos(int deflt, int fd, int pipe); #define MAX_SLICE_SIZE 1024 #define DEFLT_STAT_PERIOD 500000 #ifndef DEBUG # define DEBUG 0 #endif #endif udpcast-20120424/Makefile.in0000444000175000017500000000752711110055031014410 0ustar alainalaintop_srcdir=@top_srcdir@ srcdir=@srcdir@ VPATH=@srcdir@ prefix = @prefix@ bindir = @bindir@ infodir = @infodir@ mandir = @mandir@ datarootdir = @datarootdir@ CC = @CC@ CFLAGS = @CFLAGS@ CPPFLAGS = -I. @extraincludedir@ -I@srcdir@ @CPPFLAGS@ HOST_ID = @HOST_ID@ DEFS = @DEFS@ $(HOST_ID) LDFLAGS = @LDFLAGS@ LIBS = @LIBS@ SHLIB = @SHLIB@ MACHDEPLIBS = @MACHDEPLIBS@ LN_S = @LN_S@ INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ .SUFFIXES: .SUFFIXES: .o .c .SUFFIXES: .o .c # For additional warnings & checks, add -Wstrict-prototypes -Wshadow to the # following: CFLAGS +=-Wall -DBB_FEATURE_UDPCAST_FEC -D_FILE_OFFSET_BITS=64 -DUSE_SYSLOG -DUSE_ASSEMBLER -O6 LDFLAGS +=-s LIBS +=@LIBS@ BUSYBOX=../udp-busybox/busybox BBTARGET=$(BUSYBOX)/udpcast EXESUFFIX=@EXESUFFIX@ CFLAGS += -DNO_BB all: udp-receiver$(EXESUFFIX) udp-sender$(EXESUFFIX) \ manpages #all: fec-test disk: udpcast.img.gz #disks: sender.img.gz receiver.img.gz clean: rm -f *.o udp-sender$(EXESUFFIX) udp-receiver$(EXESUFFIX) \ udp-sender.1 udp-receiver.1 *~ distclean: clean rm -f Makefile config.status config.log config.h install: udp-sender udp-receiver rateGovernor.h install -d $(DESTDIR)$(prefix)/sbin install -m 755 udp-sender udp-receiver $(DESTDIR)$(prefix)/sbin install -d $(DESTDIR)$(mandir)/man1 install -m 644 udp-sender.1 udp-receiver.1 $(DESTDIR)$(mandir)/man1 install -d $(DESTDIR)$(prefix)/include/udpcast install -m 644 rateGovernor.h $(DESTDIR)$(prefix)/include/udpcast udp-sender$(EXESUFFIX): udp-sender.o socklib.o udpcast.o \ rateGovernor.o rate-limit.o auto-rate.o \ sender-diskio.o senddata.o udps-negotiate.o \ fifo.o produconsum.o participants.o log.o statistics.o \ fec.o udpc_version.o console.o process.o rateGovernor.o $(CC) $(LDFLAGS) $^ $(LIBS) -o $@ udp-receiver$(EXESUFFIX): udp-receiver.o socklib.o udpcast.o \ receiver-diskio.o receivedata.o udpr-negotiate.o produconsum.o \ fifo.o log.o statistics.o fec.o udpc_version.o console.o process.o $(CC) $(LDFLAGS) $^ $(LIBS) -o $@ cmd.html.man: udp-receiver.txt udp-sender.txt cmd.html cat $^ | m4 >cmd.html.man manpages: html2man.pl cmd.html.man perl $^ fec-test: fec-test.o $(CC) $(LDFLAGS) $^ -o $@ fec.o: fec.c $(CC) -c $(CPPFLAGS) $(CFLAGS) -fno-inline $< bbcopy: $(BBTARGET) \ $(BBTARGET)/fec.c $(BBTARGET)/participants.h $(BBTARGET)/socklib.c \ $(BBTARGET)/udp-receiver.c $(BBTARGET)/fec.h \ $(BBTARGET)/produconsum.c $(BBTARGET)/socklib.h \ $(BBTARGET)/udp-receiver.h $(BBTARGET)/fec-test.c \ $(BBTARGET)/produconsum.h $(BBTARGET)/statistics.c \ $(BBTARGET)/udpr-negotiate.c $(BBTARGET)/fifo.c \ $(BBTARGET)/rateGovernor.h $(BBTARGET)/rateGovernor.c \ $(BBTARGET)/rate-limit.c $(BBTARGET)/rate-limit.h \ $(BBTARGET)/auto-rate.c $(BBTARGET)/auto-rate.h \ $(BBTARGET)/statistics.h \ $(BBTARGET)/udp-sender.c $(BBTARGET)/fifo.h \ $(BBTARGET)/udpcast.c $(BBTARGET)/udp-sender.h \ $(BBTARGET)/libbb_udpcast.h $(BBTARGET)/receivedata.c \ $(BBTARGET)/udpcast.h $(BBTARGET)/udps-negotiate.c \ $(BBTARGET)/log.c $(BBTARGET)/receiver-diskio.c \ $(BBTARGET)/udpc-protoc.h $(BBTARGET)/util.h \ $(BBTARGET)/log.h $(BBTARGET)/senddata.c $(BBTARGET)/udpc_version.c \ $(BBTARGET)/participants.c $(BBTARGET)/sender-diskio.c \ $(BBTARGET)/udpc_version.h \ $(BBTARGET)/console.h $(BBTARGET)/console.c \ $(BBTARGET)/udpc_process.h $(BBTARGET)/process.c \ $(BBTARGET)/threads.h \ $(BBTARGET)/Config.in $(BBTARGET)/Kbuild $(BBTARGET)/Makefile.flags \ $(BBTARGET)/applets.h $(BBTARGET)/usage.h \ $(BBTARGET)/config.h $(BBTARGET): mkdir $(BBTARGET) $(BBTARGET)/Kbuild: Kbuild cp -f $< $(BBTARGET)/ $(BBTARGET)/%.c: %.c cp -f $< $(BBTARGET) $(BBTARGET)/%.h: %.h cp -f $< $(BBTARGET) $(BBTARGET)/%.flags: %.flags cp -f $< $(BBTARGET) $(BBTARGET)/Config.in: Config.in cp -f $< $(BBTARGET) bb: bbcopy make -C $(BUSYBOX) .PHONY: manpages udpcast-20120424/udpr-negotiate.c0000444000175000017500000002143011745600247015446 0ustar alainalain#include #include #include #include #include "log.h" #include "socklib.h" #include "udpcast.h" #include "udpc-protoc.h" #include "fifo.h" #include "udp-receiver.h" #include "util.h" #include "produconsum.h" #include "statistics.h" #ifndef O_BINARY # define O_BINARY 0 #endif #ifndef O_SYNC # define O_SYNC 0 #endif #ifndef O_TRUNC # define O_TRUNC 0 #endif static int sendConnectReq(struct client_config *client_config, struct net_config *net_config, int haveServerAddress) { struct connectReq connectReq; if(net_config->flags & FLAG_PASSIVE) return 0; connectReq.opCode = htons(CMD_CONNECT_REQ); connectReq.reserved = 0; connectReq.capabilities = htonl(RECEIVER_CAPABILITIES); connectReq.rcvbuf = htonl(getRcvBuf(client_config->S_UCAST)); if(haveServerAddress) return SSEND(connectReq); else return BCAST_CONTROL(client_config->S_UCAST, connectReq); } int sendGo(struct client_config *client_config) { struct go go; go.opCode = htons(CMD_GO); go.reserved = 0; return SSEND(go); } struct client_config *global_client_config=NULL; static void fixConsole(void) { if(global_client_config) restoreConsole(&global_client_config->console,0); } static void sendDisconnectWrapper(void) { if(global_client_config) sendDisconnect(0, global_client_config); } void sendDisconnect(int exitStatus, struct client_config *client_config) { struct disconnect disconnect; disconnect.opCode = htons(CMD_DISCONNECT); disconnect.reserved = 0; SSEND(disconnect); if (exitStatus == 0) udpc_flprintf("Transfer complete.\007\n"); } struct startTransferArgs { int fd; int pipeFd; struct client_config *client_config; int doWarn; }; static int openOutFile(struct disk_config *disk_config) { int outFile=1; if(disk_config->fileName != NULL) { int oflags = O_CREAT | O_WRONLY | O_TRUNC; if((disk_config->flags & FLAG_SYNC)) { oflags |= O_SYNC; } outFile = open(disk_config->fileName, oflags | O_BINARY, 0644); if(outFile < 0) { #ifdef NO_BB #ifndef errno extern int errno; #endif #endif udpc_fatal(1, "open outfile %s: %s\n", disk_config->fileName, strerror(errno)); } } else { #ifdef __MINGW32__ _setmode(1, O_BINARY); #endif } return outFile; } int startReceiver(int doWarn, struct disk_config *disk_config, struct net_config *net_config, struct stat_config *stat_config, const char *ifName) { char ipBuffer[16]; union serverControlMsg Msg; int connectReqSent=0; struct client_config client_config; int outFile=1; int pipedOutFile; struct sockaddr_in myIp; int pipePid = 0; int origOutFile; int haveServerAddress; int ret=0; client_config.sender_is_newgen = 0; net_config->net_if = getNetIf(ifName); zeroSockArray(client_config.socks, NR_CLIENT_SOCKS); client_config.S_UCAST = makeSocket(ADDR_TYPE_UCAST, net_config->net_if, 0, RECEIVER_PORT(net_config->portBase)); client_config.S_BCAST = makeSocket(ADDR_TYPE_BCAST, net_config->net_if, 0, RECEIVER_PORT(net_config->portBase)); if(net_config->ttl == 1 && net_config->mcastRdv == NULL) { getBroadCastAddress(net_config->net_if, &net_config->controlMcastAddr, SENDER_PORT(net_config->portBase)); setSocketToBroadcast(client_config.S_UCAST); } else { getMcastAllAddress(&net_config->controlMcastAddr, net_config->mcastRdv, SENDER_PORT(net_config->portBase)); if(isMcastAddress(&net_config->controlMcastAddr)) { setMcastDestination(client_config.S_UCAST, net_config->net_if, &net_config->controlMcastAddr); setTtl(client_config.S_UCAST, net_config->ttl); client_config.S_MCAST_CTRL = makeSocket(ADDR_TYPE_MCAST, net_config->net_if, &net_config->controlMcastAddr, RECEIVER_PORT(net_config->portBase)); // TODO: subscribe address as receiver to! } } clearIp(&net_config->dataMcastAddr); udpc_flprintf("%sUDP receiver for %s at ", disk_config->pipeName == NULL ? "" : "Compressed ", disk_config->fileName == NULL ? "(stdout)":disk_config->fileName); printMyIp(net_config->net_if); udpc_flprintf(" on %s\n", net_config->net_if->name); connectReqSent = 0; haveServerAddress = 0; client_config.clientNumber= 0; /*default number for asynchronous transfer*/ while(1) { // int len; int msglen; int sock; if (!connectReqSent) { if (sendConnectReq(&client_config, net_config, haveServerAddress) < 0) { perror("sendto to locate server"); } connectReqSent = 1; } haveServerAddress=0; sock = udpc_selectSock(client_config.socks, NR_CLIENT_SOCKS, net_config->startTimeout); if(sock < 0) { return -1; } // len = sizeof(server); msglen=RECV(sock, Msg, client_config.serverAddr, net_config->portBase); if (msglen < 0) { perror("recvfrom to locate server"); exit(1); } if(getPort(&client_config.serverAddr) != SENDER_PORT(net_config->portBase)) /* not from the right port */ continue; switch(ntohs(Msg.opCode)) { case CMD_CONNECT_REPLY: client_config.clientNumber = ntohl(Msg.connectReply.clNr); net_config->blockSize = ntohl(Msg.connectReply.blockSize); udpc_flprintf("received message, cap=%08lx\n", (long) ntohl(Msg.connectReply.capabilities)); if(ntohl(Msg.connectReply.capabilities) & CAP_NEW_GEN) { client_config.sender_is_newgen = 1; copyFromMessage(&net_config->dataMcastAddr, Msg.connectReply.mcastAddr); } if (client_config.clientNumber == -1) { udpc_fatal(1, "Too many clients already connected\n"); } goto break_loop; case CMD_HELLO_STREAMING: case CMD_HELLO_NEW: case CMD_HELLO: connectReqSent = 0; if(ntohs(Msg.opCode) == CMD_HELLO_STREAMING) net_config->flags |= FLAG_STREAMING; if(ntohl(Msg.hello.capabilities) & CAP_NEW_GEN) { client_config.sender_is_newgen = 1; copyFromMessage(&net_config->dataMcastAddr, Msg.hello.mcastAddr); net_config->blockSize = ntohs(Msg.hello.blockSize); if(ntohl(Msg.hello.capabilities) & CAP_ASYNC) net_config->flags |= FLAG_PASSIVE; if(net_config->flags & FLAG_PASSIVE) goto break_loop; } haveServerAddress=1; continue; case CMD_CONNECT_REQ: case CMD_DATA: case CMD_FEC: continue; default: break; } udpc_fatal(1, "Bad server reply %04x. Other transfer in progress?\n", (unsigned short) ntohs(Msg.opCode)); } break_loop: udpc_flprintf("Connected as #%d to %s\n", client_config.clientNumber, getIpString(&client_config.serverAddr, ipBuffer)); getMyAddress(net_config->net_if, &myIp); if(!ipIsZero(&net_config->dataMcastAddr) && !ipIsEqual(&net_config->dataMcastAddr, &myIp) && (ipIsZero(&net_config->controlMcastAddr) || !ipIsEqual(&net_config->dataMcastAddr, &net_config->controlMcastAddr) )) { udpc_flprintf("Listening to multicast on %s\n", getIpString(&net_config->dataMcastAddr, ipBuffer)); client_config.S_MCAST_DATA = makeSocket(ADDR_TYPE_MCAST, net_config->net_if, &net_config->dataMcastAddr, RECEIVER_PORT(net_config->portBase)); } if(net_config->requestedBufSize) { int i; for(i=0; irequestedBufSize); } outFile=openOutFile(disk_config); origOutFile = outFile; pipedOutFile = openPipe(outFile, disk_config, &pipePid); global_client_config= &client_config; atexit(sendDisconnectWrapper); { struct fifo fifo; int printUncompressedPos = udpc_shouldPrintUncompressedPos(stat_config->printUncompressedPos, origOutFile, pipedOutFile); receiver_stats_t stats = allocReadStats(origOutFile, stat_config->statPeriod, printUncompressedPos, stat_config->noProgress); udpc_initFifo(&fifo, net_config->blockSize); fifo.data = pc_makeProduconsum(fifo.dataBufSize, "receive"); client_config.isStarted = 0; if((net_config->flags & (FLAG_PASSIVE|FLAG_NOKBD))) { /* No console used */ client_config.console = NULL; } else { if(doWarn) udpc_flprintf("WARNING: This will overwrite the hard disk of this machine\n"); client_config.console = prepareConsole(0); atexit(fixConsole); } spawnNetReceiver(&fifo,&client_config, net_config, stats); writer(&fifo, pipedOutFile); if(pipePid) { close(pipedOutFile); } pthread_join(client_config.thread, NULL); /* if we have a pipe, now wait for that too */ if(pipePid) { ret=udpc_waitForProcess(pipePid, "Pipe"); } #ifndef __MINGW32__ fsync(origOutFile); #endif /* __MINGW32__ */ displayReceiverStats(stats, 1); } fixConsole(); sendDisconnectWrapper(); global_client_config= NULL; return ret; } udpcast-20120424/fifo.c0000444000175000017500000000101211064537425013435 0ustar alainalain#include "libbb_udpcast.h" #include "fifo.h" void udpc_initFifo(struct fifo *fifo, int blockSize) { fifo->dataBufSize = blockSize * 4096; fifo->dataBuffer = xmalloc(fifo->dataBufSize+4096); fifo->dataBuffer += 4096 - (((unsigned long)fifo->dataBuffer) % 4096); /* Free memory queue is initially full */ fifo->freeMemQueue = pc_makeProduconsum(fifo->dataBufSize, "free mem"); pc_produce(fifo->freeMemQueue, fifo->dataBufSize); fifo->data = pc_makeProduconsum(fifo->dataBufSize, "receive"); }