Example #1
0
retvalue markdone_create(const char *codename, struct markdonefile **done_p) {
	struct markdonefile *done;

	done = NEW(struct markdonefile);
	if (FAILEDTOALLOC(done))
		return RET_ERROR_OOM;
	done->finalfilename = donefilename(codename);
	if (FAILEDTOALLOC(done->finalfilename)) {
		free(done);
		return RET_ERROR_OOM;
	}
	done->tempfilename = calc_addsuffix(done->finalfilename, "new");
	if (FAILEDTOALLOC(done->tempfilename)) {
		free(done->finalfilename);
		free(done);
		return RET_ERROR_OOM;
	}
	done->file = fopen(done->tempfilename, "w+");
	if (done->file == NULL) {
		int e = errno;
		fprintf(stderr, "Error %d creating '%s': %s\n",
				e, done->tempfilename, strerror(e));
		free(done->finalfilename);
		free(done->tempfilename);
		free(done);
		return RET_ERROR;
	}
	fprintf(done->file, "Updates already processed for %s:\n", codename);
	*done_p = done;
	return RET_OK;
}
Example #2
0
static retvalue callexporthook(/*@null@*/const char *hook, const char *relfilename, const char *mode, struct release *release) {
    pid_t f, c;
    int status;
    int io[2];
    char buffer[1000];
    int already = 0;

    if (hook == NULL)
        return RET_NOTHING;

    status = pipe(io);
    if (status < 0) {
        int e = errno;
        fprintf(stderr, "Error %d creating pipe: %s!\n",
                e, strerror(e));
        return RET_ERRNO(e);
    }

    f = fork();
    if (f < 0) {
        int e = errno;
        (void)close(io[0]);
        (void)close(io[1]);
        fprintf(stderr, "Error %d while forking for exporthook: %s\n",
                e, strerror(e));
        return RET_ERRNO(e);
    }
    if (f == 0) {
        char *reltmpfilename;
        int e;

        if (dup2(io[1], 3) < 0) {
            e = errno;
            fprintf(stderr, "Error %d dup2'ing fd %d to 3: %s\n",
                    e, io[1], strerror(e));
            exit(255);
        }
        /* "Doppelt haelt besser": */
        if (io[0] != 3)
            (void)close(io[0]);
        if (io[1] != 3)
            (void)close(io[1]);
        closefrom(4);
        /* backward compatibilty */
        reltmpfilename = calc_addsuffix(relfilename, "new");
        if (reltmpfilename == NULL) {
            exit(255);
        }
        setenv("REPREPRO_BASE_DIR", global.basedir, true);
        setenv("REPREPRO_OUT_DIR", global.outdir, true);
        setenv("REPREPRO_CONF_DIR", global.confdir, true);
        setenv("REPREPRO_DIST_DIR", global.distdir, true);
        setenv("REPREPRO_LOG_DIR", global.logdir, true);
        (void)execl(hook, hook, release_dirofdist(release),
                    reltmpfilename, relfilename, mode,
                    ENDOFARGUMENTS);
        e = errno;
        fprintf(stderr, "Error %d while executing '%s': %s\n",
                e, hook, strerror(e));
        exit(255);
    }
    close(io[1]);
    markcloseonexec(io[0]);

    if (verbose > 6)
        printf("Called %s '%s' '%s.new' '%s' '%s'\n",
               hook, release_dirofdist(release),
               relfilename, relfilename, mode);
    /* read what comes from the client */
    while (true) {
        ssize_t r;
        int last, j;

        r = read(io[0], buffer + already, 999 - already);
        if (r < 0) {
            int e = errno;
            fprintf(stderr,
                    "Error %d reading from exporthook: %s!\n",
                    e, strerror(e));
            break;
        }

        already += r;
        if (r == 0) {
            buffer[already] = '\0';
            already++;
        }
        last = 0;
        for (j = 0 ; j < already ; j++) {
            if (buffer[j] == '\n' || buffer[j] == '\0') {
                int next = j+1;
                int e = (j>0)?(j-1):j;
                retvalue ret;

                while (last < j && xisspace(buffer[last]))
                    last++;
                if (last >= j) {
                    last = next;
                    continue;
                }
                while (xisspace(buffer[e])) {
                    e--;
                    assert (e >= last);
                }

                ret = gotfilename(buffer + last, e - last + 1,
                                  release);
                if (RET_WAS_ERROR(ret)) {
                    (void)close(io[0]);
                    return ret;
                }
                last = next;
            }
        }
        if (last > 0) {
            if (already > last)
                memmove(buffer, buffer + last, already - last);
            already -= last;
        }
        if (r == 0)
            break;
    }
    (void)close(io[0]);
    do {
        c = waitpid(f, &status, WUNTRACED);
        if (c < 0) {
            int e = errno;
            fprintf(stderr,
                    "Error %d while waiting for hook '%s' to finish: %s\n", e, hook, strerror(e));
            return RET_ERRNO(e);
        }
    } while (c != f);
    if (WIFEXITED(status)) {
        if (WEXITSTATUS(status) == 0) {
            if (verbose > 6)
                printf("Exporthook successfully returned!\n");
            return RET_OK;
        } else {
            fprintf(stderr,
                    "Exporthook failed with exitcode %d!\n",
                    (int)WEXITSTATUS(status));
            return RET_ERROR;
        }
    } else if (WIFSIGNALED(status)) {
        fprintf(stderr, "Exporthook killed by signal %d!\n",
                (int)(WTERMSIG(status)));
        return RET_ERROR;
    } else {
        fprintf(stderr,
                "Exporthook terminated abnormally. (status is %x)!\n",
                status);
        return RET_ERROR;
    }
}