diff options
Diffstat (limited to 'debian/migrate/dma-migrate.c')
-rw-r--r-- | debian/migrate/dma-migrate.c | 413 |
1 files changed, 0 insertions, 413 deletions
diff --git a/debian/migrate/dma-migrate.c b/debian/migrate/dma-migrate.c deleted file mode 100644 index 56bfa2adbf87..000000000000 --- a/debian/migrate/dma-migrate.c +++ /dev/null @@ -1,413 +0,0 @@ -/*- - * Copyright (c) 2010 Peter Pentchev - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#define _GNU_SOURCE - -#include <sys/types.h> -#include <sys/file.h> -#include <sys/stat.h> - -#include <dirent.h> -#include <err.h> -#include <errno.h> -#include <fcntl.h> -#include <inttypes.h> -#include <regex.h> -#include <stdarg.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> -#include <unistd.h> - -#ifndef __printflike -#ifdef __GNUC__ -#define __printflike(fmtarg, firstvararg) \ - __attribute__((__format__ (__printf__, fmtarg, firstvararg))) -#else -#define __printflike(fmtarg, firstvararg) -#endif -#endif - -#define DEFAULT_SPOOLDIR "/var/spool/dma" - -static int verbose = 0; -static char copybuf[BUFSIZ]; - -static int dma_migrate(int, const char *); - -static int open_locked(const char *, int, ...); -static void cleanup_file(int, char *); - -static void usage(int); -static void version(void); -static void debug(const char *, ...) __printflike(1, 2); - -int -main(int argc, char **argv) -{ - const char *spooldir; - int hflag, Vflag, errs, fd, res; - int ch; - DIR *d; - struct dirent *e; - struct stat sb; - - srandom((unsigned long)((time(NULL) ^ getpid()) + ((uintptr_t)argv))); - - hflag = Vflag = 0; - spooldir = DEFAULT_SPOOLDIR; - while (ch = getopt(argc, argv, "d:hVv"), ch != -1) - switch (ch) { - case 'd': - spooldir = optarg; - break; - - case 'h': - hflag = 1; - break; - - case 'V': - Vflag = 1; - break; - - case 'v': - verbose = 1; - break; - - case '?': - default: - usage(1); - /* NOTREACHED */ - } - if (Vflag) - version(); - if (hflag) - usage(0); - if (hflag || Vflag) - exit(0); - - argc -= optind; - argv += optind; - - /* Let's roll! */ - if (chdir(spooldir) == -1) - err(1, "Could not change into spool directory %s", spooldir); - if (d = opendir("."), d == NULL) - err(1, "Could not read spool directory %s", spooldir); - errs = 0; - while (e = readdir(d), e != NULL) { - /* Do we care about this entry? */ - debug("Read a directory entry: %s\n", e->d_name); - if (strncmp(e->d_name, "tmp_", 4) == 0 || - e->d_name[0] == 'M' || e->d_name[0] == 'Q' || - (e->d_type != DT_REG && e->d_type != DT_UNKNOWN)) - continue; - if (e->d_type == DT_UNKNOWN) - if (stat(e->d_name, &sb) == -1 || !S_ISREG(sb.st_mode)) - continue; - debug("- want to process it\n"); - - /* Try to lock it - skip it if dma is delivering the message */ - if (fd = open_locked(e->d_name, O_RDONLY|O_NDELAY), fd == -1) { - debug("- seems to be locked, skipping\n"); - continue; - } - - /* Okay, convert it to the M/Q schema */ - res = dma_migrate(fd, e->d_name); - close(fd); - if (res == -1) - errs++; - } - if (errs) - debug("Finished, %d conversion errors\n", errs); - else - debug("Everything seems to be all right\n"); - return (errs && 1); -} - -static int -dma_migrate(int fd, const char *fname) -{ - const char *id; - char *mname, *qname, *tempname, *sender, *recp, *line, *recpline; - int mfd, qfd, tempfd; - struct stat sb; - FILE *fp, *qfp, *mfp; - size_t sz, len; - static regex_t *qidreg = NULL; - - mfd = tempfd = qfd = -1; - mname = qname = sender = recp = line = NULL; - fp = qfp = NULL; - - if (fstat(fd, &sb) == -1) { - warn("Could not fstat(%s)", fname); - return (-1); - } - /* - * Let's just blithely assume that the queue ID *is* the filename, - * since that's the way dma did things so far. - * Well, okay, let's check it. - */ - if (qidreg == NULL) { - regex_t *nreg; - - if ((nreg = malloc(sizeof(*qidreg))) == NULL) { - warn("Could not allocate memory for a regex"); - return (-1); - } - if (regcomp(nreg, "^[a-fA-F0-9]\\+\\.[a-fA-F0-9]\\+$", 0) - != 0) { - warnx("Could not compile a dma queue ID regex"); - free(nreg); - return (-1); - } - qidreg = nreg; - } - if (regexec(qidreg, fname, 0, NULL, 0) != 0) { - warnx("The name '%s' is not a valid dma queue ID", fname); - return (-1); - } - id = fname; - debug(" - queue ID %s\n", id); - if (asprintf(&mname, "M%s", id) == -1 || - asprintf(&tempname, "tmp_%s", id) == -1 || - asprintf(&qname, "Q%s", id) == -1 || - mname == NULL || tempname == NULL || qname == NULL) - goto fail; - - /* Create the message placeholder early to avoid races */ - mfd = open_locked(mname, O_CREAT | O_EXCL | O_RDWR, 0600); - if (mfd == -1) { - warn("Could not create temporary file %s", mname); - goto fail; - } - if (stat(qname, &sb) != -1 || errno != ENOENT || - stat(tempname, &sb) != -1 || errno != ENOENT) { - warnx("Some of the queue files for %s already exist", fname); - goto fail; - } - debug(" - mfd %d names %s, %s, %s\n", mfd, mname, tempname, qname); - - fp = fdopen(fd, "r"); - if (fp == NULL) { - warn("Could not reopen the descriptor for %s", fname); - goto fail; - } - - /* Parse the header of the old-format message file */ - /* ...sender... */ - if (getline(&sender, &sz, fp) == -1) { - warn("Could not read the initial line from %s", fname); - goto fail; - } - sz = strlen(sender); - while (sz > 0 && (sender[sz - 1] == '\n' || sender[sz - 1] == '\r')) - sender[--sz] = '\0'; - if (sz == 0) { - warnx("Empty sender line in %s", fname); - goto fail; - } - debug(" - sender %s\n", sender); - /* ...recipient(s)... */ - len = strlen(fname); - recpline = NULL; - while (1) { - if (getline(&line, &sz, fp) == -1) { - warn("Could not read a recipient line from %s", fname); - goto fail; - } - sz = strlen(line); - while (sz > 0 && - (line[sz - 1] == '\n' || line[sz - 1] == '\r')) - line[--sz] = '\0'; - if (sz == 0) { - free(line); - line = NULL; - break; - } - if (recp == NULL && - strncmp(line, fname, len) == 0 && line[len] == ' ') { - recp = line + len + 1; - recpline = line; - } else { - free(line); - } - line = NULL; - } - if (recp == NULL) { - warnx("Could not find its own recipient line in %s", fname); - goto fail; - } - /* ..phew, finished with the header. */ - - tempfd = open_locked(tempname, O_CREAT | O_EXCL | O_RDWR, 0600); - if (tempfd == -1) { - warn("Could not create a queue file for %s", fname); - goto fail; - } - qfp = fdopen(tempfd, "w"); - if (qfp == NULL) { - warn("Could not fdopen(%s) for %s", tempname, fname); - goto fail; - } - mfp = fdopen(mfd, "w"); - if (mfp == NULL) { - warn("Could not fdopen(%s) for %s", mname, fname); - goto fail; - } - fprintf(qfp, "ID: %s\nSender: %s\nRecipient: %s\n", id, sender, recp); - fflush(qfp); - fsync(tempfd); - - /* Copy the message file over to mname */ - while ((sz = fread(copybuf, 1, sizeof(copybuf), fp)) > 0) - if (fwrite(copybuf, 1, sz, mfp) != sz) { - warn("Could not copy the message from %s to %s", - fname, mname); - goto fail; - } - if (ferror(fp)) { - warn("Could not read the full message from %s", fname); - goto fail; - } - fflush(mfp); - fsync(mfd); - - if (rename(tempname, qname) == -1) { - warn("Could not rename the queue file for %s", fname); - goto fail; - } - qfd = tempfd; - tempfd = -1; - if (unlink(fname) == -1) { - warn("Could not remove the old converted file %s", fname); - goto fail; - } - - fclose(fp); - fclose(qfp); - free(sender); - free(line); - free(recpline); - free(mname); - free(qname); - free(tempname); - return (0); - -fail: - if (fp != NULL) - fclose(fp); - if (qfp != NULL) - fclose(qfp); - if (sender != NULL) - free(sender); - if (line != NULL) - free(line); - if (recpline != NULL) - free(recpline); - cleanup_file(mfd, mname); - cleanup_file(qfd, qname); - cleanup_file(tempfd, tempname); - return (-1); -} - -static void -cleanup_file(int fd, char *fname) -{ - if (fd != -1) { - close(fd); - unlink(fname); - } - if (fname != NULL) - free(fname); -} - -static void -usage(int ferr) -{ - const char *s = - "Usage:\tdma-migrate [-hVv] [-d spooldir]\n" - "\t-d\tspecify the spool directory (" DEFAULT_SPOOLDIR ")\n" - "\t-h\tdisplay program usage information and exit\n" - "\t-V\tdisplay program version information and exit\n" - "\t-v\tverbose operation - display diagnostic messages"; - - if (ferr) - errx(1, "%s", s); - puts(s); -} - -static void -version(void) -{ - printf("dma-migrate 0.01 (dma 0.0.2010.06.17)\n"); -} - -static void -debug(const char *fmt, ...) -{ - va_list v; - - if (verbose < 1) - return; - va_start(v, fmt); - vfprintf(stderr, fmt, v); - va_end(v); -} - -static int -open_locked(const char *fname, int flags, ...) -{ - int mode = 0; -#ifndef O_EXLOCK - int fd, save_errno; -#endif - - if (flags & O_CREAT) { - va_list ap; - va_start(ap, flags); - mode = va_arg(ap, int); - va_end(ap); - } - -#ifndef O_EXLOCK - fd = open(fname, flags, mode); - if (fd < 0) - return(fd); - if (flock(fd, LOCK_EX|((flags & O_NONBLOCK)? LOCK_NB: 0)) < 0) { - save_errno = errno; - close(fd); - errno = save_errno; - return(-1); - } - return(fd); -#else - return(open(fname, flags|O_EXLOCK, mode)); -#endif -} |