⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gqlplus.c

📁 基于的linux的oracle sqlplus替代工具
💻 C
📖 第 1 页 / 共 5 页
字号:
{  int  len;  char *xtr = (char *) 0;  if (str)    {      len = strlen(str)-1;      while (str[len] == ' ')        str[len--] = '\0';      xtr = strdup(str+strspn(str, " "));    }  return xtr;}/*    Returns 1 if a string szOrg starts with szPrefix.   Note that leading blanks/tabs are ignored.   Returns 0 otherwise.   @param szOrg can be NULL.   @param szPrefix can be NULL. */int startsWith(char* szOrg, const char* szPrefix){  int iMatch = 0;  if (   (szOrg    == (char*) 0)      || (szPrefix == (char*) 0)       )   {    /* do nothing. */  }  else   {    char* szOrgTrimmed = trim(szOrg);    if (strstr(szOrgTrimmed, szPrefix) == szOrgTrimmed)     {      iMatch = 1;    }  }  return iMatch;}/*  Return 1 if the following conditions satisfy:    a) current line startsWith szPrefix AND    b) the remaining part after szPrefix in szOrg starts with szCmd  Return 0 otherwise.*/int matchCommand(char* szOrg, char* szPrefix, char* szCmd){  int iMatch = 0;  if (   (szOrg    == (char*) 0)      || (szPrefix == (char*) 0)       || (szCmd    == (char*) 0)      )   {    /* do nothing. */  }  else   {    char* szOrgTrimmed = trim(szOrg);    if (strstr(szOrgTrimmed, szPrefix) == szOrgTrimmed) {      char* szRemaining = szOrgTrimmed + strlen(szPrefix);      iMatch = startsWith(szRemaining, szCmd);    }  }  return iMatch;}/*  Return lowercase and trimmed version of 'str'.*/char *tl(const char *str){  int  i;  char *xtr = (char *) 0;  char *lline = (char *) 0;  if (str)    {      lline = strdup(str);      for (i = 0; i < strlen(str); i++)        lline[i] = tolower((int) lline[i]);    }  xtr = trim(lline);  free(lline);  return xtr;}/*  Set 'str' to lowercase.*/static void tl2(char *str){  int  i = 0;  if (str)    while (str[i] != '\0')      {        str[i] = tolower((int) str[i]);        i++;      }}/*  Utility function for check_numeric_prompt().*/static int check_numeric(const char *str){  int check_prompt = 0;  if (strlen(str) == 5)    if (isspace((int) str[4]))      if (isspace((int) str[3]) || (str[3] == '*') || (str[3] == 'i'))        if (isdigit((int) str[2]))          {            check_prompt = 1;            if (isdigit((int) str[0]) && isspace((int) str[1]))              check_prompt = 0;          }  return check_prompt;}/*  Return 1 if 'str' is a correct Oracle numeric prompt. The numeric  prompt has up to three numeric characters, followed by a space, or  an asterisk, or an 'i' (for Insert command).  ljb, 06/16/2004: there is another version of a numeric prompt, when  'time' is set. The prompt looks like this:  SQL> set time on  19:41:37 SQL> select * from scott.salgrade  19:41:42   2  ;*/static int check_numeric_prompt(const char *str){  int check_prompt = 0;  if (str)    {      /*	Check for the short version of the numeric prompt:      */      if (strlen(str) == 5)	check_prompt = check_numeric(str);      /*	Check for the long version of the numeric prompt (when time is set):      */      else if (strlen(str) == 14)	{	  if (isdigit((int) str[0]) && isdigit((int) str[1]) &&	      str[2] == ':' && isdigit((int) str[3]) && isdigit((int) str[4]) &&	      str[5] == ':' && isdigit((int) str[6]) && isdigit((int) str[7]) &&	      isspace((int) str[8]))	    check_prompt = check_numeric(str+9);	}    }  return check_prompt;}/*  Return 1 if 'str' is a correct Oracle time prompt. The time prompt  has time followed by a space followed by `sqlprompt', like this:  19:41:37 SQL>*/static int check_time_prompt(char *str, char *sqlprompt){  int check_prompt = 0;  if (str)    {      if (isdigit((int) str[0]) && isdigit((int) str[1]) &&	  str[2] == ':' && isdigit((int) str[3]) && isdigit((int) str[4]) &&	  str[5] == ':' && isdigit((int) str[6]) && isdigit((int) str[7]) &&	  isspace((int) str[8]) && !strcmp(&str[9], sqlprompt))	check_prompt = 1;    }  return check_prompt;}void ignore_sigint(){  sigemptyset(&iact.sa_mask);  iact.sa_flags = 0;#ifdef SA_RESTART  iact.sa_flags |= SA_RESTART;#endif  iact.sa_handler = SIG_IGN;  sigaction(SIGINT, &iact, (struct sigaction *) 0);}static void ignore_sigpipe(){  sigemptyset(&pact.sa_mask);  pact.sa_flags = 0;#ifdef SA_RESTART  pact.sa_flags |= SA_RESTART;#endif  pact.sa_handler = SIG_IGN;  sigaction(SIGPIPE, &pact, (struct sigaction *) 0);}/*  SIGINT handler. Passes the signal to the child (i.e., sqlplus)  unless we are in the middle of an editing session (edit_pid !=  0). The reason is this: Emacs redefines Ctrl-G to be  SIGINT-generating key (instead of Ctrl-C). So, during Emacs editing  session, Ctrl-G generates SIGINT which we don't want to pass to  sqlplus because it disrupts its' operation and does not make sense  anyway (that is not the interrupt we want to catch; we only care  about Ctrl-C typed at gqlplus prompt).*/static void sigint_handler(int signo){  if (edit_pid == 0)    {      kill(sqlplus_pid, SIGINT);      /*ignore_sigint();*/    }}/*  SIGQUIT handler.*/static void sigquit_handler(int signo){  kill(sqlplus_pid, signo);  printf("Quit\n");  _exit(0);}void install_sigint_handler(){  sigemptyset(&iact.sa_mask);  iact.sa_flags = 0;#ifdef SA_RESTART  iact.sa_flags |= SA_RESTART;#endif/*  Use sigaction(), for portability and reliability.*/  iact.sa_handler = sigint_handler;  sigaction(SIGINT, &iact, (struct sigaction *) 0);}void install_sigquit_handler(){  sigemptyset(&qact.sa_mask);  qact.sa_flags = 0;#ifdef SA_RESTART  qact.sa_flags |= SA_RESTART;#endif/*  Use sigaction(), for portability and reliability.*/  qact.sa_handler = sigquit_handler;  sigaction(SIGQUIT, &qact, (struct sigaction *) 0);}/*  Install signal handlers.*/void sig_init(void){  install_sigint_handler();  install_sigquit_handler();  ignore_sigpipe();}static void kill_sqlplus(){  kill(sqlplus_pid, SIGTERM);}/*  Return 1 if 'str' is one of the Oracle password prompts.*/static int check_password_prompt(char *str){  int check_prompt = 0;    if (str)    {      if (!strcmp(str, PASSWORD_PROMPT) ||	  !strcmp(str, OLD_PASSWORD) ||	  !strcmp(str, NEW_PASSWORD) ||	  !strcmp(str, RETYPE_PASSWORD))	check_prompt = 1;    }  return check_prompt;}/*  Get sqlplus output from `fd' and display it (*outstr is NULL)  without prompt, or store it in *outstr. The prompt is returned and  will be displayed later, by readline() (if we display it here, it  would get overwritten by readline()).*/static char *get_sqlplus(int fd, char *line, char **outstr){  int  done;  int  cntr;  int  nread = 0;  int  plen;  int  llen;  int  olen;  int  capacity;  int  ocapacity;  int  pdiff;  char *lline;  char *xtr;  char *last_line;  char *otr = (char *) 0;  char *ptr = (char *) 0;  char *prompt = (char *) 0;  done = 0;  cntr = 0;  capacity = INIT_LINE_LENGTH;  ocapacity = INIT_LINE_LENGTH;  /*      lline has the current undisplayed sqlplus content. llen is the     length of the content.  */  lline = malloc((capacity+1)*sizeof(char));   lline[0] = '\0';  llen = 0;  olen = 0;  if (outstr != (char **) 0)    {      otr = malloc((ocapacity+1)*sizeof(char));      ptr = otr;    }  /*    Read sqlplus output. We read until sqlplus sends a prompt. We    recognize the following prompts:    'SQL> '    'Enter user-name: '    'Enter password: '    'Disconnected from Oracle...'     'Enter value for ...'     'Specify log: {<RET>=suggested | filename | AUTO | CANCEL}'    numeric prompt (for multi-line SQL statements)    user-defined prompt (see function set_sql_prompt())    So far looks like these are the only prompts. If sqlplus sends    anything else, we are doomed. ljb, 05/20/2002  */  while (done == 0)    {      nread = read(fd, line, pipe_size);      if (nread > 0)        {          line[nread] = '\0';          fflush(stdout);          if (nread+llen > capacity)            {              while (nread+llen > capacity)                capacity += capacity;              lline = realloc(lline, capacity+1);            }          if ((outstr != (char **) 0) && (nread+olen > ocapacity))            {              while (nread+olen > ocapacity)                ocapacity += ocapacity;              pdiff = ptr-otr;              otr = realloc(otr, ocapacity+1);              ptr = otr+pdiff;            }          memcpy(&lline[llen], line, nread);          llen += nread;          lline[llen] = '\0';          if ((!strncmp(lline, QUIT_PROMPT_1, strlen(QUIT_PROMPT_1)) && (state == STARTUP)) ||               (strstr(lline, QUIT_PROMPT_1) && (state == STARTUP)) ||               strstr(lline, QUIT_PROMPT_2) || strstr(lline, USAGE_PROMPT))            {	      done = 1;	      quit_sqlplus = 1;            }	  	  /*	    The following change is to address in ADE view gqlplus 	    invocation problem.	  */	  if ((!strncmp(lline, VALUE_PROMPT, strlen(VALUE_PROMPT)))	      || strstr(lline, SQL_PROMPT)	      || strstr(lline, RECOVER_PROMPT)	      ) 	    done = 1;          /*            Display everything up to the last newline.	  */          xtr = strrchr(lline, '\n');          if (xtr)            {              last_line = strdup(xtr+1);              plen = xtr-lline;              if (!outstr)                {                  if (plen > 0)                    write(STDOUT_FILENO, lline, plen);                }              else                {                  memcpy(ptr, lline, plen);                  ptr[plen] = '\0';                  ptr += plen;                  olen += plen;                }              /*                Adjust lline. After adjustment, only the last line                received from sqlplus, so far, remains in lline.              */              llen -= plen;              memcpy(lline, xtr, llen);              lline[llen] = '\0';              if ((sql_prompt && !strcmp(last_line, sql_prompt)) ||                   !strcmp(last_line, USER_PROMPT) ||                  !strncmp(last_line, VALUE_PROMPT, strlen(VALUE_PROMPT)) ||		  check_time_prompt(last_line, sql_prompt) ||                  check_password_prompt(last_line))                done = 1;              free(last_line);            }          else if ((sql_prompt && !strcmp(lline, sql_prompt)) ||                    check_numeric_prompt(lline) ||                   check_time_prompt(lline, sql_prompt) ||                   check_password_prompt(lline))            done = 1;        }      else        {          if (nread < 0)            perror((char *) 0);        }    }  /*    Display the remaining content, up to the last newline. Everything    beyond that is the prompt.  */  xtr = strrchr(lline, '\n');  if (xtr)    {      xtr++;      prompt = strdup(xtr);      llen -= strlen(prompt);      if (!outstr)        {          if (llen > 0)            write(STDOUT_FILENO, lline, llen);        }      else         {          memcpy(ptr, lline, llen);          ptr[llen] = '\0';        }    }  else    prompt = strdup(lline);  free(lline);  if (outstr != (char **) 0)    *outstr = otr;  /*install_sigint_handler();*/  return prompt;}/*  A special version of get_sqlplus() supporting the 'set sqlprompt'  command. This function is retrieving one line from sqlplus, and that  line is the new sql_prompt.*/static char *set_sql_prompt(int fd, char *line){  int  cntr;  int  nread = 0;  int  llen;  char *lline;  cntr = 0;  /*      lline has the current undisplayed sqlplus content. llen is the     length of the content.  */  lline = malloc((MAX_PROMPT_LEN+1)*sizeof(char));   lline[0] = '\0';  llen = 0;  /*    Get bytes from sqlplus. We gamble here that everything will come    from sqlplus in one read(), since 'set sqlprompt' is a simple and    quick operation. If it doesn't, we are doomed.  */  nread = read(fd, line, pipe_size);  if (nread > 0)    {      line[nread] = '\0';

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -