/* $Id: wtape.c,v 1.15 2011/06/01 11:09:22 uehira Exp $ */ /* program "wtape.c" 8/23/89 - 8/8/90, 6/27/91, 12/24/91, 2/29/92 urabe 3/11/93 - 3/17/93, 7/5/93, 10/24/93, 5/19/94, 5/26/94, 6/1/94 97.6.25 SIZE_MAX->1000000 98.6.24 yo2000 98.6.30 FreeBSD 98.7.14 99.2.4 put signal(HUP) in switch_sig() 99.4.19 byte-order-free 2000.4.17 deleted definition of usleep() 2001.6.21 add options '-p', '-d' and '?' (uehira) 2004.1.20 avoid N*64*1024 byte block SIZE_MAX 1000000->2000000 2004.1.29 avoid odd byte block size 2005.8.10 bug in strcmp2()/strncmp2() fixed : 0-6 > 7-9 2010.2.16 64bit clean? (uehira) 2010.11.25 SIZE_MAX --> WTAPE_SIZE_MAX (conflict in Linux systems) (uehira) */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #include #include #if TIME_WITH_SYS_TIME #include #include #else /* !TIME_WITH_SYS_TIME */ #if HAVE_SYS_TIME_H #include #else /* !HAVE_SYS_TIME_H */ #include #endif /* !HAVE_SYS_TIME_H */ #endif /* !TIME_WITH_SYS_TIME */ #include "winlib.h" #define DEBUGFLAG 1 #define WTAPE_SIZE_MAX 2000000 #define NAMLEN 80 /* #define N_EXABYTE 8 */ /* moved to winlib.h */ #define DEFAULT_WAIT_MIN 0 #define DEFAULT_PARAM_FILE "wtape.prm" #define WIN_FILENAME_MAX 1024 static const char rcsid[] = "$Id: wtape.c,v 1.15 2011/06/01 11:09:22 uehira Exp $"; static uint8_w buf[WTAPE_SIZE_MAX]; static int init_flag,wfm,new_tape,switch_req,fd_exb,exb_status[N_EXABYTE], exb_busy,n_exb; static char name_buf[WIN_FILENAME_MAX],name_start[NAMLEN], exb_name[N_EXABYTE][20], file_done[WIN_FILENAME_MAX],raw_dir[WIN_FILENAME_MAX], raw_dir1[WIN_FILENAME_MAX], log_file[WIN_FILENAME_MAX],raw_oldest[20],raw_latest[20]; static size_t exb_total; /* in KB */ static int wait_min; static char param_name[WIN_FILENAME_MAX]; static char *progname; /* prototypes */ static void switch_sig(void); static int get_unit(int); static int mt_doit(int, int, int); static void init_param(void); static void read_rsv(int *); static void write_rsv(int *); static void adj_time_wtape(int *); static void ctrlc(void); static void close_exb(char *); static void rmemo(char *, char *); static void wmemo(char *, char *); static void wmemon(char *, long); static void end_process(int); static void read_units(char *); static void write_units(char *); static void switch_unit(int); static void usage(void); int main(int, char *[]); static void switch_sig(void) { switch_req=1; signal(SIGHUP,(void *)switch_sig); } static int get_unit(int unit) /* get exabyte unit */ { int j; read_units(WTAPE__UNITS); for(j=0;jN_EXABYTE-1) unit=0; while(exb_status[unit]==0) if(++unit==n_exb) unit=0; return(unit); } static int mt_doit(int fd, int ope, int count) { struct mtop exb_param; exb_param.mt_op=ope; exb_param.mt_count=count; return (ioctl(fd,MTIOCTOP,(char *)&exb_param)); } /* mt_status(fd,type,ds,er,resid,flno) */ /* int fd,*type,*ds,*er,*resid,*flno; */ /* { */ /* int re; */ /* struct mtget exb_stat; */ /* re=ioctl(fd,MTIOCGET,(char *)&exb_stat); */ /* /*printf("type=%d ds=%d er=%d resid=%d flno=%d\n", */ /* exb_stat.mt_type,exb_stat.mt_dsreg,exb_stat.mt_erreg, */ /* exb_stat.mt_resid,exb_stat.mt_fileno); */ /* */ /* *type=exb_stat.mt_type; /* drive id */ /* *ds=exb_stat.mt_dsreg; /* */ /* *er=exb_stat.mt_erreg; /* sense key error */ /* *resid=exb_stat.mt_resid; /* residual count (bytes not transferred) */ /* *flno=exb_stat.mt_fileno; /* file number */ /* return re; */ /* } */ static void init_param(void) { char tb[WIN_FILENAME_MAX],*ptr; FILE *fp; if((fp=fopen(param_name,"r"))==NULL) { fprintf(stderr,"parameter file '%s' not found\007\n",param_name); #if DEBUGFLAG printf("***** %s abort *****\n\n",progname); #endif usage(); exit(1); } read_param_line(fp,tb,sizeof(tb)); if((ptr=strchr(tb,':'))==NULL) { sscanf(tb,"%s",raw_dir); sscanf(tb,"%s",raw_dir1); } else { *ptr=0; sscanf(tb,"%s",raw_dir); sscanf(ptr+1,"%s",raw_dir1); } read_param_line(fp,tb,sizeof(tb)); sscanf(tb,"%s",log_file); for(n_exb=0;n_exb=0) exb_status[i]=1; } fclose(fp); } static void write_units(char *file) { FILE *fp; char tb[WIN_FILENAME_MAX]; int i; sprintf(tb,"%s/%s",raw_dir1,file); fp=fopen(tb,"w+"); for(i=0;i=n_exb) { exb_status[exb_busy]=0; write_units(WTAPE__UNITS); unit=exb_busy; if(++unit==n_exb) unit=0; } if((re=get_unit(unit))<0) { fprintf(stderr,"NO EXABYTE UNITS AVAILABLE !!\n"); for(i=0;i<10;i++) { fprintf(stderr,"\007"); usleep(100000); } end_process(1); } wmemon(WTAPE_EXABYTE,exb_busy=re); new_tape=1; wmemon(WTAPE_TOTAL,exb_total=0); #if DEBUGFLAG printf("new exb unit #%d (%s)\n",exb_busy,exb_name[exb_busy]); #endif if((fd_exb=open(exb_name[exb_busy],O_WRONLY))==-1) { if((fd_exb=open(exb_name[exb_busy],O_WRONLY))==-1) { sprintf(tb,"%s: %s",progname,exb_name[exb_busy]); perror(tb); switch_unit(-1); } } } static void usage(void) { WIN_version(); fprintf(stderr,"%s\n",rcsid); fprintf(stderr, "Usage: %s (options) ([unit])\n", progname); fprintf(stderr, "List of options:\n"); fprintf(stderr, " -p [param file] set parameter file (default:wtape.prm)\n"); fprintf(stderr, " -d [delay] set delay in minute (default:0)\n"); fprintf(stderr, " -? print this message\n"); exit(1); } int main(int argc, char *argv[]) { FILE *fp; char tb[100]; int i,io_error,unit,f_get,last_min=0,tm[5]; uint32_w j; size_t cnt; ssize_t re; int ch,max_num,tm1[5],k; char max_c[100]; if((progname=strrchr(argv[0],'/')) != NULL) progname++; else progname=argv[0]; #if DEBUGFLAG printf("***** %s start *****\n",progname); #endif wait_min=DEFAULT_WAIT_MIN; snprintf(param_name,sizeof(param_name),"%s",DEFAULT_PARAM_FILE); while((ch=getopt(argc,argv,"p:d:?"))!=-1) { switch (ch) { case 'p': /* parameter file */ strcpy(param_name,optarg); break; case 'd': /* delay minute */ wait_min=atoi(optarg); break; case '?': default: usage(); } } argc-=optind; argv+=optind; /* initialize parameters */ init_param(); signal(SIGTERM,(void *)ctrlc); /* set up ctrlc routine */ signal(SIGINT,(void *)ctrlc); /* set up ctrlc routine */ signal(SIGHUP,(void *)switch_sig); rmemo(WDISK_COUNT,max_c); max_num=atoi(max_c); if(wait_min<0 || wait_min>max_num-70) { fprintf(stderr,"Invalid delay minute (0<=[delay]<=%d).\n", max_num-70); end_process(1); } /* get exabyte unit */ if(argc>0) { sscanf(argv[0],"%d",&unit); if(unit<0 || unit>=n_exb) unit=0; } else unit=0; switch_unit(unit); /* read wtape.rsv */ read_rsv(tm); for(;;) { tm[4]++; adj_time_wtape(tm); sprintf(name_start,"%02d%02d%02d%02d.%02d", tm[0],tm[1],tm[2],tm[3],tm[4]); rmemo(WDISK_OLDEST,raw_oldest); rmemo(WDISK_LATEST,raw_latest); if(wait_min) { sscanf(raw_latest,"%02d%02d%02d%02d.%02d", &tm1[0],&tm1[1],&tm1[2],&tm1[3],&tm1[4]); for(k=0;k0) /* enter wait */ while(strncmp2(name_start,raw_latest,8)>=0) { /* wait approx. 1 h */ if(switch_req) { close_exb("BY REQ"); switch_unit(-1); } else sleep(60); rmemo(WDISK_LATEST,raw_latest); if(wait_min) { sscanf(raw_latest,"%02d%02d%02d%02d.%02d", &tm1[0],&tm1[1],&tm1[2],&tm1[3],&tm1[4]); for(k=0;kWTAPE_SIZE_MAX) break; re=read(f_get,buf+4,j-4); /* read rest (data) */ if(re==0) break; if((buf[8]&0xf0)!=(last_min&0xf0) && init_flag==0) { #if DEBUGFLAG printf("write fm\n"); #endif mt_doit(fd_exb,MTWEOF,1); wfm=1; lseek(fd_exb,0,0); /* for SUN-OS bug */ } last_min=buf[8]; /* #if DEBUGFLAG printf("%4x:",j); fflush(stdout); #endif */ /* write one sec */ if(j%2) j++; /* avoid odd byte block size */ if(j%(64*1024)==0) j+=2; /* avoid N*64KB block size */ if((re=write(fd_exb,buf,j))%zd",progname,j,re); perror(tb); #endif io_error=1; break; } init_flag=0; wfm=0; #if DEBUGFLAG printf("."); fflush(stdout); #endif if(re>0) wmemon(WTAPE_TOTAL,exb_total+=((re+512)/1024)); cnt+=j; } /* for(i=0;i<60;i++) */ if(io_error) { lseek(f_get,0,0); /* rewind file */ close_exb("ON ERROR"); switch_unit(-1); /* change exabyte */ continue; } break; } /* for(;;) */ /* close disk file */ #if DEBUGFLAG printf("\n"); #endif close(f_get); if(new_tape) { fp=fopen(log_file,"a+"); fprintf(fp,"unit %d %02X/%02X/%02X %02X:%02X --> ", exb_busy,buf[4],buf[5],buf[6],buf[7],buf[8]); fclose(fp); new_tape=0; } write_rsv(tm); #if DEBUGFLAG printf("%s < %zu total= %zu KB\n",name_buf,cnt,exb_total); #endif if(switch_req) { close_exb("BY REQ"); switch_unit(-1); /* change exabyte */ } } }