📄 gqlplus.c
字号:
fflush(stdout); memcpy(&lline[llen], line, nread); llen += nread; lline[llen] = '\0'; cntr++; } else { if (nread < 0) { perror((char *) 0); free(lline); lline = (char *) 0; } } return lline;}/* Single line read from sqlplus. */static char *read_sqlplus(int fd, char *line){ int nread; char *rline; rline = (char *) 0; /* Get bytes from sqlplus. We gamble here that everything will come from sqlplus in one read(). If it doesn't, we are doomed. */ nread = read(fd, line, pipe_size); if (nread > 0) { line[nread] = '\0'; rline = strdup(line); } else if (nread < 0) perror("read_sqlplus()"); return rline;}/* Special processing for the ACCEPT sqplus command `cmd'. The special processing is required because the command essentially redefines prompt while the user enters value of the variable defined in the ACCEPT command, thus we cannot use the standard gqlplus loop to read message from sqlplus.*/static char *accept_cmd(char *cmd, int fdin, int fdout, char *sql_prompt, char *line){ int status; int len; char *accept; char *rline; char *prompt; char *ptr; char *fline; accept = (char *) 0; /* Is there a prompt? If there is, read sqlplus message (which will be either the ACCEPT prompt, or an error message). */ if (strstr(cmd, " prompt ")) { /* Ensure that entire sqlplus message will arrive in a single read(). This is particularly important in case of error messages, which seem to arrive in two pieces. */ sleep(1); /* Read the sqlplus message in response to the ACCEPT command. Typically, that would be `prompt' parameter of the ACCEPT command. */ accept = read_sqlplus(fdin, line); } /* If this message is terminated with `sql_prompt', that means that sqlplus actually returned error message. If that is the case, print the first line, and return. */ if (accept && (ptr = strchr(accept, '\n'))) { len = ptr-accept+1; fline = malloc((len+1)*sizeof(char)); memcpy(fline, accept, len); fline[len] = '\0'; printf("%s", fline); fflush(stdout); free(fline); prompt = strdup(sql_prompt); } else { /* Now place user input in `rline' using readline(). */ rline = readline(accept); /* Send it to sqlplus. */ write(fdout, rline, strlen(rline)); /* Terminate the user input sent to sqlplus. */ status = write(fdout, "\n", 1); if (status == -1) { fprintf(stderr, "sqlplus terminated - exiting...\n"); exit(-1); } /* Now read the message sent from sqlplus, which should be the SQL prompt. We don't display it, since that will be done by the subsequent readline() call. */ prompt = read_sqlplus(fdin, line); } return prompt;}/* Extract tokens (separated by characters in 'delimiter' string) from 'str'. Return NULL-terminated array of tokens. The function allocates the space for the returned array. It is the caller's responsibility to free it.*/static char **str_tokenize(char *str, char *delimiter){ int len; int i; int rlen; int cntr; int capacity = INIT_LENGTH; char *xtr; char *ptr; char **tokens; char **xtokens; tokens = (char **) 0; cntr = 0; if ((str != (char *) 0) && (delimiter != (char *) 0)) { rlen = strlen(str); if (rlen > 0) { tokens = malloc(INIT_LENGTH*sizeof(char *)); capacity = INIT_LENGTH; } xtr = str; while (rlen > 0) { len = strspn(xtr, delimiter); xtr += len; rlen -= len; len = strcspn(xtr, delimiter); rlen -= len; if (len > 0) { ptr = malloc(len+1); memcpy(ptr, xtr, len); ptr[len] = '\0'; xtr += len; tokens[cntr++] = ptr; if (cntr >= capacity) { capacity += capacity; xtokens = malloc(capacity*sizeof(char *)); for (i = 0; i < cntr; i++) { xtokens[i] = strdup(tokens[i]); free(tokens[i]); } free(tokens); tokens = xtokens; } } } if (tokens) tokens[cntr] = (char *) 0; } return tokens;}static void str_free(char **tokens){ int i; i = 0; if (tokens) while (tokens[i] != (char *) 0) free(tokens[i++]); free(tokens);}static char *sfree(char *str){ free(str); return (char *) 0;}/* Return 1 if file described by `st_mode' is regular executable file.*/static int check_mode(mode_t st_mode){ int mode; mode_t mode1; mode_t mode2; mode = 0; mode1 = S_ISREG(st_mode); if (mode1) { mode2 = S_IXUSR; mode = st_mode & S_IXUSR; } return mode;}/* Search PATH for executable `exe'. Return full path to exe.*/static char *search_path(char *exe){ int i; int status; int done; int mode; char *path; char *env; char *str; char *xtr; char **dirs; struct stat buf; path = (char *) 0; env = getenv(PATH); if (env) { dirs = str_tokenize(env, ":"); i = 0; str = malloc(strlen(env)+strlen(exe)+2); done = 0; while (((xtr = dirs[i++]) != (char *) 0) && !done) { sprintf(str, "%s/%s", xtr, exe); status = stat(str, &buf); if (!status) { mode = check_mode(buf.st_mode); if (mode) { path = str; done = 1; } } } str_free(dirs); } return path;}/* Search PATH for file named `exe' with proper permissions. Return full path to the file.*/static char *search_exe(char *exe){ int status; int mode; char *path; char *lpath; struct stat buf; path = (char *) 0; lpath = search_path(exe); if (lpath) { /* Check permissions. */ status = stat(lpath, &buf); if (!status) { mode = check_mode(buf.st_mode); if (mode) path = lpath; } } return path;}char *get_env(char *name){ char *xtr; char *env; xtr = getenv(name); if (xtr != (char *) 0) { env = malloc(strlen(name)+strlen(xtr)+2); sprintf(env, "%s=%s", name, xtr); } else env = strdup(""); return env;}char **get_environment(void){ int idx; char *env; char **enx; enx = calloc(MAX_NENV+1, sizeof(char *)); env = get_env(ORACLE_HOME); idx = 0; enx[idx++] = env; enx[idx++] = get_env(ORACLE_SID); enx[idx++] = get_env(TNS_ADMIN); enx[idx++] = get_env(SQLPATH); enx[idx++] = get_env(NLS_LANG); /* added by dbakorea */ enx[idx++] = get_env(ORA_NLS33); /* added by dbakorea */ enx[idx++] = get_env(NLS_DATE_FORMAT); /* added by leeym */ enx[idx++] = get_env(NLS_COMP); enx[idx++] = get_env(NLS_SORT); enx[idx++] = get_env(LD_LIBRARY_PATH); enx[idx++] = get_env(DYLD_LIBRARY_PATH); enx[idx++] = get_env(ORACLE_PATH); enx[idx++] = get_env(TWO_TASK); return enx;}static void print_environment(char **enx){ int idx; char *env; idx = 0; while (enx[idx]) printf("enx[%d]: '%s'\n", idx, enx[idx++]);}/* Find the location of `sqlplus' binary. `orahome' is the value of ORACLE_HOME environment variable, if it is defined. The rules are as follows: - look for executable binary `sqlplus' in PATH - if not found, look for executable binary `sqlplus' in ORACLE_HOME/bin - if not found, look for executable binary `sqlplus' in the current directory Return full path of the binary. Return NULL if it doesn't exist or isn't executable.*/static char *stat_sqlplus(const char *orahome){ int status = 0; int mode; char *spath; struct stat buf; /* Check PATH for sqlplus binary. */ spath = search_exe("sqlplus"); if (!spath) { if (orahome) { /* Not found, check $ORACLE_HOME/bin. */ spath = malloc(strlen(orahome)+30); sprintf(spath, "%s/bin/sqlplus", orahome); status = stat(spath, &buf); if (!status) { mode = check_mode(buf.st_mode); if (!mode) spath = sfree(spath); } else spath = sfree(spath); } } if (!spath) { /* Check the current directory. */ spath = strdup("./sqlplus"); status = stat(spath, &buf); if (!status) { mode = check_mode(buf.st_mode); if (!mode) spath = sfree(spath); } else spath = sfree(spath); } return spath;}/* Read 'fname' into string.*/static char *read_file(const char *fname, char *line){ int status; int len; char *str = (char *) 0; char *xtr; struct stat buf; FILE *fptr; fptr = fopen(fname, "r"); if (fptr != (FILE *) 0) { status = stat(fname, &buf); if (status == 0) { str = malloc((buf.st_size+1)*sizeof(char)); if (str != (char *) 0) { xtr = str; while (fgets(line, MAX_LINE_LENGTH, fptr)) { len = strlen(line); memcpy(xtr, line, len); xtr += len; } fclose(fptr); *xtr = '\0'; } } } return str;}/* Extract basename of 'path'. Like basename() (not available on all platforms).*/static char *bname(char *path){ char *xtr; char *bname = (char *) 0; if (path && *path) { xtr = strrchr(path, '/'); if (xtr) { xtr++; bname = strdup(xtr); } else bname = strdup(path); } return bname;}/* Extract EDITOR values from 'str'. */static char **set_editor(char *str){ char *ptr; char *xtr; char **editor = (char **) 0; if (str && *str && (ptr = strrchr(str, '='))) { ptr++; ptr += strspn(ptr, " \""); xtr = strdup(ptr); ptr = strrchr(xtr, ';'); if (ptr) *ptr = '\0'; ptr = strrchr(xtr, '"'); if (ptr) *ptr = '\0'; /* We have the 'define _editor' string, now extract tokens. */ editor = str_tokenize(xtr, " "); /* Remove end-of-line. */ if ((ptr = strchr(editor[0], '\n'))) *ptr = '\0'; _editor = strdup(editor[0]); if (*editor[0] != '/') editor[0] = search_path(editor[0]); free(xtr); } return editor;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -