Package: reprepro Version: 3.5.0 Tags: patch This bug is not about the Debian packaging of reprepro, but about compiling the upstream source on a non-Linux system.
For various reasons, I'm compiling reprepro for AIX 5.3 with GCC, to use on IBM i5/OS V5R4 for a few hundred Debian PCs. I encountered a handful of problems that needed changes, as listed below, and I'm including a patch for most of them. Overall I'm very impressed with the portability of the code. - A number of the files use malloc() and free() without including <stdlib.h>. The AIX C library is careful only to define these where the various standards say they should be found. I haven't provided a patch for this one. - The last parameter for execl() should be (char*)NULL, not just NULL, in case char* is a different size to whatever NULL resolves to. GCC 4.3 warns about this on AIX. - AIX 5.3 doesn't provide O_NOFOLLOW. I most cases, this is combined with O_EXCL which seems to be redundant, and I've removed it; in donefile.c I've taken the potential security exposure and not used it. You might wish to define it to 0 instead. - AIX 5.3 doesn't have <endian.h>, but does get the BSD-ish BYTE_ORDER, BIG_ENDIAN and LITTLE_ENDIAN macros if you include <sys/param.h> and/or <sys/types.h>. I haven't included a patch for configure.ac, etc., to get them to detect HAVE_ENDIAN_H on Linux, but it should be trivial. Alternatively, there's AC_C_BIGENDIAN. - AIX 5.3 doesn't have vasnprintf (or dprintf). I've removed vmprintf(), changed formaterror to use snprintf with a static buffer that is much larger than anything it will have to hold, and changed mprintf() and dprintf() to call vsnprintf twice, as shown in the GNU libc manual. I figure that there's no point making dprintf() use vasprintf(), because they're both GNU libc extensions. - _D_EXACT_NAMELEN is a GNU extension. I just use strlen(r->d_name) if it isn't defined. - I don't check zlibCompileFlags() when using zlib 1.1, which is what I have available. - AIX doesn't have getopt_long, but I've compiled against libiberty from GCC. - AIX GCC needs an option "-pthread" to compile and link threadsafe code (like Berkeley DB), not -D_REENTRANT. I added this option to the CFLAGS when running configure. I don't know how autoconf is supposed to discover this. Please let me know if you'd like any more information. -- Laissez lire, et laissez danser; ces deux amusements ne feront jamais de mal au monde.
*** aptmethod.c.orig Fri Jun 6 21:07:53 2008 --- aptmethod.c Tue Jun 10 11:40:10 2008 *************** *** 335,341 **** if( methodname == NULL ) exit(255); ! (void)execl(methodname,methodname,NULL); e = errno; fprintf(stderr, "Error %d while executing '%s': %s\n", --- 335,341 ---- if( methodname == NULL ) exit(255); ! (void)execl(methodname,methodname,(char*)NULL); e = errno; fprintf(stderr, "Error %d while executing '%s': %s\n", *** checks.c.orig Wed Apr 9 01:01:42 2008 --- checks.c Tue Jun 10 10:34:11 2008 *************** *** 171,185 **** static const char *formaterror(const char *format, ...) { va_list ap; ! static char *data = NULL; - if( data != NULL ) - free(data); va_start(ap, format); ! data = vmprintf(format, ap); va_end(ap); - if( data == NULL ) - return "Out of memory"; return data; } --- 171,181 ---- static const char *formaterror(const char *format, ...) { va_list ap; ! static char data[1024]; va_start(ap, format); ! snprintf(data, sizeof(data), format, ap); va_end(ap); return data; } *** database.c.orig Wed Apr 9 01:01:43 2008 --- database.c Tue Jun 10 11:28:38 2008 *************** *** 84,90 **** lockfile = calc_dirconcat(db->directory, "lockfile"); if( lockfile == NULL ) return RET_ERROR_OOM; ! fd = open(lockfile,O_WRONLY|O_CREAT|O_EXCL|O_NOFOLLOW|O_NOCTTY,S_IRUSR|S_IWUSR); while( fd < 0 ) { int e = errno; if( e == EEXIST ) { --- 84,90 ---- lockfile = calc_dirconcat(db->directory, "lockfile"); if( lockfile == NULL ) return RET_ERROR_OOM; ! fd = open(lockfile,O_WRONLY|O_CREAT|O_EXCL|O_NOCTTY,S_IRUSR|S_IWUSR); while( fd < 0 ) { int e = errno; if( e == EEXIST ) { *************** *** 95,101 **** while( timetosleep > 0 ) timetosleep = sleep(timetosleep); tries++; ! fd = open(lockfile,O_WRONLY|O_CREAT|O_EXCL|O_NOFOLLOW|O_NOCTTY,S_IRUSR|S_IWUSR); continue; } --- 95,101 ---- while( timetosleep > 0 ) timetosleep = sleep(timetosleep); tries++; ! fd = open(lockfile,O_WRONLY|O_CREAT|O_EXCL|O_NOCTTY,S_IRUSR|S_IWUSR); continue; } *** donefile.c.orig Mon Mar 3 04:37:39 2008 --- donefile.c Tue Jun 10 11:43:20 2008 *************** *** 36,42 **** --- 36,46 ---- char *donefilename = calc_addsuffix(filename,"done"); if( donefilename == NULL ) return RET_ERROR_OOM; + #ifdef O_NOFOLLOW fd = open(donefilename, O_RDONLY|O_NOCTTY|O_NOFOLLOW, 0666); + #else + fd = open(donefilename, O_RDONLY|O_NOCTTY, 0666); + #endif if( fd < 0 ) { int e = errno; if( e == EACCES || e == ENOENT ) { *************** *** 98,105 **** --- 102,113 ---- return RET_ERROR_OOM; md5sum = checksums_getmd5sum(checksums); + #ifdef O_NOFOLLOW fd = open(donefilename, O_WRONLY|O_CREAT|O_TRUNC|O_NOCTTY|O_NOFOLLOW, 0666); + #else + fd = open(donefilename, O_WRONLY|O_CREAT|O_TRUNC|O_NOCTTY, 0666); + #endif if( fd < 0 ) { int e = errno; fprintf(stderr, "Error creating file %s: %d=%s\n", *** exports.c.orig Fri Jun 6 21:07:53 2008 --- exports.c Tue Jun 10 11:40:42 2008 *************** *** 298,304 **** exit(255); } (void)execl(hook, hook, release_dirofdist(release), ! reltmpfilename, relfilename, mode, NULL); e = errno; fprintf(stderr, "Error %d while executing '%s': %s\n", e, hook, strerror(e)); --- 298,304 ---- exit(255); } (void)execl(hook, hook, release_dirofdist(release), ! reltmpfilename, relfilename, mode, (char*)NULL); e = errno; fprintf(stderr, "Error %d while executing '%s': %s\n", e, hook, strerror(e)); *** md5.c.orig Sun Jul 29 04:21:31 2007 --- md5.c Tue Jun 10 11:26:56 2008 *************** *** 28,35 **** --- 28,38 ---- #include <config.h> + #ifdef HAVE_ENDIAN_H #include <endian.h> /* for __BYTE_ORDER */ + #endif #include <string.h> /* for memcpy() */ + #include <sys/param.h> #include <sys/types.h> /* for stupid systems */ #include <netinet/in.h> /* for ntohl() */ *************** *** 37,43 **** static void MD5Transform(UWORD32 buf[4], UWORD32 const in[16]); ! #if __BYTE_ORDER == __BIG_ENDIAN static void byteSwap(UWORD32 *buf, unsigned words) { --- 40,47 ---- static void MD5Transform(UWORD32 buf[4], UWORD32 const in[16]); ! #if (defined(__BYTE_ORDER) && __BYTE_ORDER == __BIG_ENDIAN) \ ! || (defined(BYTE_ORDER) && BYTE_ORDER == BIG_ENDIAN) static void byteSwap(UWORD32 *buf, unsigned words) { *************** *** 50,56 **** } while (--words); } #else ! #if __BYTE_ORDER == __LITTLE_ENDIAN #define byteSwap(buf,words) #else #error "only supporting little or big endian currently" --- 54,61 ---- } while (--words); } #else ! #if (defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN) \ ! || (defined(BYTE_ORDER) && BYTE_ORDER == LITTLE_ENDIAN) #define byteSwap(buf,words) #else #error "only supporting little or big endian currently" *** mprintf.c.orig Tue Feb 5 07:56:37 2008 --- mprintf.c Tue Jun 10 12:08:48 2008 *************** *** 9,17 **** #include "mprintf.h" ! // TODO: check for asprintf in configure and ! // write a replacement for such situations. char * mprintf(const char *fmt,...) { char *p; int r; --- 9,17 ---- #include "mprintf.h" ! #define MPRINTF_INITIAL_SIZE 256 + #ifdef HAVE_VASPRINTF char * mprintf(const char *fmt,...) { char *p; int r; *************** *** 26,43 **** else return p; } ! ! char * vmprintf(const char *fmt,va_list va) { char *p; int r; ! r = vasprintf(&p,fmt,va); ! /* return NULL both when r is < 0 and when NULL was returned */ ! if( r < 0 ) return NULL; ! else return p; } #ifndef HAVE_DPRINTF int dprintf(int fd, const char *format, ...){ --- 26,68 ---- else return p; } ! #else ! char * mprintf(const char *fmt, ...) { char *p; int r; + va_list va; ! p = malloc(MPRINTF_INITIAL_SIZE); ! if ( p == NULL ) { ! r = -1; ! } else { ! va_start(va,fmt); ! r = vsnprintf(p,MPRINTF_INITIAL_SIZE,fmt,va); ! va_end(va); ! } ! ! if ( r >= MPRINTF_INITIAL_SIZE ) { ! char *newp; ! newp = realloc(p,r+1); ! if ( newp == NULL ) { ! r = -1; ! } else { ! p = newp; ! va_start(va,fmt); ! r = vsnprintf(p,r+1,fmt,va); ! va_end(va); ! } ! } ! ! /* return NULL when r < 0 */ ! if ( r < 0 ) { ! free(p); return NULL; ! } else { return p; + } } + #endif #ifndef HAVE_DPRINTF int dprintf(int fd, const char *format, ...){ *************** *** 46,54 **** va_list va; ! va_start(va, format); ! buffer = vmprintf(format, va); ! va_end(va); if( buffer == NULL ) return -1; ret = write(fd, buffer, strlen(buffer)); --- 71,98 ---- va_list va; ! buffer = malloc(MPRINTF_INITIAL_SIZE); ! if ( buffer == NULL ) { ! ret = -1; ! } else { ! va_start(va,format); ! ret = vsnprintf(buffer,MPRINTF_INITIAL_SIZE,format,va); ! va_end(va); ! } ! ! if ( ret >= MPRINTF_INITIAL_SIZE ) { ! char *newp; ! newp = realloc(buffer,ret+1); ! if ( newp == NULL ) { ! ret = -1; ! } else { ! buffer = newp; ! va_start(va,format); ! ret = vsnprintf(buffer,ret+1,format,va); ! va_end(va); ! } ! } ! if( buffer == NULL ) return -1; ret = write(fd, buffer, strlen(buffer)); *** release.c.orig Fri Jun 6 21:07:53 2008 --- release.c Tue Jun 10 11:59:48 2008 *************** *** 481,490 **** --- 481,492 ---- static retvalue initgzcompression(struct filetorelease *f) { int zret; + #ifdef ZLIB_VERNUM if( (zlibCompileFlags() & (1<<17)) !=0 ) { fprintf(stderr,"libz compiled without .gz supporting code\n"); return RET_ERROR; } + #endif f->gzoutputbuffer = malloc(GZBUFSIZE); if( f->gzoutputbuffer == NULL ) return RET_ERROR_OOM; *** sha1.c.orig Wed Nov 21 00:58:47 2007 --- sha1.c Tue Jun 10 11:21:03 2008 *************** *** 49,61 **** --- 49,71 ---- #include "config.h" #endif + #ifdef HAVE_ENDIAN_H #include <endian.h> + #endif #include <stdint.h> #include <stdio.h> #include <string.h> #include <assert.h> + #include <sys/param.h> + #include <sys/types.h> #include "sha1.h" + + #ifndef __BYTE_ORDER + #define __BYTE_ORDER BYTE_ORDER + #define __LITTLE_ENDIAN LITTLE_ENDIAN + #define __BIG_ENDIAN BIG_ENDIAN + #endif static void SHA1_Transform(uint32_t state[5], const uint8_t buffer[64]); *** sha256.c.orig Sat May 17 23:04:00 2008 --- sha256.c Tue Jun 10 11:24:12 2008 *************** *** 6,12 **** --- 6,14 ---- #include <config.h> + #ifdef HAVE_ENDIAN_H #include <endian.h> + #endif #include <limits.h> #include <stdint.h> #include <stdio.h> *************** *** 17,23 **** #include "sha256.h" ! #if __BYTE_ORDER == __LITTLE_ENDIAN # define SWAP(n) \ (((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24)) #else --- 19,26 ---- #include "sha256.h" ! #if (defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN) \ ! || (defined(BYTE_ORDER) && BYTE_ORDER == LITTLE_ENDIAN) # define SWAP(n) \ (((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24)) #else *** signature.c.orig Wed Apr 9 01:01:43 2008 --- signature.c Tue Jun 10 11:37:25 2008 *************** *** 414,420 **** if( signature_data == NULL ) { return RET_ERROR_OOM; } ! fd = open(signaturename, O_WRONLY|O_CREAT|O_EXCL|O_NOCTTY|O_NOFOLLOW, 0666); if( fd < 0 ) { free(signature_data); return RET_ERRNO(errno); --- 414,420 ---- if( signature_data == NULL ) { return RET_ERROR_OOM; } ! fd = open(signaturename, O_WRONLY|O_CREAT|O_EXCL|O_NOCTTY, 0666); if( fd < 0 ) { free(signature_data); return RET_ERRNO(errno); *** updates.c.orig Wed Apr 9 01:01:43 2008 --- updates.c Tue Jun 10 11:36:45 2008 *************** *** 882,888 **** --- 882,892 ---- e, listdir, strerror(e)); return RET_ERRNO(e); } + #ifdef _D_EXACT_NAMELEN namelen = _D_EXACT_NAMLEN(r); + #else + namelen = strlen(r->d_name); + #endif if( namelen < patternlen || strncmp(pattern,r->d_name,patternlen) != 0) continue; if( foundinorigins(origins,nameoffset,r->d_name) ) *************** *** 1246,1252 **** if( f == 0 ) { int e; (void)closefrom(3); ! execl(listhook,listhook,index->filename,newfilename,NULL); e = errno; fprintf(stderr, "Error %d while executing '%s': %s\n", e, listhook, strerror(e)); --- 1250,1256 ---- if( f == 0 ) { int e; (void)closefrom(3); ! execl(listhook,listhook,index->filename,newfilename,(char*)NULL); e = errno; fprintf(stderr, "Error %d while executing '%s': %s\n", e, listhook, strerror(e));