Re: Re: snnewgroup: Segmentation fault on ppc systems

Chris Niekel <[email protected]>
Newsgroups gmane.network.sn
Message-ID <[email protected]>
On Mon, Dec 15, 2003 at 01:52:56AM +0100, Sebastian D.B. Krause wrote:
> Chris Niekel <[email protected]> wrote:
> > I'll try to make those changes soon, and have them tested by the
> > debian developer and hopefully you.
> 
> Of coure I'll help if I can. Is there any progress in the fix yet?

Yes, I made some progress. If you could apt-get source sn, and apply the
attached patch (cd sn-0.3.6; patch -p1 < ..../sn-ppc.patch). If you then
build the program, I'd like to hear if you can create newsgroups, and
hopefully read news as well.

Let me know how it went!

Chris


-- 
    I've been down so long, if I'd cheer up, I'd still be depressed.
            - Lisa Simpson, Moanin' Lisa Blues.
sn-ppc.patch (text/plain, 7.8 KB)
M  args.c
M  parameters.c
M  debian/changelog
M  lib/openf.c
M  lib/out.c
M  lib/statf.c
M  lib/format.c
M  lib/format.h
M  lib/log.c

* modified files

--- orig/args.c
+++ mod/args.c
@@ -24,8 +24,9 @@
    int len;
 
    va_start(ap, fmt);
-
    len = formatv(args_outbuf, sizeof (args_outbuf) - 2, fmt, ap);
