Hello, Your patch is wrong because you are using `char *textfile` in the first snprintf without initializing it. I made a patch which fixes the bug and works on the Hurd.
Regards, Arnaud Fontaine
diff -uN trr19-1.0beta5.orig/trr_format.c trr19-1.0beta5/trr_format.c --- trr19-1.0beta5.orig/trr_format.c 2007-01-21 21:19:23.000000000 +0100 +++ trr19-1.0beta5/trr_format.c 2007-01-21 18:56:58.000000000 +0100 @@ -21,6 +21,11 @@ #include <signal.h> #include <errno.h> #include <pwd.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <unistd.h> + +#include "utils.h" #if defined(HAVE_STRING_H) #include <string.h> @@ -40,12 +45,16 @@ main(int argc, char **argv){ - char textfile[256], formattedfile[256], lockfile[256], *tmpfname; - char command[256], line[1024]; + int err = 0; FILE *fd, *tmpfd; + size_t len=0; + pid_t ret; int i; struct passwd *pw = NULL; - + int tmpfnamefd = 0; + char *textfile = NULL, *lockfile = NULL, *formattedfile = NULL, + *command = NULL, *line = NULL; + char tmpfname[] = "/tmp/trr_update.XXXXXX"; /* ignore signals */ signal(SIGHUP, SIG_IGN); @@ -53,14 +62,16 @@ signal(SIGQUIT, SIG_IGN); signal(SIGTERM, SIG_IGN); - strcpy(textfile, TEXT_DIR); - strcat(textfile, argv[1]); - strcpy(formattedfile, textfile); - strcat(formattedfile, ".formed"); - strcpy(lockfile, textfile); - strcat(lockfile, ".lock"); + if(argc < 2){ + fprintf(stderr, "%s: %s\n", argv[0], strerror (EINVAL)); + exit(1); + } + + my_asprintf(&textfile, "%s%s", TEXT_DIR, argv[1]); + my_asprintf(&formattedfile, "%s.formed", textfile); + my_asprintf(&lockfile, "%s.lock", textfile); - umask(18); + umask(022); /* if previous process is formatting same target text, wait for that process to finish formatting. */ @@ -81,47 +92,82 @@ } } /* successfully formatted */ - unlink(lockfile); - return 0; + exit(0); } else{ perror(lockfile); exit(1); } else{ + tmpfnamefd = mkstemp(tmpfname); + /* format a text - fork and exec the processes so we can drop privileges */ switch( fork() ) { case -1: /* Error */ - perror(fork); + perror("fork"); exit(1); break; case 0: /* Child */ - tmpfname = tmpnam(NULL); unlink(formattedfile); /* Drop group privileges */ pw = getpwuid(getuid()); + if(!pw){ + unlink(lockfile); + fprintf(stderr, "You don't exist..go away\n"); + exit(1); + } + setgid(pw->pw_gid); - sprintf(command, "%s -v '^[ \t]*$' %s | %s 's/\\([.?!;]\\) *$/\\1/' | %s 's/^ *\\(.*\\)$/\\1/' > %s", - GREP, textfile, SED, SED, tmpfname); - system(command); + if (my_asprintf(&command, "%s -v '^[ \t]*$' %s | %s 's/\\([.?!;]\\) *$/\\1/' | %s 's/^ *\\(.*\\)$/\\1/' > %s", + GREP, textfile, SED, SED, tmpfname) == -1 || tmpfnamefd == -1) + { + if (tmpfnamefd != -1) + unlink(lockfile); + + perror("temporary file creation"); + exit(1); + } + + execl("/bin/sh", "sh", "-c", command); break; default: /* Parent */ + do + ret = wait (NULL); + while (!(ret == -1 && errno == ECHILD)); break; } - tmpfd = fopen(tmpfname, "r"); + unlink(tmpfname); + tmpfd = fdopen(tmpfnamefd, "r"); + if (!tmpfd){ + unlink(lockfile); + perror("fopen"); + exit(1); + } + fd = fopen(formattedfile, "w"); - - while(fgets(line, 1024, tmpfd)) + if (!fd){ + unlink(lockfile); + perror("fopen"); + exit(1); + } + + while(my_getline(&line, &len, tmpfd) != -1) fputs(line, fd); + /* release lock */ + unlink(lockfile); + + free(line); + free(command); + free(formattedfile); + free(textfile); + free(lockfile); + fclose(tmpfd); fclose(fd); - unlink(tmpfname); - /* release lock */ - unlink(lockfile); - return 0; + return err; } } diff -uN trr19-1.0beta5.orig/trr_update.c trr19-1.0beta5/trr_update.c --- trr19-1.0beta5.orig/trr_update.c 2007-01-21 21:19:23.000000000 +0100 +++ trr19-1.0beta5/trr_update.c 2007-01-21 21:18:12.000000000 +0100 @@ -21,6 +21,9 @@ #include <stdlib.h> #include <signal.h> #include <errno.h> +#include <time.h> + +#include "utils.h" #if defined(HAVE_STRING_H) #include <string.h> @@ -45,9 +48,12 @@ #endif /* HAVE_FCNTL_H */ main(int argc, char **argv){ - char scorefile[256], lockfile[256], datestr[64]; - char line[256], savedline[256]; - const char *user, *scores, *step, *times, *ttime, *token; + char *scorefile = NULL, *lockfile = NULL, *line = NULL, *savedline = NULL; + char *user = NULL, *scores = NULL, *step = NULL, *times = NULL, + *ttime = NULL, *token = NULL; + size_t len=0; + char datestr[64]; + FILE *fd, *tmpf; int score, tmpscore, i, myself, inserted; long datev; @@ -59,12 +65,16 @@ signal(SIGTERM, SIG_IGN); umask(18); - strcpy(scorefile, RECORD_DIR); + + if (argc < 7){ + fprintf(stderr, "too few arguments\n"); + exit(1); + } + + my_asprintf (&scorefile, "%s%s", RECORD_DIR, argv[1]); /* create a new record file */ if (argc == 2){ - strcat(scorefile, argv[1]); - if ((fd = fopen(scorefile, "w")) == NULL){ perror(scorefile); exit(1); @@ -73,10 +83,9 @@ exit(0); } - /* upfate high score file */ - strcat(scorefile, argv[1]); - strcpy(lockfile, scorefile); - strcat(lockfile, ".lock"); + /* update high score file */ + my_asprintf(&lockfile, "%s.lock", scorefile); + user = argv[2]; scores = argv[3]; score = atoi(argv[3]); @@ -110,13 +119,19 @@ inserted = 0; /* sorting ... */ - while (fgets(line, 256, fd)){ + while (my_getline(&line, &len, fd) != -1){ myself = 0; - strcpy(savedline, line); - token = (char*)strtok(line, " \t"); - if (! strcmp(user, token)) + savedline = strdup(line); + token = strtok(line, " \t"); + if (token && !strcmp(user, token)) myself = 1; - token = (char*)strtok(NULL, " \t"); + + token = strtok(NULL, " \t"); + if (!token){ + perror("strok"); + exit(1); + } + tmpscore = atoi(token); if ((! inserted) && (tmpscore <= score)){ inserted = 1; @@ -146,12 +161,18 @@ unlink(lockfile); exit(1); } - while (fgets(line, 256, tmpf)) + while (my_getline(&line, &len, tmpf) != -1) fputs(line, fd); fclose(tmpf); fclose(fd); + free(line); + free(lockfile); + free(scorefile); + free(savedline); + free(token); + /* release lock */ unlink(lockfile); return 0; Les fichiers binaires trr19-1.0beta5.orig/trr_update.o et trr19-1.0beta5/trr_update.o sont différents. diff -uN trr19-1.0beta5.orig/utils.c trr19-1.0beta5/utils.c --- trr19-1.0beta5.orig/utils.c 1970-01-01 01:00:00.000000000 +0100 +++ trr19-1.0beta5/utils.c 2007-01-21 14:39:46.000000000 +0100 @@ -0,0 +1,98 @@ +/* utils.c -- utils functions for trr19 + * Last modified on Sun Jan 01 01:10:21 2007 + * Copyright (C) 2007 Arnaud Fontaine <[EMAIL PROTECTED]> + */ + +/* This file is a part of TRR19, a type training software on + * GNU Emacs. + * + * You can redistribute it and/or modify it under the terms of + * the version 2 of GNU General Public License as published by the + * Free Software Foundation. + * + * TRR19 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. + */ + +#ifndef __GLIBC__ + +#include <errno.h> +#include <string.h> +#include <stdlib.h> +#include <stdio.h> +#include <stdarg.h> + +#include "utils.h" + +ssize_t my_getline(char **lineptr, size_t *n, FILE *stream) +{ + char *ret = NULL; + + if(lineptr == NULL || n == NULL) + { + errno = EINVAL; + return -1; + } + + if(*n == 0) + { + *lineptr = malloc(CHUNK_SIZE); + *n = CHUNK_SIZE; + } + + ret = fgets (*lineptr, *n, stream); + while(ret != NULL && (*lineptr)[strlen (*lineptr) - 1] != '\n') + { + *n += CHUNK_SIZE; + *lineptr = realloc(*lineptr, *n); + + ret = fgets(*lineptr + strlen (*lineptr), CHUNK_SIZE, stream); + } + + if (ret == NULL) + return -1; + + return strlen (*lineptr); +} + +int my_asprintf(char **str, const char *fmt, ...) +{ + int size; + va_list ap; + int n; + + if(*str == NULL) + { + *str = malloc(CHUNK_SIZE); + if (*str == NULL) + return -1; + + size = CHUNK_SIZE; + } + else + size = strlen (*str); + + va_start (ap, fmt); + n = vsnprintf (*str, size, fmt, ap); + + while (n >= size) + { + size += CHUNK_SIZE; + *str = realloc(*str, size); + if (*str == NULL) + { + errno = ENOMEM; + return -1; + } + + n = vsnprintf (*str, size, fmt, ap); + } + + va_end (ap); + + return n; +} + +#endif diff -uN trr19-1.0beta5.orig/utils.h trr19-1.0beta5/utils.h --- trr19-1.0beta5.orig/utils.h 1970-01-01 01:00:00.000000000 +0100 +++ trr19-1.0beta5/utils.h 2007-01-21 20:43:31.000000000 +0100 @@ -0,0 +1,34 @@ +/* utils.h -- header for utils functions for trr19 + * Last modified on Sun Jan 01 01:10:21 2007 + * Copyright (C) 2007 Arnaud Fontaine <[EMAIL PROTECTED]> + */ + +/* This file is a part of TRR19, a type training software on + * GNU Emacs. + * + * You can redistribute it and/or modify it under the terms of + * the version 2 of GNU General Public License as published by the + * Free Software Foundation. + * + * TRR19 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. + */ + +#ifndef UTILS_H +#define UTILS_H + +#define CHUNK_SIZE 4096 + +/* GLibc provides getline and asprintf, which allocate automatically + the memory and replaces respectively fgets and sprintf */ +#ifdef __GLIBC__ +# define my_getline getline +# define my_asprintf asprintf +#else +ssize_t my_getline(char **lineptr, size_t *n, FILE *stream); +int my_asprintf(char **str, const char *fmt, ...); +#endif /* !__GLIBC__ */ + +#endif Les fichiers binaires trr19-1.0beta5.orig/utils.o et trr19-1.0beta5/utils.o sont différents.