--- ../tmp/trr19-1.0beta5/trr_format.c 2007-01-21 17:45:06.000000000 +0100 +++ trr_format.c 2007-01-21 18:45:35.000000000 +0100 @@ -21,6 +21,11 @@ #include #include #include +#include +#include +#include + +#include "utils.h" #if defined(HAVE_STRING_H) #include @@ -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,83 @@ } } /* 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"); + 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); - - fclose(tmpfd); - fclose(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; } }