00001
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047 #include <SUM.h>
00048 #include <soi_key.h>
00049 #include <sys/time.h>
00050 #include <sys/errno.h>
00051 #include <rpc/rpc.h>
00052 #include <rpc/pmap_clnt.h>
00053 #include <sum_rpc.h>
00054 #include <soi_error.h>
00055 #include <printk.h>
00056
00057 char *get_eff_date(int plusdays);
00058
00059 #define TODAY (atol(get_eff_date(0)))
00060
00061 extern void printkey (KEY *key);
00062 void usage();
00063 void get_cmd(int argc, char *argv[]);
00064 void setup();
00065 void goaway();
00066 void sighandler(int sig);
00067 KEY *jmtxdo_1(KEY *params);
00068 static void jmtxprog_1(struct svc_req *rqstp, SVCXPRT *transp);
00069
00070 static struct timeval TIMEOUT = { 30, 0 };
00071 uint32_t rinfo;
00072 CLIENT *current_client, *clnttape, *clntsum;
00073 SVCXPRT *glb_transp;
00074 SVCXPRT *transp;
00075
00076 KEY *alist;
00077 static int WRTSTATUS;
00078
00079 int soi_errno = NO_ERROR;
00080 char *username;
00081 char *tapeid;
00082 char thishost[MAX_STR];
00083 char devname[64];
00084 char mode[64];
00085 int drivenum;
00086 int slotnum, slot1, slot2;
00087 time_t now;
00088 int verbose = 0;
00089 int debugflg = 0;
00090
00091 static struct timeval first[6], second[6];
00092 float ftmp;
00093
00094
00095 void StartTimer(int n)
00096 {
00097 gettimeofday (&first[n], NULL);
00098 }
00099
00100 float StopTimer(int n)
00101 {
00102 gettimeofday (&second[n], NULL);
00103 if (first[n].tv_usec > second[n].tv_usec) {
00104 second[n].tv_usec += 1000000;
00105 second[n].tv_sec--;
00106 }
00107 return (float) (second[n].tv_sec-first[n].tv_sec) +
00108 (float) (second[n].tv_usec-first[n].tv_usec)/1000000.0;
00109 }
00110
00111
00112 int send_mail(char *fmt, ...)
00113 {
00114 va_list args;
00115 char string[1024], cmd[1024];
00116
00117 va_start(args, fmt);
00118 vsprintf(string, fmt, args);
00119
00120 sprintf(cmd, "echo \"%s\" | Mail -s \"jmtx mail\" jim@sun.stanford.edu", string);
00121 system(cmd);
00122 va_end(args);
00123 return(0);
00124 }
00125
00126 void usage()
00127 {
00128 printf("This is a stand alone program that will execute mtx load, unload, transfer and \n");
00129 printf("status commands via SUMS, so that it knows where all the tapes are.\n");
00130 printf("Usage: jmtx -f /dev/t950 status\n");
00131 printf("Usage: jmtx -f /dev/t950 load|unload [slot#] [drive#]\n");
00132 printf("Usage: jmtx -f /dev/t950 transfer [source_slot#] [dest_slot#]\n");
00133 printf("Usage: jmtx -f /dev/t950 transtape [tape#] [dest_slot#]\n");
00134 printf(" where the program finds the slot# for the given tape# and does transfer\n");
00135 printf("NOTE: you must be user production to run.\n");
00136 printf("NOTE: The -f arg is for symmetry with mtx only. You will connect\n");
00137 printf(" to the sum_svc that you are configured to and get its drives.\n");
00138 exit(1);
00139 }
00140
00141
00142 void get_cmd(int argc, char *argv[])
00143 {
00144 int c;
00145
00146 while(--argc > 0 && (*++argv)[0] == '-') {
00147 while((c = *++argv[0]))
00148 switch(c) {
00149 case 'd':
00150 debugflg=1;
00151 break;
00152 case 'v':
00153 verbose=1;
00154 break;
00155 case 'f':
00156 ++argv[0];
00157 if(*++argv[0] != NULL) {
00158 strcpy(devname, argv[0]);
00159 }
00160 while(*++argv[0] != NULL);
00161 --argv[0];
00162 break;
00163 default:
00164 usage();
00165 break;
00166 }
00167 }
00168 if(argc == 2) {
00169 strcpy(mode, argv[1]);
00170 if(strcmp(mode, "status")) {
00171 usage();
00172 }
00173 return;
00174 }
00175 else if(argc != 4) {
00176 usage();
00177 }
00178 strcpy(mode, argv[1]);
00179 if(strcmp(mode, "load") && strcmp(mode, "unload") && strcmp(mode, "transfer") && strcmp(mode, "transtape")) {
00180 usage();
00181 }
00182 if(!strcmp(mode, "transfer")) {
00183 slot1 = atoi(argv[2]);
00184 slot2 = atoi(argv[3]);
00185 }
00186 else if(!strcmp(mode, "transtape")) {
00187 tapeid = argv[2];
00188 slot2 = atoi(argv[3]);
00189 }
00190 else {
00191 slotnum = atoi(argv[2]);
00192 drivenum = atoi(argv[3]);
00193 }
00194 }
00195
00196
00197 void goaway()
00198 {
00199
00200
00201
00202
00203
00204 (void) pmap_unset(JMTXPROG, JMTXVERS);
00205 exit(1);
00206 }
00207
00208
00209 void sighandler(int sig)
00210 {
00211 char line[80];
00212
00213 printf("\n jmtx received a termination signal\n");
00214 goaway();
00215 }
00216
00217
00218
00219 void setup()
00220 {
00221 char *cptr;
00222 int n;
00223 char pgport[32];
00224
00225 printk_set(printf, printf);
00226 gethostname(thishost, MAX_STR);
00227 cptr = index(thishost, '.');
00228 if(cptr) *cptr = (char)NULL;
00229
00230 signal(SIGINT, sighandler);
00231 if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
00232 signal(SIGTERM, sighandler);
00233
00234
00235 (void) pmap_unset(JMTXPROG, JMTXVERS);
00236 transp = svctcp_create(RPC_ANYSOCK, 0, 0);
00237 if (transp == NULL) {
00238 printf("***cannot create tcp service\n");
00239 exit(1);
00240 }
00241 if (!svc_register(transp, JMTXPROG, JMTXVERS, jmtxprog_1, IPPROTO_TCP)) {
00242 printf("***unable to register (TAPEARCPROG, TAPEARCVERS, tcp)\n");
00243 exit(1);
00244 }
00245
00246
00247 if(strcmp(thishost, SUMSVCHOST))
00248 clnttape = clnt_create(thishost, TAPEPROG, TAPEVERS, "tcp");
00249 else
00250 clnttape = clnt_create(TAPEHOST, TAPEPROG, TAPEVERS, "tcp");
00251 if(!clnttape) {
00252 clnt_pcreateerror("Can't get client handle to tape_svc in jmtx");
00253 printf("jmtx can't get tape_svc handle on %s\n", thishost);
00254 exit(1);
00255 }
00256 }
00257
00258
00259 int main(int argc, char *argv[])
00260 {
00261 int status;
00262 uint32_t retstat = 0;
00263 char *call_err;
00264
00265 get_cmd(argc, argv);
00266 if(!(username = (char *)getenv("USER"))) username = "nouser";
00267 if(strcmp(username, "production")) {
00268 printf("!!NOTE: You must be user production to run tapearc!\n");
00269 exit(1);
00270 }
00271
00272
00273 setup();
00274
00275 alist = newkeylist();
00276 setkey_str(&alist, "mode", mode);
00277
00278 if(!(strcmp(mode, "transtape"))) {
00279 setkey_str(&alist, "tapeid", tapeid);
00280 setkey_int(&alist, "slot2", slot2);
00281 }
00282 else if(!(strcmp(mode, "transfer"))) {
00283 setkey_int(&alist, "slot1", slot1);
00284 setkey_int(&alist, "slot2", slot2);
00285 }
00286 else if(strcmp(mode, "status")) {
00287 setkey_int(&alist, "slotnum", slotnum);
00288 setkey_int(&alist, "drivenum", drivenum);
00289 }
00290
00291 status = clnt_call(clnttape, JMTXTAPEDO, (xdrproc_t)xdr_Rkey, (char *)alist,
00292 (xdrproc_t)xdr_uint32_t, (char *)&retstat, TIMEOUT);
00293 if(status != 0) {
00294 if(status != RPC_TIMEDOUT) {
00295 clnt_perrno(status);
00296 printf("\n***Error on clnt_call() to tape_svc JMTXTAPEDO procedure\n");
00297 call_err = clnt_sperror(clnttape, "Err");
00298 printf("%s\n", call_err);
00299 goaway();
00300 }
00301 else {
00302 printf("\nThe call to tape_svc has timed out. Still will accept a response...\n");
00303 }
00304 }
00305 if(retstat == RESULT_PEND) {
00306 printf("jmtx waiting for results from tape_svc...\n");
00307 }
00308 else {
00309 if(retstat != 0) {
00310 printf("Error in return status = %d\n", retstat);
00311 if(retstat == 2) printf("Error: tape not in a slot\n");
00312 goaway();
00313 }
00314 }
00315 svc_run();
00316 }
00317
00318
00319
00320
00321
00322 static void
00323 jmtxprog_1(rqstp, transp)
00324 struct svc_req *rqstp;
00325 SVCXPRT *transp;
00326 {
00327 union __svcargun {
00328 Rkey jmtxdo_1_arg;
00329 } argument;
00330 char *result;
00331
00332 bool_t (*xdr_argument)(), (*xdr_result)();
00333 char *(*local)();
00334 switch (rqstp->rq_proc) {
00335 case NULLPROC:
00336 printf("Called NULLPROC in jmtxprog_1()\n");
00337 (void) svc_sendreply(transp, (xdrproc_t)xdr_void, (char *)NULL);
00338 return;
00339 case JMTXDO:
00340 xdr_argument = xdr_Rkey;
00341 xdr_result = xdr_Rkey;;
00342 local = (char *(*)()) jmtxdo_1;
00343 break;
00344 default:
00345 printf("**jmtxprog_1() dispatch default procedure %ld,ignore\n", rqstp->rq_proc);
00346 (void) svc_sendreply(transp, (xdrproc_t)xdr_void, (char *)NULL);
00347 svcerr_noproc(transp);
00348 return;
00349 }
00350 bzero((char *)&argument, sizeof(argument));
00351 if (!svc_getargs(transp, (xdrproc_t)xdr_argument, (char *)&argument)) {
00352 printf("***Error on svc_getargs()\n");
00353 svcerr_decode(transp);
00354 svc_sendreply(transp, (xdrproc_t)xdr_void, (char *)NULL);
00355 return;
00356
00357 }
00358
00359 if(!svc_sendreply(transp, (xdrproc_t)xdr_void, (char *)NULL)) {
00360 svcerr_systemerr(transp);
00361 return;
00362 }
00363 glb_transp = transp;
00364 result = (*local)(&argument, rqstp);
00365
00366
00367 if (!svc_freeargs(transp, (xdrproc_t)xdr_argument, (char *)&argument)) {
00368 printf("**unable to free arguments\n");
00369
00370 }
00371 return;
00372 }
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382 KEY *jmtxdo_1(KEY *params)
00383 {
00384 char *errstr, *sumserv;
00385
00386 if(findkey(params, "DEBUGFLG")) {
00387 debugflg = getkey_int(params, "DEBUGFLG");
00388 if(debugflg) {
00389 printf("!!TEMP in jmtxdo_1() call in tape_svc. keylist is:\n");
00390 keyiterate(printkey, params);
00391 }
00392 }
00393
00394 if(WRTSTATUS = getkey_int(params, "STATUS")) {
00395 printf("**Error return for jmtx\n");
00396 sumserv = (char *)getenv("SUMSERVER");
00397 if(findkey(params, "ERRSTR")) {
00398 errstr = getkey_str(params, "ERRSTR");
00399 printf("%s", errstr);
00400 }
00401 printf("\nSee %s:/usr/local/logs/SUM/tape_svc_XX.log\n", sumserv);
00402 (void) pmap_unset(JMTXPROG, JMTXVERS);
00403 exit(1);
00404 }
00405 else {
00406 if(findkey(params, "MSG")) {
00407 printf("%s\n", getkey_str(params, "MSG"));
00408 }
00409 printf("Success\n");
00410 }
00411 (void) pmap_unset(JMTXPROG, JMTXVERS);
00412 exit(0);
00413
00414 }
00415
00416
00417
00418
00419
00420 char *get_eff_date(int plusdays)
00421 {
00422 struct timeval tvalr;
00423 struct tm *t_ptr;
00424 time_t newtime;
00425 char *timestr;
00426
00427 if(gettimeofday(&tvalr, NULL) == -1) {
00428 return("200712121212");
00429 }
00430 t_ptr = localtime(&tvalr.tv_sec);
00431 t_ptr->tm_mday = t_ptr->tm_mday + plusdays;
00432 newtime = mktime(t_ptr);
00433 t_ptr = localtime(&newtime);
00434 timestr = (char *)malloc(32);
00435 sprintf(timestr, "%04d%02d%02d%02d%02d",
00436 t_ptr->tm_year+1900, t_ptr->tm_mon+1, t_ptr->tm_mday,
00437 t_ptr->tm_hour, t_ptr->tm_min);
00438 return(timestr);
00439 }