int fsdump(int argc, char *argv[]) { int i, j, io; int status; int block, bytes; int scsi_id, blk, nblks, size, mark; struct stat boot_stat; struct partition *pp; scsi_id = scsi_device; printf("Current SCSI device = ID %d\n", scsi_id); getline("Is it sure ? (y/n) ", cons_buf); if ((cons_buf[0] != 'y') && (cons_buf[0] != 'Y')) return ST_ERROR; scsi_read_raw(scsi_id, 0, 1, index, LABEL_SIZE); for (i = 0; i < MAXPARTITIONS; i++) { pp = &(lp->d_partitions[i]); if ((i != 0) && (i != 3) && (i != 4) && (i != 5)) { pp->p_size = 0; } if (i == 5 && argc > 1 && !strcmp(argv[1], "tailor")) pp->p_size = 0; } st_rewind(rst0); printf("Boot Program "); io = open("sd(0,0)boot", 0); if (io >= 0) { printf("read ... "); size = read(io, dump_buf, 1048576); close(io); printf("%d bytes ... ", size); if (size <= 0) { printf("failed\n"); return ST_ERROR; } boot_stat.st_size = size; } printf("write ... "); status = stwrite(rst0, dump_buf, size); st_write_EOF(rst0); if (status < size) { printf("failed\n"); return ST_ERROR; } printf("done\n"); printf("disklabel (index)\t"); printf("write ... "); status = stwrite(rst0, index, LABEL_SIZE); st_write_EOF(rst0); if (status < LABEL_SIZE) { printf("failed\n"); return ST_ERROR; } printf("done\n\n"); for (i = 0; i < MAXPARTITIONS; i++) { pp = &(lp->d_partitions[i]); if (pp->p_size > 0) { printf("%c: ", i + 'A'); printf("size = %d(0x%s), ", pp->p_size, hexstr(pp->p_size, 8)); printf("offset = %d(0x%s)\n", pp->p_offset, hexstr(pp->p_offset, 8)); blk = pp->p_offset; nblks = pp->p_size; size = nblks << DEV_BSHIFT; block = BUF_BLOCK; bytes = BUF_BYTES; mark = nblks / block; if (nblks % block) mark++; for (j = 0; j < mark; j++) printf("-"); for (j = 0; j < mark; j++) printf("%c", '\x08'); while (nblks > 0) { if (nblks < block) { block = nblks; bytes = nblks << DEV_BSHIFT; } if (!scsi_read_raw(scsi_id, blk, block, dump_buf, bytes)) { printf("disk read failed !!!\n"); return ST_ERROR; } if (stwrite(rst0, dump_buf, bytes) < bytes) { printf("tape write failed !!!\n"); return ST_ERROR; } blk += block; nblks -= block; size -= bytes; printf("#"); } st_write_EOF(rst0); printf("\n\n"); } } return ST_NORMAL; }
int fsrestore(int argc, char *argv[]) { int i, j, status; int block, bytes; int blk, nblks, size, mark; struct partition *pp; printf("Current SCSI device = ID %d\n", scsi_device); getline("Is it sure ? (y/n) ", cons_buf); if ((cons_buf[0] != 'y') && (cons_buf[0] != 'Y')) return ST_ERROR; st_rewind(rst0); st_skip(rst0); status = stread(rst0, index, LABEL_SIZE); st_skip(rst0); for (i = 0; i < MAXPARTITIONS; i++) { pp = &(lp->d_partitions[i]); if (pp->p_size > 0) { printf("%c: ", i + 'A'); printf("size = %d(0x%s), ", pp->p_size, hexstr(pp->p_size, 8)); printf("offset = %d(0x%s)\n", pp->p_offset, hexstr(pp->p_offset, 8)); blk = pp->p_offset; nblks = pp->p_size; size = nblks << DEV_BSHIFT; block = BUF_BLOCK; bytes = BUF_BYTES; mark = nblks / block; if (nblks % block) mark++; for (j = 0; j < mark; j++) printf("-"); for (j = 0; j < mark; j++) printf("%c", '\x08'); while (nblks > 0) { if (nblks < block) { block = nblks; bytes = nblks << DEV_BSHIFT; } if (stread(rst0, dump_buf, bytes) != bytes) { printf("tape read failed !!!\n"); return ST_ERROR; } if (!scsi_write(blk, dump_buf, bytes)) { printf("disk write failed !!!\n"); return ST_ERROR; } blk += block; nblks -= block; size -= bytes; printf("#"); } st_skip(rst0); printf("\n\n"); } } return ST_NORMAL; }
int st_ioctl(dev_t dev, u_long cmd, caddr_t data, int fflag, struct proc *p) { IOSCSITape *st = IOSCSITape::devices[minor(dev)]; struct mtop *mt = (struct mtop *) data; struct mtget *g = (struct mtget *) data; int number = mt->mt_count; int error = 0; switch (cmd) { case MTIOCGET: memset(g, 0, sizeof(struct mtget)); g->mt_type = 0x7; /* Ultrix compat *//*? */ g->mt_blksiz = st->blksize; g->mt_density = st->density; g->mt_fileno = st->fileno; g->mt_blkno = st->blkno; g->mt_dsreg = st->flags; /* report raw driver flags */ g->mt_erreg = st->sense_flags; /* TODO: Implement the full mtget struct */ break; case MTIOCTOP: switch (mt->mt_op) { case MTBSF: number = -number; case MTFSF: error = st_space(st, kSCSISpaceCode_Filemarks, number); break; case MTBSR: number = -number; case MTFSR: error = st_space(st, kSCSISpaceCode_LogicalBlocks, number); break; case MTREW: error = st_rewind(st); break; case MTWEOF: error = st_write_filemarks(st, number); break; case MTOFFL: error = st_unload(st); break; case MTNOP: break; case MTEOM: error = st_space(st, kSCSISpaceCode_EndOfData, number); break; case MTSETBSIZ: error = st_set_blocksize(st, number); break; default: error = EINVAL; } break; case MTIOCRDSPOS: error = st_rdpos(st, false, (unsigned int *)data); break; case MTIOCRDHPOS: error = st_rdpos(st, true, (unsigned int *)data); break; default: error = ENOTTY; } return error; }