/* * Get the next character from the input. * Returns the character or * L_EOF if end of file * L_EOL if end of line */ int lex_get_char(LEX *lf) { if (lf->ch == L_EOF) { Emsg0(M_ABORT, 0, _("get_char: called after EOF." " You may have a open double quote without the closing double quote.\n")); } if (lf->ch == L_EOL) { /* * See if we are really reading a file otherwise we have reached EndOfFile. */ if (!lf->fd || bfgets(lf->line, lf->fd) == NULL) { lf->ch = L_EOF; if (lf->next) { if (lf->fd) { lex_close_file(lf); } } return lf->ch; } lf->line_no++; lf->col_no = 0; Dmsg2(1000, "fget line=%d %s", lf->line_no, lf->line); } lf->ch = (uint8_t)lf->line[lf->col_no]; if (lf->ch == 0) { lf->ch = L_EOL; } else { lf->col_no++; } Dmsg2(dbglvl, "lex_get_char: %c %d\n", lf->ch, lf->ch); return lf->ch; }
/* * This job is done, so release the device. From a Unix standpoint, * the device remains open. * * Note, if we were spooling, we may enter with the device blocked. * We unblock at the end, only if it was us who blocked the * device. * */ bool release_device(DCR *dcr) { utime_t now; JCR *jcr = dcr->jcr; DEVICE *dev = dcr->dev; bool ok = true; char tbuf[100]; int was_blocked = BST_NOT_BLOCKED; /* * Capture job statistics now that we are done using this device. */ now = (utime_t)time(NULL); update_job_statistics(jcr, now); dev->Lock(); if (!dev->is_blocked()) { block_device(dev, BST_RELEASING); } else { was_blocked = dev->blocked(); dev->set_blocked(BST_RELEASING); } lock_volumes(); Dmsg2(100, "release_device device %s is %s\n", dev->print_name(), dev->is_tape() ? "tape" : "disk"); /* * If device is reserved, job never started, so release the reserve here */ dcr->clear_reserved(); if (dev->can_read()) { VOLUME_CAT_INFO *vol = &dev->VolCatInfo; dev->clear_read(); /* clear read bit */ Dmsg2(150, "dir_update_vol_info. label=%d Vol=%s\n", dev->is_labeled(), vol->VolCatName); if (dev->is_labeled() && vol->VolCatName[0] != 0) { dcr->dir_update_volume_info(false, false); /* send Volume info to Director */ remove_read_volume(jcr, dcr->VolumeName); volume_unused(dcr); } } else if (dev->num_writers > 0) { /* * Note if WEOT is set, we are at the end of the tape and may not be positioned correctly, * so the job_media_record and update_vol_info have already been done, * which means we skip them here. */ dev->num_writers--; Dmsg1(100, "There are %d writers in release_device\n", dev->num_writers); if (dev->is_labeled()) { Dmsg2(200, "dir_create_jobmedia. Release vol=%s dev=%s\n", dev->getVolCatName(), dev->print_name()); if (!dev->at_weot() && !dcr->dir_create_jobmedia_record(false)) { Jmsg2(jcr, M_FATAL, 0, _("Could not create JobMedia record for Volume=\"%s\" Job=%s\n"), dcr->getVolCatName(), jcr->Job); } /* * If no more writers, and no errors, and wrote something, write an EOF */ if (!dev->num_writers && dev->can_write() && dev->block_num > 0) { dev->weof(1); write_ansi_ibm_labels(dcr, ANSI_EOF_LABEL, dev->VolHdr.VolumeName); } if (!dev->at_weot()) { dev->VolCatInfo.VolCatFiles = dev->file; /* set number of files */ /* * Note! do volume update before close, which zaps VolCatInfo */ dcr->dir_update_volume_info(false, false); /* send Volume info to Director */ Dmsg2(200, "dir_update_vol_info. Release vol=%s dev=%s\n", dev->getVolCatName(), dev->print_name()); } if (dev->num_writers == 0) { /* if not being used */ volume_unused(dcr); /* we obviously are not using the volume */ } } } else { /* * If we reach here, it is most likely because the job has failed, * since the device is not in read mode and there are no writers. * It was probably reserved. */ volume_unused(dcr); } Dmsg3(100, "%d writers, %d reserve, dev=%s\n", dev->num_writers, dev->num_reserved(), dev->print_name()); /* * If no writers, close if file or !CAP_ALWAYS_OPEN */ if (dev->num_writers == 0 && (!dev->is_tape() || !dev->has_cap(CAP_ALWAYSOPEN))) { dev->close(dcr); free_volume(dev); } unlock_volumes(); /* * Fire off Alert command and include any output */ if (!job_canceled(jcr)) { if (!dcr->device->drive_tapealert_enabled && dcr->device->alert_command) { int status = 1; POOLMEM *alert, *line; BPIPE *bpipe; alert = get_pool_memory(PM_FNAME); line = get_pool_memory(PM_FNAME); alert = edit_device_codes(dcr, alert, dcr->device->alert_command, ""); /* * Wait maximum 5 minutes */ bpipe = open_bpipe(alert, 60 * 5, "r"); if (bpipe) { while (bfgets(line, bpipe->rfd)) { Jmsg(jcr, M_ALERT, 0, _("Alert: %s"), line); } status = close_bpipe(bpipe); } else { status = errno; } if (status != 0) { berrno be; Jmsg(jcr, M_ALERT, 0, _("3997 Bad alert command: %s: ERR=%s.\n"), alert, be.bstrerror(status)); } Dmsg1(400, "alert status=%d\n", status); free_pool_memory(alert); free_pool_memory(line); } else { /* * If all reservations are cleared for this device raise an event that SD plugins can register to. */ if (dev->num_reserved() == 0) { generate_plugin_event(jcr, bsdEventDeviceReleased, dcr); } } } pthread_cond_broadcast(&dev->wait_next_vol); Dmsg2(100, "JobId=%u broadcast wait_device_release at %s\n", (uint32_t)jcr->JobId, bstrftimes(tbuf, sizeof(tbuf), (utime_t)time(NULL))); release_device_cond(); /* * If we are the thread that blocked the device, then unblock it */ if (pthread_equal(dev->no_wait_id, pthread_self())) { dev->dunblock(true); } else { /* * Otherwise, reset the prior block status and unlock */ dev->set_blocked(was_blocked); dev->Unlock(); } if (dcr->keep_dcr) { detach_dcr_from_dev(dcr); } else { free_dcr(dcr); } Dmsg2(100, "Device %s released by JobId=%u\n", dev->print_name(), (uint32_t)jcr->JobId); return ok; }
int main(int argc, char **argv) { FILE *in = stdin; int status; char temp[MAXEXPR]; /* temp strings for command */ /* static char expr[MAXEXPR] = "WRITE(_OUTPUT_UNIT,`DECOMPILE(`"; */ static char expr[MAXEXPR] = ""; static struct descriptor expr_dsc = {0, DTYPE_T, CLASS_S, (char *)expr}; static EMPTYXD(ans); static EMPTYXD(output_unit); static DESCRIPTOR(out_unit_stdout,"PUBLIC _OUTPUT_UNIT=*"); static DESCRIPTOR(out_unit_other,"PUBLIC _OUTPUT_UNIT=FOPEN($,'w')"); static DESCRIPTOR(reset_output_unit,"PUBLIC _OUTPUT_UNIT=$"); int prefixlen = strlen(expr); char line_in[MAXEXPR]; char last_line[MAXEXPR]; #ifdef _WIN32 char *hfile="%HOMEDRIVE%%HOMEPATH%\\AppData\\Local\\tdic"; #else char hfile[32]; strcpy(hfile,getenv("HOME")); strcat(hfile,HFILE); #endif #ifdef DYNTdiShr if(TDIhandle == NULL) { TDIhandle = dlopen(DYNTdiShr, RTLD_LAZY); if(!TDIhandle) { fprintf (stderr, "%s\n", dlerror()); exit(1); } *(void **)(&BTdiExecute) = dlsymget(TDIhandle, "TdiExecute"); } #endif #ifdef DYNreadline if(READhandle == NULL) { CURSEShandle = dlopen(DYNcurses, RTLD_NOW | RTLD_GLOBAL); READhandle = dlopen(DYNreadline, RTLD_LAZY); // READhandle = dlopen(DYNreadline, RTLD_NOW); // READhandle = dlopen(DYNreadline, RTLD_NOW | RTLD_GLOBAL); if(!READhandle) { fprintf (stderr, "%s\n", dlerror()); exit(1); } *(void **)(&Busing_history) = dlsymget(READhandle, "using_history"); *(void **)(&Bread_history) = dlsymget(READhandle, "read_history"); *(void **)(&Bwrite_history) = dlsymget(READhandle, "write_history"); *(void **)(&Badd_history) = dlsymget(READhandle, "add_history"); *(void **)(&Bhistory_truncate_file) = dlsymget(READhandle, "history_truncate_file"); *(void **)(&Breadline) = dlsymget(READhandle, "readline"); } #endif Busing_history(); *last_line=0; /* get input from file */ if (argc > 1) { in = fopen(argv[1],"r"); if (in == (FILE *)0) { printf("Error opening input file /%s/\n",argv[1]); return(0); } } /* if specified, output to a file, defaults to stdout */ if (argc > 2) { struct descriptor out_d = {0,DTYPE_T,CLASS_S,0}; out_d.length = (unsigned short)strlen(argv[2]); out_d.pointer = argv[2]; BTdiExecute(&out_unit_other,&out_d,&output_unit MDS_END_ARG); } else { BTdiExecute(&out_unit_stdout, &output_unit MDS_END_ARG); } /* get history loaded */ Bread_history(hfile); /* main loop to get characters */ while(bfgets(line_in,MAXEXPR,in,PROMPT) != NULL) { int comment = line_in[0] == '%'; /* is a comment */ int len = strlen(line_in); /* get first line of command */ if (!comment) { BTdiExecute(&reset_output_unit,&output_unit, &ans MDS_END_ARG); /* tdiputs(line_in);*/ } /* if a continuation, keep getting the rest of the command */ while(line_in[len-1] == '\\') { bfgets(&line_in[len-1],MAXEXPR-len+1,in,"> "); /* if (!comment) tdiputs(&line_in[len-1]);*/ len = strlen(line_in); } if (!comment) { static DESCRIPTOR(error_out,"_MSG=DEBUG(0),DEBUG(4),WRITE($,_MSG)"); static DESCRIPTOR(clear_errors,"WRITE($,DECOMPILE($)),DEBUG(4)"); #ifdef OLDHIST if(!strcmp(line_in,last_line) || (*line_in == ' ')) { /* printf("Removing [%d]\n",Bwhere_history());*/ HIST_ENTRY *entry = Bremove_history(Bwhere_history()); if(entry) { free (entry->line); free (entry); } } else strcpy(last_line,line_in); #else if(*line_in && (*line_in != ' ') && strcmp(line_in,last_line)) { Badd_history(line_in); strcpy(last_line,line_in); } #endif /* Check the special TDIC options */ if(!strcmp(line_in,"exit") || !strcmp(line_in,"quit")) { Bwrite_history(hfile); if(getenv("HISTFILESIZE")) { int i; sscanf(getenv("HISTFILESIZE"),"%d",&i); Bhistory_truncate_file(hfile,i); } exit(1); } else if(*line_in == '!') { *line_in = ' '; /* replace by a space */ system(line_in); } else if(!strcmp(line_in,"help") || !strcmp(line_in,"man")) { printf("TDI(C) reference (October 1999)\n"); printf(" help func <help function>\n"); printf(" help func* <lists 1st line of each help>\n"); printf(" use func* <lists lines in comment starting with [call:]>\n"); printf(" type func(*) <type/p all the functions requested>\n"); printf(" tcl <TCL command>\n open <shot#>\n"); printf(" !<shell command>\n man [TDI intrinsic]\n"); printf(" exit (guess)\n ; behaves as in MatLab\n"); } else if(!strncmp(line_in,"type ",5)) { char *nameStart, *nameEnd, *mdspath, *tpath; struct stat statf; strcpy(temp, line_in+5); /* copy the target */ /* Check the path name for finding file */ mdspath = getenv(MDSPATH); /* get pointer */ if(mdspath == NULL) { printf("Path [%s] not defined !\n",MDSPATH); return(0); } /* Strip the name down before appending it to command */ nameStart=temp; while(*nameStart == ' ') nameStart++; /* Find end of name */ if( (nameEnd = strchr(nameStart,'.')) == NULL) nameEnd = nameStart + strlen(nameStart); else nameEnd--; while(*nameEnd == ' ' && nameEnd >= nameStart) nameEnd--; /* Zero end of string */ *++nameEnd = '\0'; /* If there is anything left, scan the path */ if(strlen(nameStart)) do { strcpy(line_in,"more "); if((tpath=strchr(mdspath,';'))==NULL) { strcat(line_in,mdspath); } else { strncat(line_in,mdspath,tpath-mdspath); mdspath = tpath+1; /* put to next char */ } strcat(line_in, "/"); strcat(line_in, nameStart);/* put back the target */ strcat(line_in, ".fun"); if(!stat(line_in+5,&statf)) { printf("Found <%s>\n",line_in+5); system(line_in); tpath = NULL; } } while(tpath != NULL); } else if(!strncmp(line_in,"man ",4)) { strcpy(temp, line_in+4); /* copy the target */ strcpy(line_in,"man "); strcat(line_in, temp); /* put back the target */ system(line_in); } else if(!strncmp(line_in,"tcl",3)) { strcpy(line_in, "$MDSPLUS/bin/tcl"); /* move the text to the left */ system(line_in); } #ifdef NEVER else if(!strncmp(line_in,"tcl",3)) { strcpy(line_in, line_in+4); /* move the text to the left */ mdsdcl$do(&Dtcl,&Dcommand); } else if(!strncmp(line_in,"open",4)) { strcpy(temp, line_in+5); /* copy shot number into temp */ strcpy(line_in,"set tree tcv_shot/shot="); strcat(line_in, temp); /* concantenate the number */ mdsdcl$do(&Dtcl,&Dcommand); }