+   va_end(ap);
+
    if (-1 == write(fd, args_outbuf, len))
    {
       *args_outbuf = '\0';


--- orig/debian/changelog
+++ mod/debian/changelog
@@ -1,3 +1,10 @@
+sn (0.3.6-4) unstable; urgency=low
+
+  * Fix va_start/va_end mess, and missing parameters in code, so this 
+    will run on ppc. (Thanks to Michael K. Edwards for help!)
+
+ -- Chris Niekel <[email protected]>  Tue,  9 Dec 2003 17:44:52 +0100
+
 sn (0.3.6-3) unstable; urgency=low
 
   * Remove the debian.old directory, which I accidentally added.


--- orig/lib/format.c
+++ mod/lib/format.c
@@ -8,12 +8,13 @@
 #include <string.h>
 #include <errno.h>
 #include <stdarg.h>
+#include "format.h"
 
 static const char rcsid[] = "$Id$";
 
 static char *ichars = "0123456789abcdefghijklmnopqrstuvwxyz";
 
-char *istr (int i, int base, char tmp[40])
+char *istr (int i, int base, char *tmp)
 {
    int n;
    int negative = 0;
@@ -32,7 +33,7 @@
    return (tmp + n);
 }
 
-char *uistr (unsigned int u, int base, char tmp[40])
+char *uistr (unsigned int u, int base, char *tmp)
 {
    int n;
 
@@ -43,36 +44,6 @@
    return (tmp + n);
 }
 
-char *vachar (int c, va_list * app, char tmp[40], int *len)
-{
-   int e;
-   int i;
-   unsigned u;
-   char *p;
-
-   e = errno;
-   switch (c)
-   {
-      case 'S': *len = va_arg(*app, int); return (va_arg(*app, char *));
-      case 's': p = va_arg(*app, char *); break;
-      case 'i': /* Fall Through */
-      case 'd': i = va_arg(*app, int); p = istr(i, 10, tmp); break;
-      case 'u': u = va_arg(*app, unsigned); p = uistr(u, 10, tmp); break;
-      case 'o': u = va_arg(*app, unsigned); p = uistr(u, 8, tmp); break;
-      case 'x': u = va_arg(*app, unsigned); p = uistr(u, 16, tmp); break;
-      case 'm': p = strerror(e); break;
-      case '%': *len = 1; return ("%");
-      default: *len = 0; return ("");
-   }
-   if (!p)
-   {
-      *len = 6;
-      return ("(null)");
-   }
-   *len = strlen(p);
-   return (p);
-}
-
 int formatv (char *buf, int size, char *fmt, va_list ap)
 {
    char *p;
@@ -88,7 +59,7 @@
       if ('%' == *fmt)
       {
          fmt++;
-         p = vachar(*fmt, &ap, tmp, &len);
+         vachar(*fmt, ap, len);
          for (; len; len--)
          {
             *buf++ = *p++;
@@ -113,4 +84,5 @@
 
    va_start(ap, fmt);
    return (formatv(buf, size, fmt, ap));
+   va_end(ap);
 }


--- orig/lib/format.h
+++ mod/lib/format.h
@@ -17,17 +17,55 @@
 
 /* Print integer into tmp, returns pointer to start of it */
 
-extern char *istr (int i, int base, char tmp[40]);
-extern char *uistr (unsigned int u, int base, char tmp[40]);
+extern char *istr (int i, int base, char *tmp);
+extern char *uistr (unsigned int u, int base, char *tmp);
 
-/* Returns string based on format character c.  length of string,
-which may NOT be null terminated, is in *len. */
 
-extern char *vachar (int c, va_list * app, char tmp[40], int *len);
 
 /* 2 forms, like snprintf */
 
 extern int formatv (char *buf, int size, char *fmt, va_list ap);
 extern int formats (char *buf, int size, char *fmt, ...);
 
+/* "Returns" string based on format character c.  length of string,
+which may NOT be null terminated, is in len. 
+This is a macro, because it uses va_arg, and you can only use that in a
+single function call. */
+#define vachar(c, ap, len) \
+         { \
+             int e, i; \
+             unsigned u; \
+             p = 0; \
+             switch(c) \
+             { \
+                 case 'S': len = va_arg(ap, int); p = va_arg(ap, char *); \
+                           break; \
+                 case 's': p = va_arg(ap, char*); \
+                           len = strlen(p); \
+                           /*printf("string has length %d (%s)\n", len, p);*/ \
+                           break; \
+                 case 'i': /* fall through */ \
+                 case 'd': i = va_arg(ap, int);  \
+                           p = istr(i, 10, tmp);  \
+                           len = strlen(p); \
+                           break; \
+                 case 'u': u = va_arg(ap, unsigned); p = uistr(u, 10, tmp); \
+                           len = strlen(p); \
+                           break; \
+                 case 'o': u = va_arg(ap, unsigned); p = uistr(u, 8, tmp); \
+                           len = strlen(p); \
+                           break; \
+                 case 'x': u = va_arg(ap, unsigned); p = uistr(u, 16, tmp); \
+                           len = strlen(p); \
+                           break; \
+                 case 'm': p = strerror(errno); \
+                           len = strlen(p); \
+                           break; \
+                 case '%': len = 1; \
+                           p = "%"; \
+                           break; \
+                 default:  len = 0; \
+                           p = ""; \
+             } \
+         }
 #endif


--- orig/lib/log.c
+++ mod/lib/log.c
@@ -42,5 +42,6 @@
 
    va_start(ap, fmt);
    logv(fmt, ap);
+   va_end(ap);
    _exit(ex);
 }


--- orig/lib/openf.c
+++ mod/lib/openf.c
@@ -17,10 +17,14 @@
 
 int openf (int mode, int flags, char *fmt, ...)
 {
+   int len;
    va_list ap;
 
    va_start(ap, fmt);
-   if (formatv(buf, sizeof (buf) - 1, fmt, ap) >= sizeof (buf))
+   len = formatv(buf, sizeof (buf) - 1, fmt, ap);
+   va_end(ap);
+
+   if (len >= sizeof (buf))
    {
       errno = ENAMETOOLONG;
       return (-1);


--- orig/lib/out.c
+++ mod/lib/out.c
@@ -36,7 +36,7 @@
          fmt++;
          if (!*fmt)
             break;
-         p = vachar(*fmt, &ap, tmp, &len);
+         vachar(*fmt, ap, len);
          for (; len; len--)
          {
             if (used >= sizeof (outbuf))


--- orig/lib/statf.c
+++ mod/lib/statf.c
@@ -16,10 +16,14 @@
 
 int statf (struct stat *stp, char *fmt, ...)
 {
+   int len;
    va_list ap;
 
    va_start(ap, fmt);
-   if (formatv(buf, sizeof (buf) - 1, fmt, ap) >= sizeof (buf))
+   len = formatv(buf, sizeof (buf) - 1, fmt, ap);
+   va_end(ap);
+
+   if (len >= sizeof (buf))
    {
       errno = ENAMETOOLONG;
       return (-1);


--- orig/parameters.c
+++ mod/parameters.c
@@ -19,6 +19,8 @@
 uid_t snuid;
 gid_t sngid;
 
+#define MAXPWGRLEN 32
+
 void parameters (int wantwriteperms)
 {
    struct stat st;
@@ -27,9 +29,9 @@
       snroot = SNROOT;
 
    if (-1 == stat(snroot, &st))
-      fail(2, "Can't find \"%s\":%m");
+      fail(2, "Can't find \"%s\":%m", snroot);
    if (!S_ISDIR(st.st_mode))
-      fail(2, "%s is not a directory");
+      fail(2, "%s is not a directory", snroot);
    snuid = st.st_uid;
    sngid = st.st_gid;
    if (0 == geteuid())
@@ -41,11 +43,19 @@
    if (wantwriteperms)
       if (snuid != geteuid() || sngid != getegid())
       {
-         char euid_name[10], egid_name[10];
+         struct passwd *uid_pw;
+         struct group *gid_gr;
+         char euid_name[MAXPWGRLEN], egid_name[MAXPWGRLEN];
 
-         strncpy(euid_name, (getpwuid(geteuid()))->pw_name, 10);
-         strncpy(egid_name, (getgrgid(getegid()))->gr_name, 10);
+	 uid_pw = getpwuid(geteuid());
+         strncpy(euid_name, uid_pw ? uid_pw->pw_name : "(unknown)", MAXPWGRLEN-1);
+	 euid_name[MAXPWGRLEN-1] = '\0';
+         gid_gr = getgrgid(getegid());
+         strncpy(egid_name, gid_gr ? gid_gr->gr_name : "(unknown)", MAXPWGRLEN-1);
+	 egid_name[MAXPWGRLEN-1] = '\0';
+	 uid_pw = getpwuid(snuid);
+         gid_gr = getgrgid(sngid);
          fail(2, "Can't write in %s (I am %s.%s, must be %s.%s)", snroot,
-              euid_name, egid_name, (getpwuid(snuid))->pw_name, (getgrgid(sngid))->gr_name);
+              euid_name, egid_name, uid_pw ? uid_pw->pw_name : "(dunno)", gid_gr ? gid_gr->gr_name : "(dunno)");
       }
 }
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.