--- trr_format.c.orig 2007-01-31 16:59:49.000000000 +0100 +++ trr_format.c 2007-01-31 15:16:52.000000000 +0100 @@ -20,6 +20,12 @@ #include #include #include +#include +#include +#include +#include + +#include "utils.h" #if defined(HAVE_STRING_H) #include @@ -38,11 +44,17 @@ #endif /* HAVE_FCNTL_H */ -main(int argc, char **argv){ - char textfile[256], formattedfile[256], lockfile[256], *tmpfname; - char command[256], line[1024]; +int main(int argc, char **argv){ + 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); @@ -50,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. */ @@ -78,32 +92,83 @@ } } /* successfully formatted */ - unlink(lockfile); - return 0; + exit(0); } else{ perror(lockfile); exit(1); } else{ - /* format a text */ - tmpfname = tmpnam(NULL); - unlink(formattedfile); - sprintf(command, "%s -v '^[ \t]*$' %s | %s 's/\\([.?!;]\\) *$/\\1/' | %s 's/^ *\\(.*\\)$/\\1/' > %s", - GREP, textfile, SED, SED, tmpfname); - system(command); + tmpfnamefd = mkstemp(tmpfname); - tmpfd = fopen(tmpfname, "r"); - fd = fopen(formattedfile, "w"); + /* format a text - fork and exec the processes so we can drop privileges */ + switch( fork() ) { + case -1: /* Error */ + perror("fork"); + exit(1); + break; + case 0: /* Child */ + unlink(formattedfile); + + /* Drop group privileges */ + pw = getpwuid(getuid()); + if(!pw){ + unlink(lockfile); + fprintf(stderr, "You don't exist..go away\n"); + exit(1); + } - while(fgets(line, 1024, tmpfd)) - fputs(line, fd); + setgid(pw->pw_gid); - fclose(tmpfd); - fclose(fd); + 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, NULL); + break; + default: /* Parent */ + do + ret = wait (NULL); + while (!(ret == -1 && errno == ECHILD)); + break; + } + + tmpfd = fdopen(tmpfnamefd, "r"); + if (!tmpfd){ + unlink(lockfile); + perror("fopen"); + exit(1); + } + + fd = fopen(formattedfile, "w"); + if (!fd){ + unlink(lockfile); + perror("fopen"); + exit(1); + } + + while(my_getline(&line, &len, tmpfd) != -1) + fputs(line, fd); + unlink(tmpfname); /* release lock */ unlink(lockfile); - return 0; + + free(line); + free(command); + free(formattedfile); + free(textfile); + free(lockfile); + + fclose(tmpfd); + fclose(fd); + + return err; } }