diff --git a/src/odt.c b/src/odt.c index 60fe465..2674871 100644 --- a/src/odt.c +++ b/src/odt.c @@ -72,9 +72,40 @@ createOutputDocument(const char* const outputFilename, const char* const tempDir pid_t child_pid; if ((child_pid = fork()) == 0) { /* you are the child */ + + /* In some implementations, realpath will give an error + * if the file does not exist, so we need to run it on + * the output directory, not the as-yet nonexistent + * output filename. That's what all this (below) is for. */ + char outputDir[FILENAME_MAX]; + char outputBase[FILENAME_MAX]; char outputRealPath[FILENAME_MAX]; + strncpy(outputDir, outputFilename, FILENAME_MAX); + char *ptr = strrchr(outputDir, '/'); + if (ptr) { + strncpy(outputBase, ptr + 1, FILENAME_MAX); + *(ptr + 1) = '\0'; + } else { + strncpy(outputDir, ".", FILENAME_MAX); + strncpy(outputBase, outputFilename, FILENAME_MAX); + } + + if (realpath(outputDir, outputRealPath) == NULL) { + /* hopefully this doesn't run, but it will give good info + * if it does */ + perror("realpath"); + fprintf(stderr, "outputFilename was \"%s\"\n", outputFilename); + char curdir[FILENAME_MAX]; + getcwd(curdir, FILENAME_MAX); + fprintf(stderr, "curdir was \"%s\"\n", curdir); + exit(1); + } + + /* Then we append the output filename. */ + strncat(outputRealPath, "/", FILENAME_MAX); + strncat(outputRealPath, outputBase, FILENAME_MAX); + char* const args[] = { "zip", "-r", outputRealPath, "mimetype", ".", NULL }; - realpath(outputFilename, outputRealPath); chdir(tempDir); freopen("/dev/null", "w", stdout); execvp("zip", args);