Пример #1
0
/*
 * 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;
}
Пример #2
0
/*
 * 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;
}
Пример #3
0
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);
	 }