예제 #1
0
void
do_TAO(int fd, int test_write, int preemp, int dvdrw)
{
	struct cdr_track track;
	int i;

	for (i = 0; i < notracks; i++) {
		track.test_write = test_write;
		track.datablock_type = tracks[i].block_type;
		track.preemp = preemp;
		if (ioctl(fd, CDRIOCINITTRACK, &track) < 0)
			err(EX_IOERR, "ioctl(CDRIOCINITTRACK)");

		if (dvdrw)
			tracks[i].addr = 0;
		else
			if (ioctl(fd, CDRIOCNEXTWRITEABLEADDR,
				  &tracks[i].addr) < 0)
				err(EX_IOERR, "ioctl(CDRIOCNEXTWRITEABLEADDR)");

		if (!quiet)
			fprintf(stderr, "next writeable LBA %d\n",
				tracks[i].addr);
		if (write_file(fd, &tracks[i])) {
			cleanup_flush();
			err(EX_IOERR, "write_file");
		}
		if (ioctl(fd, CDRIOCFLUSH) < 0)
			err(EX_IOERR, "ioctl(CDRIOCFLUSH)");
	}
}
예제 #2
0
static void cleanup_service(VSTREAM *src, char *unused_service, char **argv)
{
    VSTRING *buf = vstring_alloc(100);
    CLEANUP_STATE *state;
    int     flags;
    int     type = 0;
    int     status;

    /*
     * Sanity check. This service takes no command-line arguments.
     */
    if (argv[0])
	msg_fatal("unexpected command-line argument: %s", argv[0]);

    /*
     * Open a queue file and initialize state.
     */
    state = cleanup_open(src);

    /*
     * Send the queue id to the client. Read client processing options. If we
     * can't read the client processing options we can pretty much forget
     * about the whole operation.
     */
    attr_print(src, ATTR_FLAG_NONE,
	       ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, state->queue_id,
	       ATTR_TYPE_END);
    if (attr_scan(src, ATTR_FLAG_STRICT,
		  ATTR_TYPE_INT, MAIL_ATTR_FLAGS, &flags,
		  ATTR_TYPE_END) != 1) {
	state->errs |= CLEANUP_STAT_BAD;
	flags = 0;
    }
    cleanup_control(state, flags);

    /*
     * XXX Rely on the front-end programs to enforce record size limits.
     * 
     * First, copy the envelope records to the queue file. Then, copy the
     * message content (headers and body). Finally, attach any information
     * extracted from message headers.
     */
    while (CLEANUP_OUT_OK(state)) {
	if ((type = rec_get_raw(src, buf, 0, REC_FLAG_NONE)) < 0) {
	    state->errs |= CLEANUP_STAT_BAD;
	    break;
	}
	if (REC_GET_HIDDEN_TYPE(type)) {
	    msg_warn("%s: record type %d not allowed - discarding this message",
		     state->queue_id, type);
	    state->errs |= CLEANUP_STAT_BAD;
	    break;
	}
	CLEANUP_RECORD(state, type, vstring_str(buf), VSTRING_LEN(buf));
	if (type == REC_TYPE_END)
	    break;
    }

    /*
     * Keep reading in case of problems, until the sender is ready to receive
     * our status report.
     */
    if (CLEANUP_OUT_OK(state) == 0 && type > 0) {
	while (type != REC_TYPE_END
	       && (type = rec_get(src, buf, 0)) > 0)
	     /* void */ ;
    }

    /*
     * Log something to make timeout errors easier to debug.
     */
    if (vstream_ftimeout(src))
	msg_warn("%s: read timeout on %s",
		 state->queue_id, VSTREAM_PATH(src));

    /*
     * Finish this message, and report the result status to the client.
     */
    status = cleanup_flush(state);		/* in case state is modified */
    attr_print(src, ATTR_FLAG_NONE,
	       ATTR_TYPE_INT, MAIL_ATTR_STATUS, status,
	       ATTR_TYPE_STR, MAIL_ATTR_WHY,
	       (state->flags & CLEANUP_FLAG_SMTP_REPLY)
	       && state->smtp_reply ? state->smtp_reply :
	       state->reason ? state->reason : "",
	       ATTR_TYPE_END);
    cleanup_free(state);

    /*
     * Cleanup.
     */
    vstring_free(buf);
}
예제 #3
0
void
do_DAO(int fd, int test_write, int multi)
{
	struct cdr_cuesheet sheet;
	struct cdr_cue_entry cue[100];
	int format = CDR_SESS_CDROM;
	int addr, i, j = 0;

	int bt2ctl[16] = { 0x0,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
			   0x4, 0x4, 0x4, 0x4, 0x4, 0x4,  -1,  -1 };

	int bt2df[16] = { 0x0,    -1,   -1,   -1,   -1,   -1,   -1,   -1,
			  0x10, 0x30, 0x20,   -1, 0x21,   -1,   -1,   -1 };

	if (ioctl(fd, CDRIOCNEXTWRITEABLEADDR, &addr) < 0)
		err(EX_IOERR, "ioctl(CDRIOCNEXTWRITEABLEADDR)");
	if (verbose)
		fprintf(stderr, "next writeable LBA %d\n", addr);

	cue_ent(&cue[j++], bt2ctl[tracks[0].block_type], 0x01, 0x00, 0x0,
		(bt2df[tracks[0].block_type] & 0xf0) |
		(tracks[0].block_type < 8 ? 0x01 : 0x04), 0x00, addr);

	for (i = 0; i < notracks; i++) {
		if (bt2ctl[tracks[i].block_type] < 0 ||
		    bt2df[tracks[i].block_type] < 0)
			errx(EX_IOERR, "track type not supported in DAO mode");

		if (tracks[i].block_type >= CDR_DB_XA_MODE1)
			format = CDR_SESS_CDROM_XA;

		if (i == 0) {
			addr += tracks[i].pregap;
			tracks[i].addr = addr;

			cue_ent(&cue[j++], bt2ctl[tracks[i].block_type],
				0x01, i+1, 0x1, bt2df[tracks[i].block_type],
				0x00, addr);

		}
		else {
			if (tracks[i].pregap) {
				if (tracks[i].block_type > 0x7) {
					cue_ent(&cue[j++],bt2ctl[tracks[i].block_type],
						0x01, i+1, 0x0,
						(bt2df[tracks[i].block_type] & 0xf0) |
						(tracks[i].block_type < 8 ? 0x01 :0x04),
						0x00, addr);
				}
				else
					cue_ent(&cue[j++],bt2ctl[tracks[i].block_type],
						0x01, i+1, 0x0,
						bt2df[tracks[i].block_type],
						0x00, addr);
			}
			tracks[i].addr = tracks[i - 1].addr +
				roundup_blocks(&tracks[i - 1]);

			cue_ent(&cue[j++], bt2ctl[tracks[i].block_type],
				0x01, i+1, 0x1, bt2df[tracks[i].block_type],
				0x00, addr + tracks[i].pregap);

			if (tracks[i].block_type > 0x7)
				addr += tracks[i].pregap;
		}
		addr += roundup_blocks(&tracks[i]);
	}

	cue_ent(&cue[j++], bt2ctl[tracks[i - 1].block_type], 0x01, 0xaa, 0x01,
		(bt2df[tracks[i - 1].block_type] & 0xf0) |
		(tracks[i - 1].block_type < 8 ? 0x01 : 0x04), 0x00, addr);

	sheet.len = j * 8;
	sheet.entries = cue;
	sheet.test_write = test_write;
	sheet.session_type = multi ? CDR_SESS_MULTI : CDR_SESS_NONE;
	sheet.session_format = format;
	if (verbose) {
		u_int8_t *ptr = (u_int8_t *)sheet.entries;

		fprintf(stderr,"CUE sheet:");
		for (i = 0; i < sheet.len; i++)
			if (i % 8)
				fprintf(stderr," %02x", ptr[i]);
			else
				fprintf(stderr,"\n%02x", ptr[i]);
		fprintf(stderr,"\n");
	}

	if (ioctl(fd, CDRIOCSENDCUE, &sheet) < 0)
		err(EX_IOERR, "ioctl(CDRIOCSENDCUE)");

	for (i = 0; i < notracks; i++) {
		if (write_file(fd, &tracks[i])) {
			cleanup_flush();
			err(EX_IOERR, "write_file");
		}
	}

	ioctl(fd, CDRIOCFLUSH);
}