コード例 #1
0
ファイル: t-buffer.c プロジェクト: CharizTeam/dpkg
static void
test_fdio_hash(void)
{
	char hash[MD5HASHLEN + 1];
	char *test_file;
	int fd;

	test_file = test_alloc(strdup("test.XXXXXX"));
	fd = mkstemp(test_file);
	test_pass(fd >= 0);

	test_pass(fd_md5(fd, hash, -1, NULL) >= 0);
	test_str(hash, ==, ref_hash_empty);

	test_pass(write(fd, str_test, strlen(str_test)) == strlen(str_test));
	test_pass(lseek(fd, 0, SEEK_SET) == 0);

	test_pass(fd_md5(fd, hash, -1, NULL) >= 0);
	test_str(hash, ==, ref_hash_test);

	test_pass(unlink(test_file) == 0);
}
コード例 #2
0
ファイル: split.c プロジェクト: jtniehof/dpkg
static int
mksplit(const char *file_src, const char *prefix, size_t partsize,
        size_t maxpartsize, bool msdos)
{
	int fd_src;
	struct stat st;
	char hash[MD5HASHLEN + 1];
	char *package, *version;
	int nparts, curpart;
	off_t startat;
	char *prefixdir = NULL, *msdos_prefix = NULL;
	struct varbuf file_dst = VARBUF_INIT;
	struct varbuf partmagic = VARBUF_INIT;
	struct varbuf partname = VARBUF_INIT;
	char *partdata;

	fd_src = open(file_src, O_RDONLY);
	if (fd_src < 0)
		ohshite(_("unable to open source file `%.250s'"), file_src);
	if (fstat(fd_src, &st))
		ohshite(_("unable to fstat source file"));
	if (!S_ISREG(st.st_mode))
		ohshit(_("source file `%.250s' not a plain file"), file_src);

	fd_md5(fd_src, hash, -1, "md5hash");
	lseek(fd_src, 0, SEEK_SET);

	/* FIXME: Use libdpkg-deb. */
	package = deb_field(file_src, "Package");
	version = deb_field(file_src, "Version");

	nparts = (st.st_size + partsize - 1) / partsize;

	setvbuf(stdout, NULL, _IONBF, 0);

	printf("Splitting package %s into %d parts: ", package, nparts);

	if (msdos) {
		char *t;

		t = m_strdup(prefix);
		prefixdir = m_strdup(dirname(t));
		free(t);

		t = m_strdup(prefix);
		msdos_prefix = m_strdup(basename(t));
		free(t);

		prefix = clean_msdos_filename(msdos_prefix);
	}

	partdata = m_malloc(partsize);
	curpart = 1;

	for (startat = 0; startat < st.st_size; startat += partsize) {
		int fd_dst;
		ssize_t partrealsize;

		varbufreset(&file_dst);
		/* Generate output filename. */
		if (msdos) {
			struct varbuf refname = VARBUF_INIT;
			int prefix_max;

			varbufprintf(&refname, "%dof%d", curpart, nparts);
			prefix_max = max(8 - strlen(refname.buf), 0);
			varbufprintf(&file_dst, "%s/%.*s%.8s.deb",
			             prefixdir, prefix_max, prefix,
			             refname.buf);
			varbuf_destroy(&refname);
		} else {
			varbufprintf(&file_dst, "%s.%dof%d.deb",
			             prefix, curpart, nparts);
		}

		/* Read data from the original package. */
		partrealsize = read(fd_src, partdata, partsize);
		if (partrealsize < 0)
			ohshite("mksplit: read");

		if ((size_t)partrealsize > maxpartsize) {
			ohshit("Header is too long, making part too long. "
			       "Your package name or version\n"
			       "numbers must be extraordinarily long, "
			       "or something. Giving up.\n");
		}

		/* Split the data. */
		fd_dst = open(file_dst.buf, O_CREAT | O_WRONLY, 0644);
		if (fd_dst < 0)
			ohshite(_("unable to open file '%s'"), file_dst.buf);

		/* Write the ar header. */
		dpkg_ar_put_magic(file_dst.buf, fd_dst);

		/* Write the debian-split part. */
		varbufprintf(&partmagic, "%s\n%s\n%s\n%s\n%zu\n%zu\n%d/%d\n",
		             SPLITVERSION, package, version, hash,
		             st.st_size, partsize, curpart, nparts);
		dpkg_ar_member_put_mem(file_dst.buf, fd_dst, PARTMAGIC,
		                       partmagic.buf, partmagic.used);
		varbufreset(&partmagic);

		/* Write the data part. */
		varbufprintf(&partname, "data.%d", curpart);
		dpkg_ar_member_put_mem(file_dst.buf, fd_dst, partname.buf,
		                       partdata, (size_t)partrealsize);
		varbufreset(&partname);

		close(fd_dst);

		printf("%d ", curpart);

		curpart++;
	}

	varbuf_destroy(&file_dst);
	varbuf_destroy(&partname);
	varbuf_destroy(&partmagic);
	free(partdata);

	free(prefixdir);
	free(msdos_prefix);

	close(fd_src);

	printf("done\n");

	return 0;
}
コード例 #3
0
ファイル: pqinsert.c プロジェクト: khallock/LDM
int main(
        int ac,
        char *av[]
)
{
        const char* const       pqfname = getQueuePath();
        const char* const progname = ubasename(av[0]);
        int useProductID = FALSE;
        int signatureFromId = FALSE;
        char *productID = NULL;
        int multipleFiles = FALSE;
        char identifier[KEYSIZE];
        int status;
        int seq_start = 0;
        enum ExitCode {
            exit_success = 0,   /* all files inserted successfully */
            exit_system = 1,    /* operating-system failure */
            exit_pq_open = 2,   /* couldn't open product-queue */
            exit_infile = 3,    /* couldn't process input file */
            exit_dup = 4,       /* input-file already in product-queue */
            exit_md5 = 6        /* couldn't initialize MD5 processing */
        } exitCode = exit_success;

#if !USE_MMAP
        pqeIndex = PQE_NONE;
#endif

        {
            extern int optind;
            extern int opterr;
            extern char *optarg;
            int ch;

            (void) openulog(progname, LOG_NOTIME, LOG_LDM, "-");
            (void) setulogmask(LOG_UPTO(LOG_NOTICE));

            opterr = 0; /* Suppress getopt(3) error messages */

            while ((ch = getopt(ac, av, ":ivxl:q:f:s:p:")) != EOF)
                    switch (ch) {
                    case 'i':
                            signatureFromId = 1;
                            break;
                    case 'v':
                            (void) setulogmask(getulogmask() | LOG_MASK(LOG_INFO));
                            break;
                    case 'x':
                            (void) setulogmask(getulogmask() | LOG_MASK(LOG_DEBUG));
                            break;
                    case 'l':
                            openulog(progname, ulog_get_options(), LOG_LDM, optarg);
                            break;
                    case 'q':
                            setQueuePath(optarg);
                            break;
                    case 's':
                            seq_start = atoi(optarg);
                            break;
                    case 'f':
                            feedtype = atofeedtypet(optarg);
                            if(feedtype == NONE)
                            {
                                fprintf(stderr, "Unknown feedtype \"%s\"\n", optarg);
                                    usage(progname);
                            }
                            break;
                    case 'p':
                            useProductID = TRUE;
                            productID = optarg;
                            break;
                    case ':': {
                        LOG_ADD1("Option \"-%c\" requires an operand", optopt);
                        usage(progname);
                    }
                    /* no break */
                    default:
                        LOG_ADD1("Unknown option: \"%c\"", optopt);
                        usage(progname);
                        /* no break */
                    }

            ac -= optind; av += optind ;

            if(ac < 1) usage(progname);
            }

        /*
         * register exit handler
         */
        if(atexit(cleanup) != 0)
        {
                serror("atexit");
                exit(exit_system);
        }

        /*
         * set up signal handlers
         */
        set_sigactions();

        /*
         * who am i, anyway
         */
        (void) strncpy(myname, ghostname(), sizeof(myname));
        myname[sizeof(myname)-1] = 0;

        /*
         * open the product queue
         */
        if(status = pq_open(pqfname, PQ_DEFAULT, &pq))
        {
                if (PQ_CORRUPT == status) {
                    uerror("The product-queue \"%s\" is inconsistent\n",
                            pqfname);
                }
                else {
                    uerror("pq_open: \"%s\" failed: %s",
                            pqfname, status > 0 ? strerror(status) :
                                            "Internal error");
                }
                exit(exit_pq_open);
        }


        {
        char *filename;
        int fd;
        struct stat statb;
        product prod;
        MD5_CTX *md5ctxp = NULL;

        /*
         * Allocate an MD5 context
         */
        md5ctxp = new_MD5_CTX();
        if(md5ctxp == NULL)
        {
                serror("new_md5_CTX failed");
                exit(exit_md5);
        }


        /* These members are constant over the loop. */
        prod.info.origin = myname;
        prod.info.feedtype = feedtype;

        if (ac > 1) {
          multipleFiles = TRUE;
        }

        for(prod.info.seqno = seq_start ; ac > 0 ;
                         av++, ac--, prod.info.seqno++)
        {
                filename = *av;

                fd = open(filename, O_RDONLY, 0);
                if(fd == -1)
                {
                        serror("open: %s", filename);
                        exitCode = exit_infile;
                        continue;
                }

                if( fstat(fd, &statb) == -1) 
                {
                        serror("fstat: %s", filename);
                        (void) close(fd);
                        exitCode = exit_infile;
                        continue;
                }

                /* Determine what to use for product identifier */
                if (useProductID) 
                  {
                    if (multipleFiles) 
                      {
                        sprintf(identifier,"%s.%d", productID, prod.info.seqno);
                        prod.info.ident = identifier;
                      }
                    else
                      prod.info.ident = productID;
                   }
                else
                    prod.info.ident = filename;
                
                prod.info.sz = statb.st_size;
                prod.data = NULL;

                /* These members, and seqno, vary over the loop. */
                status = set_timestamp(&prod.info.arrival);
                if(status != ENOERR) {
                        serror("set_timestamp: %s, filename");
                        exitCode = exit_infile;
                        continue;
                }

#if USE_MMAP
                prod.data = mmap(0, prod.info.sz,
                        PROT_READ, MAP_PRIVATE, fd, 0);
                if(prod.data == NULL)
                {
                        serror("mmap: %s", filename);
                        (void) close(fd);
                        exitCode = exit_infile;
                        continue;
                }

                status = 
                    signatureFromId
                        ? mm_md5(md5ctxp, prod.info.ident,
                            strlen(prod.info.ident), prod.info.signature)
                        : mm_md5(md5ctxp, prod.data, prod.info.sz,
                            prod.info.signature);

                (void)exitIfDone(1);

                if (status != 0) {
                    serror("mm_md5: %s", filename);
                    (void) munmap(prod.data, prod.info.sz);
                    (void) close(fd);
                    exitCode = exit_infile;
                    continue;
                }

                /* These members, and seqno, vary over the loop. */
                status = set_timestamp(&prod.info.arrival);
                if(status != ENOERR) {
                        serror("set_timestamp: %s, filename");
                        exitCode = exit_infile;
                        continue;
                }

                /*
                 * Do the deed
                 */
                status = pq_insert(pq, &prod);

                switch (status) {
                case ENOERR:
                    /* no error */
                    if(ulogIsVerbose())
                        uinfo("%s", s_prod_info(NULL, 0, &prod.info,
                            ulogIsDebug())) ;
                    break;
                case PQUEUE_DUP:
                    uerror("Product already in queue: %s",
                        s_prod_info(NULL, 0, &prod.info, 1));
                    exitCode = exit_dup;
                    break;
                case PQUEUE_BIG:
                    uerror("Product too big for queue: %s",
                        s_prod_info(NULL, 0, &prod.info, 1));
                    exitCode = exit_infile;
                    break;
                case ENOMEM:
                    uerror("queue full?");
                    exitCode = exit_system;
                    break;  
                case EINTR:
#if defined(EDEADLOCK) && EDEADLOCK != EDEADLK
                case EDEADLOCK:
                    /*FALLTHROUGH*/
#endif
                case EDEADLK:
                    /* TODO: retry ? */
                    /*FALLTHROUGH*/
                default:
                    uerror("pq_insert: %s", status > 0
                        ? strerror(status) : "Internal error");
                    break;
                }

                (void) munmap(prod.data, prod.info.sz);
#else // USE_MMAP above; !USE_MMAP below
                status = 
                    signatureFromId
                        ? mm_md5(md5ctxp, prod.info.ident,
                            strlen(prod.info.ident), prod.info.signature)
                        : fd_md5(md5ctxp, fd, statb.st_size,
                            prod.info.signature);

                (void)exitIfDone(1);

                if (status != 0) {
                        serror("xx_md5: %s", filename);
                        (void) close(fd);
                        exitCode = exit_infile;
                        continue;
                }

                if(lseek(fd, 0, SEEK_SET) == (off_t)-1)
                {
                        serror("rewind: %s", filename);
                        (void) close(fd);
                        exitCode = exit_infile;
                        continue;
                }

                pqeIndex = PQE_NONE;
                status = pqe_new(pq, &prod.info, &prod.data, &pqeIndex);

                if(status != ENOERR) {
                    serror("pqe_new: %s", filename);
                    exitCode = exit_infile;
                }
                else {
                    ssize_t     nread = read(fd, prod.data, prod.info.sz);

                    (void)exitIfDone(1);

                    if (nread != prod.info.sz) {
                        serror("read %s %u", filename, prod.info.sz);
                        status = EIO;
                    }
                    else {
                        status = pqe_insert(pq, pqeIndex);
                        pqeIndex = PQE_NONE;

                        switch (status) {
                        case ENOERR:
                            /* no error */
                            if(ulogIsVerbose())
                                uinfo("%s", s_prod_info(NULL, 0, &prod.info,
                                    ulogIsDebug())) ;
                            break;
                        case PQUEUE_DUP:
                            uerror("Product already in queue: %s",
                                s_prod_info(NULL, 0, &prod.info, 1));
                            exitCode = exit_dup;
                            break;
                        case ENOMEM:
                            uerror("queue full?");
                            break;  
                        case EINTR:
#if defined(EDEADLOCK) && EDEADLOCK != EDEADLK
                        case EDEADLOCK:
                            /*FALLTHROUGH*/
#endif
                        case EDEADLK:
                            /* TODO: retry ? */
                            /*FALLTHROUGH*/
                        default:
                            uerror("pq_insert: %s", status > 0
                                ? strerror(status) : "Internal error");
                        }
                    }                   /* data read into `pqeIndex` region */

                    if (status != ENOERR) {
                        (void)pqe_discard(pq, pqeIndex);
                        pqeIndex = PQE_NONE;
                    }
                }                       /* `pqeIndex` region allocated */

#endif
                (void) close(fd);
        }                               /* input-file loop */

        free_MD5_CTX(md5ctxp);  
        }                               /* code block */

        exit(exitCode);
}
コード例 #4
0
/*
 * Sends a list of files to the LDM as data-products.
 *
 * Arguments:
 *      ldmProxy        The LDM proxy data-structure.
 *      offer           The description of the class of data-products that this
 *                      process is willing to send.
 *      origin          The identifier of the host that created the
 *                      data-products (typically the host running this program).
 *      seq_start       The starting value of the data-product sequence number.
 *      nfiles          The number of files to send.
 *      filenames       The pathnames of the files to send.
 *
 * Returns:
 *      0                       Success.
 *      SYSTEM_ERROR            O/S failure. "log_add()" called.
 *      CONNECTION_ABORTED      The connection was aborted. "log_add()"        *                              called.
 */
