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));

Reply via email to