📄 gqlplus.c
字号:
if (*cname && strstr(cname, "------")) cflag = 1; } else { clen = strspn(cname, SPACETAB); cname += clen; clen = strcspn(cname, SPACETAB); columns[i] = malloc((clen+1)*sizeof(char)); memcpy(columns[i], cname, clen); (columns[i])[clen] = '\0'; tl2(columns[i]); i++; if (i >= capacity) { capacity += capacity; columns = realloc(columns, (capacity+1)*sizeof(char *)); for (j = i; j <= capacity; j++) columns[j] = (char *) 0; } } } return columns;}static char **get_column_names(char *tablename, char *owner, int fdin, int fdout, char *line){ int len; char *ccmd = (char *) 0; char *str = (char *) 0; char *prompt = (char *) 0; char **columns = (char **) 0; if (tablename) { len = strlen(DESCRIBE)+strlen(tablename)+4; if (owner) len += strlen(owner); ccmd = malloc(len*sizeof(char)); if (owner) sprintf(ccmd, "%s %s.%s\n", DESCRIBE, owner, tablename); else sprintf(ccmd, "%s %s\n", DESCRIBE, tablename); write(fdout, ccmd, strlen(ccmd)); prompt = get_sqlplus(fdin, line, &str); free(prompt); columns = parse_columns(str); free(str); free(ccmd); } return columns;}static int get_pagesize(int fdin, int fdout, char *line){ int pagesize; int len; char *str; char *xtr; write(fdout, PAGESIZE_CMD, strlen(PAGESIZE_CMD)); get_sqlplus(fdin, line, &str); xtr = strchr(str, ' ')+1; len = strspn(xtr, DIGITS); xtr[len] = '\0'; pagesize = atoi(xtr); free(str); return pagesize;}/* Extract table names from 'str', where 'str' is the string representation of the results of SELECT_TABLES query. If 'complete_columns' is 1, get column names as well.*/static struct table *get_names(char *str, int fdin, int fdout, int pagesize, char *line){ int i; int j; int idx; int capacity; char *tname; char *ltr; char **toks; char **tokens; struct table *tables = NULL; FILE *fptr; /*fptr = fopen("gqlplus.log", "a");*/ fptr = (FILE *) 0; if (fptr) { fprintf(fptr, "str:`%s'\n", str); fprintf(fptr, "pagesize: %d\n", pagesize); } capacity = INIT_NUM_TABLES; tables = calloc(capacity+1, sizeof(struct table)); toks = str_tokenize(str, "\n"); idx = 0; if (pagesize > 0) { idx = 1; ltr = (char *) 0; } else ltr = str; i = 0; while ((tname = toks[idx])) { idx++; ltr = (char *) 0; if (*tname && strcmp(tname, "TABLE_NAME") && strcmp(tname, "VIEW_NAME") && !strstr(tname, "------") && !strstr(tname, "rows selected")) { tokens = str_tokenize(tname, " \t"); if (fptr) { if (tname) fprintf(fptr, "tname:\n%s\n", tname); if (tokens[0]) fprintf(fptr, "tokens[0]: `%s'\n", tokens[0]); if (tokens[1]) fprintf(fptr, "tokens[1]: `%s'\n", tokens[1]); } if (tokens[0]) { tables[i].name = strdup(tokens[0]); tl2(tables[i].name); } if (tokens[1]) { tables[i].owner = strdup(tokens[1]); tl2(tables[i].owner); } str_free(tokens); if (complete_columns == 1) tables[i].columns = get_column_names(tables[i].name, tables[i].owner, fdin, fdout, line); i++; } if (i >= capacity) { capacity += capacity; tables = realloc(tables, (capacity+1)*sizeof(struct table)); for (j = i; j <= capacity; j++) { tables[j].name = (char *) 0; tables[j].owner = (char *) 0; tables[j].columns = (char **) 0; } } } if (fptr) fclose(fptr); return tables;}/* Get the list of all tables and views for this user. If 'complete_columns' is 1, get all column names as well.*/static struct table *get_completion_names(int fdin, int fdout, char *line){ int pagesize; char *str; char *ccmd; struct table *tables; str = (char *) 0; tables = (struct table *) 0; pagesize = get_pagesize(fdin, fdout, line); ccmd = malloc((strlen(SELECT_TABLES_1)+strlen(SELECT_TABLES_2)+1)*sizeof(char)); sprintf(ccmd, "%s%s", SELECT_TABLES_1, SELECT_TABLES_2); write(fdout, ccmd, strlen(ccmd)); get_sqlplus(fdin, line, &str); /* kehlet: ORA- error is likely because the database isn't open */ if (!strstr(str, "ORA-")) { tables = get_names(str, fdin, fdout, pagesize, line); } free(str); write(fdout, DEL_CMD, strlen(DEL_CMD)); get_sqlplus(fdin, line, &str); free(ccmd); return tables;}/* Generator function for table/column name completion. STATE lets us know whether to start from scratch; without any state (i.e. STATE == 0), then we start at the top of the list.*/char *tablecolumn_generator(const char *text, int state){ static int table_index; static int len; static int column_index; char *ltext; char *name; char *cname; /* If this is a new word to complete, initialize now. This includes saving the length of TEXT for efficiency, and initializing the index variable to 0. */ if (!state) { table_index = 0; column_index = 0; len = strlen (text); } ltext = tl((char *) text); /* Return the next name which partially matches from the command list. */ while ((name = tables[table_index].name)) { table_index++; if (strncmp(name, ltext, len) == 0) { free(ltext); return (strdup(name)); } /* Table name did not match. Try column names: */ else if (complete_columns == 1) { while ((cname = tables[table_index-1].columns[column_index])) { column_index++; if (strncmp(cname, ltext, len) == 0) { table_index--; free(ltext); return (strdup(cname)); } } column_index = 0; } } free(ltext); /* If no names matched, then return NULL. */ return ((char *) 0);}/* Detect gqlplus-specific commmand-line switch `sw'.*/static int gqlplus_switch(char **argv, char *sw){ int i = 0; int carg = 0; int index = -1; while (argv[i]) { carg++; if (!strcmp(argv[i], sw)) index = i; i++; } if (index != -1) { for (i = index; i < carg; i++) argv[i] = argv[i+1]; carg--; argv[carg] = (char *) 0; } return carg;}static int install_completion(char *line, int *all_tables){ int completion_names = 0; rl_completion_entry_function = tablecolumn_generator; if (progress == 1) { if (complete_columns == 1) printf("gqlplus: scanning tables and columns...\n"); else printf("gqlplus: scanning tables...\n"); } tables = get_completion_names(fds2[0], fds1[1], line); if (tables) completion_names = 1; else { /* Something's wrong - we can't read or parse ALL_TABLES. Abandon tablename completion. But warn the user. */ fprintf(stderr, "Warning: couldn't query or parse ALL_TABLES or ALL_VIEWS. Tablename completion disabled.\n"); *all_tables = 0; } return completion_names;}/* Return the shell command (the argument of '!' or 'HO' SQLPLUS commands).*/static char *get_shellcmd(char *lline){ int len; char *shellcmd = (char *) 0; char *xtr; if (lline[0] == '!') { if (lline[1] == '\0') shellcmd = getenv("SHELL"); else shellcmd = &lline[1]; } else if (!strncmp(lline, HOST_CMD, strlen(HOST_CMD))) { xtr = lline; len = strcspn(lline, " "); xtr += len; len = strspn(xtr, " "); xtr += len; if (strlen(xtr) != 0) shellcmd = xtr; else shellcmd = getenv("SHELL"); } return shellcmd;}/* Check if we have the complete connect string on the command line.*/static char *get_connect_string(int argc, char **argv){ int i; int done = 0; char *str; char *sid; char *connect_string = (char *) 0; sid = getenv(ORACLE_SID); for (i = 1; (i < argc) && (done == 0); i++) { str = argv[i]; if ((str[0] != '-') && (str[0] != '@')) { if (strchr(str, '/')) { if (strchr(str, '@')) connect_string = strdup(str); else if (sid != (char *) 0) { connect_string = malloc(strlen(str)+strlen(sid)+2); sprintf(connect_string, "%s@%s", str, sid); } } else username = strdup(str); } } return connect_string;}/* Build connect string from username, password, ORACLE_SID.*/static char *build_connect_string(char *user, char *password){ char *connect_string = (char *) 0; char *sid; char **tokens; sid = getenv(ORACLE_SID); if (strchr(user, '@')) { if (strchr(user, '/')) connect_string = strdup(user); else if ((password != (char *) 0)) { tokens = str_tokenize(user, "@"); connect_string = malloc(strlen(user)+strlen(password)+3); sprintf(connect_string, "%s/%s@%s", tokens[0], password, tokens[1]); str_free(tokens); } } else if (password && (strchr(password, '@'))) { connect_string = malloc(strlen(user)+strlen(password)+3); sprintf(connect_string, "%s/%s", user, password); } else { if (sid != (char *) 0) { if (strchr(user, '/')) { connect_string = malloc(strlen(user)+strlen(sid)+2); sprintf(connect_string, "%s@%s", user, sid); } else if (password != (char *) 0) { connect_string = malloc(strlen(user)+strlen(password)+strlen(sid)+3); sprintf(connect_string, "%s/%s@%s", user, password, sid); } } } return connect_string;}/* Call sqlplus to extract the initial sqlplus prompt. This is needed in case a user has a (g)login.sql file which redefines the standard prompt.*/static char *get_sql_prompt(char *old_prompt, char *sqlplus, char *connect_string, char *line, int *status){ int len; char *sqlprompt = (char *) 0; char *tmpname; char *cmd; char *xtr; char *ptr; *status = 0; if (connect_string) { tmpname = tmpnam((char *) 0); cmd = malloc(strlen(GET_PROMPT)+strlen(TAIL_PROMPT)+strlen(sqlplus)+strlen(connect_string)+strlen(tmpname)+20); sprintf(cmd, "%s%s -s %s %s > %s", GET_PROMPT, sqlplus, connect_string, TAIL_PROMPT, tmpname); /*printf("cmd: `%s'\n", cmd);*/ *status = system(cmd); if (!*status) { free(cmd); xtr = read_file(tmpname, line); unlink(tmpname); /* Get the last line. */ xtr = strstr(xtr, SQLPROMPT); if (xtr) { if (!strcmp(xtr, "\n") || strncmp(xtr, SQLPROMPT, strlen(SQLPROMPT))) sqlprompt = old_prompt; else { /* Is this user using (g)login.sql? And if so, is she setting sqlprompt? */ ptr = strchr(xtr, '"'); ptr++; len = strcspn(ptr, "\""); sqlprompt = malloc(len+1); memcpy(sqlprompt, ptr, len); sqlprompt[len] = '\0'; } } } } return sqlprompt;}static void usage(int argc, char **argv){ int i; int done; done = 0; for (i = 0; (i < argc) && !done; i++) if (!strcmp(argv[i], "-h")) { done = 1; printf("\ngqlplus version %s; usage: gqlplus [sqlplus_options] [-h] [-d] [-p]\n", VERSION); printf(" \"-h\" this messsage\n"); printf(" \"-d\" disable column name completion\n"); printf(" \"-p\" show progress report and elapsed time\n"); printf(" SQL> %sr: rescan tables (for completion)\n", szCmdPrefix); printf(" SQL> %sh: display command history\n", szCmdPrefix); printf("To kill the program, use SIGQUIT (Ctrl-\\)\n"); }}static char *str_expand(char *str, int *capacity, int length, int extension){ int new_length; char *xstr; xstr = str; new_length = length+extension; if (new_length > *capacity) { while (*capacity <= new_length) *capacity += *capacity; xstr = realloc(str, *capacity+1); } return xstr;}static void get_final_sqlplus(int fdin){ int flags; int result; int capaci
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -