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