static int
ldmsend(
    LdmProxy*           ldmProxy,
    prod_class_t*       offer,
    char*               origin,
    int                 seq_start,
    int                 nfiles,
    char*               filenames[])
{
    int                 status = 0;
    char*               filename;
    int                 fd;
    struct stat         statb;
    prod_info           info;
    MD5_CTX*            md5ctxp = NULL;
    prod_class_t*       want;

    /*
     * Allocate an MD5 context
     */
    md5ctxp = new_MD5_CTX();
    if (md5ctxp == NULL)
    {
        log_syserr_q("new_md5_CTX failed");
        return SYSTEM_ERROR;
    }

    status = lp_hiya(ldmProxy, offer, &want);

    if (status != 0) {
        status = CONNECTION_ABORTED;
    }
    else {
        /* These members are constant over the loop. */
        info.origin = origin;
        info.feedtype = offer->psa.psa_val->feedtype;

        for (info.seqno = seq_start; exitIfDone(1) && nfiles > 0;
                filenames++, nfiles--, info.seqno++) {
            filename = *filenames;
            info.ident = filename;
            /*
             * ?? This could be the creation time of the file.
             */
            (void) set_timestamp(&info.arrival);

            /*
             * Checks 'arrival', 'feedtype', and 'ident'
             * against what the other guy has said he wants.
             */
            if (!prodInClass(offer, &info)) {
                log_info_q("Not going to send %s", filename);
                continue;       
            }
            if (!prodInClass(want, &info)) {
                log_info_q("%s doesn't want %s", lp_host(ldmProxy), filename);
                continue;       
            }

            fd = open(filename, O_RDONLY, 0);
            if (fd == -1) {
                log_syserr_q("open: %s", filename);
                continue;
            }

            if (fstat(fd, &statb) == -1) {
                log_syserr_q("fstat: %s", filename);
                (void) close(fd);
                continue;
            }

            log_info_q("Sending %s, %d bytes", filename, statb.st_size);
            
            /* These members, and seqno, vary over the loop. */
            if (fd_md5(md5ctxp, fd, statb.st_size, info.signature) != 0) {
                (void) close(fd);
                continue;
            }
            if (lseek(fd, 0, SEEK_SET) == (off_t)-1) {
                log_syserr_q("rewind: %s", filename);
                (void) close(fd);
                continue;
            }

            info.sz = (u_int)statb.st_size;

            (void)exitIfDone(1);

            status = send_product(ldmProxy, fd, &info);

            (void) close(fd);

            if (0 != status) {
                log_add("Couldn't send file \"%s\" to LDM", filename);
                break;
            }
        }                                       /* file loop */

        if (lp_flush(ldmProxy))
            log_add("Couldn't flush connection");

        free_prod_class(want);
    }                                           /* HIYA succeeded */

    free_MD5_CTX(md5ctxp);  
    return status;
}
コード例 #5
0
ファイル: pqinsert.c プロジェクト: KeithLatteri/awips2
int main(
        int ac,
        char *av[]
)
{
        char *progname = av[0];
        char *logfname;
        int useProductID = FALSE;
        int signatureFromId = FALSE;
        char *productID = NULL;
        int multipleFiles = FALSE;
        char identifier[KEYSIZE];
        int status;
        int seq_start = 0;
        enum ExitCode {
            exit_success = 0,
            exit_system = 1,    /* operating-system failure */
            exit_pq_open = 2,   /* couldn't open product-queue */
            exit_infile = 3,    /* couldn't process input file */
            exit_md5 = 6        /* couldn't initialize MD5 processing */
        } exitCode = exit_success;

        logfname = "-";

        /*
         * Check the environment for some options.
         * May be overridden by command line switches below.
         */
        {
                const char *ldmpqfname = getenv("LDMPQFNAME");
                if(ldmpqfname != NULL)
                        pqfname = ldmpqfname;
        }

        {
        extern int optind;
        extern int opterr;
        extern char *optarg;
        int ch;
        int logmask = (LOG_MASK(LOG_ERR) | LOG_MASK(LOG_WARNING) |
            LOG_MASK(LOG_NOTICE));

        opterr = 1;

        while ((ch = getopt(ac, av, "ivxl:q:f:s:p:")) != EOF)
                switch (ch) {
                case 'i':
                        signatureFromId = 1;
                        break;
                case 'v':
                        logmask |= LOG_MASK(LOG_INFO);
                        break;
                case 'x':
                        logmask |= LOG_MASK(LOG_DEBUG);
                        break;
                case 'l':
                        logfname = optarg;
                        break;
                case 'q':
                        pqfname = optarg;
                        break;
                case 's':
                        seq_start = atoi(optarg);
                        break;
                case 'f':
                        feedtype = atofeedtypet(optarg);
                        if(feedtype == NONE)
                        {
                            fprintf(stderr, "Unknown feedtype \"%s\"\n", optarg);
                                usage(progname);        
                        }
                        break;
                case 'p':
                        useProductID = TRUE;
                        productID = optarg;
                        break;
                case '?':
                        usage(progname);
                        break;
                }

        ac -= optind; av += optind ;

        if(ac < 1) usage(progname);
        (void) setulogmask(logmask);
        }

        /*
         * Set up error logging
         */
        (void) openulog(ubasename(progname), LOG_NOTIME, LOG_LDM, logfname);

        /*
         * register exit handler
         */
        if(atexit(cleanup) != 0)
        {
                serror("atexit");
                exit(exit_system);
        }

        /*
         * set up signal handlers
         */
        set_sigactions();

        /*
         * who am i, anyway
         */
        (void) strcpy(myname, ghostname());

        /*
         * open the product queue
         */
        if(status = pq_open(pqfname, PQ_DEFAULT, &pq))
        {
                if (PQ_CORRUPT == status) {
                    uerror("The product-queue \"%s\" is inconsistent\n",
                            pqfname);
                }
                else {
                    uerror("pq_open: \"%s\" failed: %s",
                            pqfname, status > 0 ? strerror(status) :
                                            "Internal error");
                }
                exit(exit_pq_open);
        }


        {
        char *filename;
        int fd;
        struct stat statb;
        product prod;
        MD5_CTX *md5ctxp = NULL;

        /*
         * Allocate an MD5 context
         */
        md5ctxp = new_MD5_CTX();
        if(md5ctxp == NULL)
        {
                serror("new_md5_CTX failed");
                exit(exit_md5);
        }


        /* These members are constant over the loop. */
        prod.info.origin = myname;
        prod.info.feedtype = feedtype;

        if (ac > 1) {
          multipleFiles = TRUE;
        }

        for(prod.info.seqno = seq_start ; ac > 0 ;
                         av++, ac--, prod.info.seqno++)
        {
                filename = *av;

                fd = open(filename, O_RDONLY, 0);
                if(fd == -1)
                {
                        serror("open: %s", filename);
                        exitCode = exit_infile;
                        continue;
                }

                if( fstat(fd, &statb) == -1) 
                {
                        serror("fstat: %s", filename);
                        (void) close(fd);
                        exitCode = exit_infile;
                        continue;
                }

                /* Determine what to use for product identifier */
                if (useProductID) 
                  {
                    if (multipleFiles) 
                      {
                        sprintf(identifier,"%s.%d", productID, prod.info.seqno);
                        prod.info.ident = identifier;
                      }
                    else
                      prod.info.ident = productID;
                   }
                else
                    prod.info.ident = filename;
                
                prod.info.sz = statb.st_size;
                prod.data = NULL;

#ifndef NO_MMAP
                prod.data = mmap(0, prod.info.sz,
                        PROT_READ, MAP_PRIVATE, fd, 0);
                if(prod.data == NULL)
                {
                        serror("mmap: %s", filename);
                        (void) close(fd);
                        exitCode = exit_infile;
                        continue;
                }

                status = 
                    signatureFromId
                        ? mm_md5(md5ctxp, prod.info.ident,
                            strlen(prod.info.ident), prod.info.signature)
                        : mm_md5(md5ctxp, prod.data, prod.info.sz,
                            prod.info.signature);

                (void)exitIfDone(1);

                if (status != 0) {
                    serror("mm_md5: %s", filename);
                    (void) munmap(prod.data, prod.info.sz);
                    (void) close(fd);
                    exitCode = exit_infile;
                    continue;
                }

                /* These members, and seqno, vary over the loop. */
                status = set_timestamp(&prod.info.arrival);
                if(status != ENOERR) {
                        serror("set_timestamp: %s, filename");
                        exitCode = exit_infile;
                        continue;
                }

                /*
                 * Do the deed
                 */
                status = pq_insert(pq, &prod);

                switch (status) {
                case ENOERR:
                    /* no error */
                    if(ulogIsVerbose())
                        uinfo("%s", s_prod_info(NULL, 0, &prod.info,
                            ulogIsDebug())) ;
                    break;
                case PQUEUE_DUP:
                    uerror("Product already in queue: %s",
                        s_prod_info(NULL, 0, &prod.info, 1));
                    break;
                case ENOMEM:
                    uerror("queue full?");
                    break;  
                case EINTR:
#if defined(EDEADLOCK) && EDEADLOCK != EDEADLK
                case EDEADLOCK:
                    /*FALLTHROUGH*/
#endif
                case EDEADLK:
                    /* TODO: retry ? */
                    /*FALLTHROUGH*/
                default:
                    uerror("pq_insert: %s", status > 0
                        ? strerror(status) : "Internal error");
                    break;
                }

                (void) munmap(prod.data, prod.info.sz);
#else /*!NO_MMAP*/
                status = 
                    signatureFromId
                        ? mm_md5(md5ctxp, prod.info.ident,
                            strlen(prod.info.ident), prod.info.signature)
                        : fd_md5(md5ctxp, fd, statb.st_size,
                            prod.info.signature);

                (void)exitIfDone(1);

                if (status != 0) {
                        serror("fd_md5: %s", filename);
                        (void) close(fd);
                        exitCode = exit_infile;
                        continue;
                }

                if(lseek(fd, 0, SEEK_SET) == (off_t)-1)
                {
                        serror("rewind: %s", filename);
                        (void) close(fd);
                        exitCode = exit_infile;
                        continue;
                }

                index = PQE_NONE;
                status = pqe_new(pq, &prod.info, &prod.data, &index);

                if(status != ENOERR) {
                    serror("pqe_new: %s", filename);
                    exitCode = exit_infile;
                }
                else {
                    ssize_t     nread = read(fd, prod.data, prod.info.sz);

                    (void)exitIfDone(1);

                    if (nread != prod.info.sz) {
                        serror("read %s %u", filename, prod.info.sz);
                        status = EIO;
                    }
                    else {
                        status = pqe_insert(pq, index);
                        index = PQE_NONE;

                        switch (status) {
                        case ENOERR:
                            /* no error */
                            if(ulogIsVerbose())
                                uinfo("%s", s_prod_info(NULL, 0, &prod.info,
                                    ulogIsDebug())) ;
                            break;
                        case PQUEUE_DUP:
                            uerror("Product already in queue: %s",
                                s_prod_info(NULL, 0, &prod.info, 1));
                            break;
                        case ENOMEM:
                            uerror("queue full?");
                            break;  
                        case EINTR:
#if defined(EDEADLOCK) && EDEADLOCK != EDEADLK
                        case EDEADLOCK:
                            /*FALLTHROUGH*/
#endif
                        case EDEADLK:
                            /* TODO: retry ? */
                            /*FALLTHROUGH*/
                        default:
                            uerror("pq_insert: %s", status > 0
                                ? strerror(status) : "Internal error");
                        }
                    }                   /* data read into "index" region */

                    if (status != ENOERR) {
                        (void)pqe_discard(pq, index);
                        index = PQE_NONE;
                    }
                }                       /* "index" region allocated */

#endif /*!NO_MMAP*/
                (void) close(fd);
        }                               /* input-file loop */

        free_MD5_CTX(md5ctxp);  
        }                               /* code block */

        exit(exitCode);
}
コード例 #6
0
ファイル: ldmsend.c プロジェクト: KeithLatteri/awips2
static int
ldmsend(CLIENT *clnt,
        prod_class_t* clssp,
        char*       origin,
        int         seq_start,
        int         nfiles,
        char*       filenames[])
{
        int status = 0;
        char *filename;
        int fd;
        struct stat statb;
        prod_info info;
        MD5_CTX *md5ctxp = NULL;

        /*
         * Allocate an MD5 context
         */
        md5ctxp = new_MD5_CTX();
        if(md5ctxp == NULL)
        {
                status = errno;
                serror("new_md5_CTX failed");
                return status;
        }

        status = (*hiya)(clnt, &clssp);

        if(status != 0)
                return status;

        /* These members are constant over the loop. */
        info.origin = origin;
        info.feedtype = clssp->psa.psa_val->feedtype;

        for( info.seqno = seq_start; exitIfDone(1) && nfiles > 0;
                 filenames++, nfiles--, info.seqno++)
        {
                filename = *filenames;
                info.ident = filename;
                /*
                 * ?? This could be the creation time of the file.
                 */
                (void) set_timestamp(&info.arrival);

                /*
                 * Checks 'arrival', 'feedtype', and 'ident'
                 * against what the other guy has said he wants.
                 */
                if(!prodInClass(clssp, &info))
                {
                        uinfo("%s doesn't want %s", remote, filename);
                        continue;       
                }

                fd = open(filename, O_RDONLY, 0);
                if(fd == -1)
                {
                        serror("open: %s", filename);
                        continue;
                }

                if( fstat(fd, &statb) == -1) 
                {
                        serror("fstat: %s", filename);
                        (void) close(fd);
                        continue;
                }

                uinfo("Sending %s, %d bytes", filename, statb.st_size);
                
                /* These members, and seqno, vary over the loop. */
                if(fd_md5(md5ctxp, fd, statb.st_size, info.signature) != 0)
                {
                        (void) close(fd);
                        continue;
                }
                if(lseek(fd, 0, SEEK_SET) == (off_t)-1)
                {
                        serror("rewind: %s", filename);
                        (void) close(fd);
                        continue;
                }

                (void)exitIfDone(1);

                info.sz = (u_int)statb.st_size;

                (*send_product)(clnt, fd, &info);

                (void) close(fd);
        }

        if (exitIfDone(1) && NULL != nullproc &&
                NULL == (*nullproc)(NULL, clnt)) {
            uerror("%s: NULLPROC failure: %s", remote, clnt_errmsg(clnt));

            status = 1;
        }

        free_MD5_CTX(md5ctxp);  
        return status;
}
コード例 #7
0
ファイル: split.c プロジェクト: cornytrace/DPKG-for-Android
static int
mksplit(const char *file_src, const char *prefix, off_t maxpartsize,
        bool msdos)
{
	int fd_src;
	struct stat st;
	char hash[MD5HASHLEN + 1];
	char *package, *version, *arch;
	int nparts, curpart;
	off_t partsize;
	off_t cur_partsize, last_partsize;
	char *prefixdir = NULL, *msdos_prefix = NULL;
	struct varbuf file_dst = VARBUF_INIT;
	struct varbuf partmagic = VARBUF_INIT;
	struct varbuf partname = VARBUF_INIT;

	fd_src = open(file_src, O_RDONLY);
	if (fd_src < 0)
		ohshite(_("unable to open source file `%.250s'"), file_src);
	if (fstat(fd_src, &st))
		ohshite(_("unable to fstat source file"));
	if (!S_ISREG(st.st_mode))
		ohshit(_("source file `%.250s' not a plain file"), file_src);

	fd_md5(fd_src, hash, -1, "md5hash");
	lseek(fd_src, 0, SEEK_SET);

	/* FIXME: Use libdpkg-deb. */
	package = deb_field(file_src, "Package");
	version = deb_field(file_src, "Version");
	arch = deb_field(file_src, "Architecture");

	partsize = maxpartsize - HEADERALLOWANCE;
	last_partsize = st.st_size % partsize;
	if (last_partsize == 0)
		last_partsize = partsize;
	nparts = (st.st_size + partsize - 1) / partsize;

	setvbuf(stdout, NULL, _IONBF, 0);

	printf(P_("Splitting package %s into %d part: ",
	          "Splitting package %s into %d parts: ", nparts),
	       package, nparts);

	if (msdos) {
		char *t;

		t = m_strdup(prefix);
		prefixdir = m_strdup(dirname(t));
		free(t);

		msdos_prefix = m_strdup(path_basename(prefix));
		prefix = clean_msdos_filename(msdos_prefix);
	}

	for (curpart = 1; curpart <= nparts; curpart++) {
		int fd_dst;

		varbuf_reset(&file_dst);
		/* Generate output filename. */
		if (msdos) {
			char *refname;
			int prefix_max;

			m_asprintf(&refname, "%dof%d", curpart, nparts);
			prefix_max = max(8 - strlen(refname), 0);
			varbuf_printf(&file_dst, "%s/%.*s%.8s.deb",
			              prefixdir, prefix_max, prefix, refname);
			free(refname);
		} else {
			varbuf_printf(&file_dst, "%s.%dof%d.deb",
			              prefix, curpart, nparts);
		}

		if (curpart == nparts)
			cur_partsize = last_partsize;
		else
			cur_partsize = partsize;

		if (cur_partsize > maxpartsize) {
			ohshit(_("Header is too long, making part too long. "
			       "Your package name or version\n"
			       "numbers must be extraordinarily long, "
			       "or something. Giving up.\n"));
		}

		/* Split the data. */
		fd_dst = creat(file_dst.buf, 0644);
		if (fd_dst < 0)
			ohshite(_("unable to open file '%s'"), file_dst.buf);

		/* Write the ar header. */
		dpkg_ar_put_magic(file_dst.buf, fd_dst);

		/* Write the debian-split part. */
		varbuf_printf(&partmagic,
		              "%s\n%s\n%s\n%s\n%jd\n%jd\n%d/%d\n%s\n",
		              SPLITVERSION, package, version, hash,
		              (intmax_t)st.st_size, (intmax_t)partsize,
		              curpart, nparts, arch);
		dpkg_ar_member_put_mem(file_dst.buf, fd_dst, PARTMAGIC,
		                       partmagic.buf, partmagic.used);
		varbuf_reset(&partmagic);

		/* Write the data part. */
		varbuf_printf(&partname, "data.%d", curpart);
		dpkg_ar_member_put_file(file_dst.buf, fd_dst, partname.buf,
		                        fd_src, cur_partsize);
		varbuf_reset(&partname);

		close(fd_dst);

		printf("%d ", curpart);
	}

	varbuf_destroy(&file_dst);
	varbuf_destroy(&partname);
	varbuf_destroy(&partmagic);

	free(prefixdir);
	free(msdos_prefix);

	close(fd_src);

	printf(_("done\n"));

	return 0;
}