/*---------------------------------------------------------------- * * exec_sql_main.c * A direct/embedded SQL bash built-in command for postgreSQL. * This routine is called by "exec_sql.def". * * Change logs * 2000.03.22: Add 'encoding' at list_AllconnectDB(). * 2000.03.23: Move printVersion(),printConnect() to "sql_connect.c". * Change pset-db to pset->dbset->db. * 2000.04.21: Change COPY statement to EXEC_SQL -y "COPY .." * 2000.05.10: Add WITH NULL AS 'X' to COPY statement. * 2001.04.10: Modify the style of exec_sql_main(). * 2001.04.15: Delete exec_sql_example[]. * 2001.04.15: Add set_exec_sql_options() call. * 2001.04.15: Fix execCopy(). * 2001.04.15: Delete set_connection/disconnect message. * 2001.04.15: Add lo_import/lo_export/lo_unlink. * 2001.06.11: Add SQL_WORD(SQL reserved word) shell variable. * 2001.06.11: Add 'normal_option_end:' label. * 2001.06.11: Add EXEC_SQL_OPTION struct. * 2001.11.24: Add sigsetjmp(),siglongjmp() to cancell query. * 2001.11.26: Add SQL_HELP version. * * *---------------------------------------------------------------- * This software is copyrighted by SAKAIDA Masaaki - Osaka,Japan. * The author hereby grants permission to use, copy, modify, * distribute, and license this software and its documentation * for any purpose, provided that existing copyright notices are * retained in all copies and that this notice is included * verbatim in any distributions. No written agreement, license, * or royalty fee is required for any of the authorized uses. * Modifications to this software may be copyrighted by their * author and need not follow the licensing terms described * here, provided that the new terms are clearly indicated on * the first page of each file where they apply. * IN NO EVENT SHALL THE AUTHOR OR DISTRIBUTORS BE LIABLE TO ANY * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR * CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS * SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF, EVEN * IF THE AUTHOR HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. * THE AUTHOR AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON * AN "AS IS" BASIS, AND THE AUTHOR AND DISTRIBUTORS HAVE NO * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, * ENHANCEMENTS, OR MODIFICATIONS. *----------------------------------------------------------------- */ #include #include #include #include #include #include #include "libpq-fe.h" #include "exec_sql.h" #include "sql_connect.h" #include "sql_copy.h" #include "sql_set.h" #include "psql_sub.h" #include "utils.h" #include "sql_errno.h" #include "sql_help.h" #include "version.h" #ifdef __CYGWIN32__ #include #endif #define SQL_WORD "SQL_WORD" /* the shell variable name of SQL reserved word.*/ #define SQL_WORD_LEN 16 #define DEFAULT_FIELD_SEP "|" #define TAB_FIELD_SEP_STRING "\\t" #define TAB_FIELD_SEP "\t" #define DEFAULT_NULL_STRING " " #define DEFAULT_ZERO_STRING " " #define COPY_FIELD_SEP "\t" /*SEPARATOR of COPY command*/ #define COPY_NULL_STRING "\\N" /*NULL string of COPY command*/ #define COPY_ZERO_STRING "" /*ZERO string of COPY command*/ /*------------------------------------------------------------------ * Functions list *------------------------------------------------------------------ *extern int exec_sql_main(Option * option, char *singleQuery); */ static void initPSconnSet(char *singleQuery,Option *option, EXEC_SQL_OPTION *saved_option, PSconnSet *pset); static int execCopy(PSconnSet *pset, char *singleQuery, FILE *fp, char*copy_query); static void usage(FILE * fout, char *optarg); static void printHelp(FILE * fout, char *topic); static void printStatusSHELLvar(FILE * fout); static void safe_write_stderr(const char *s); static void handle_sigint(int sig); static int bind_SQLCA(SQLCA * sqlca); static int print_SQLCA(FILE *fout); static void get_sql_word(char *singleQuery, char *sql_word); /*------------------------------------------------------------------ * Cancel connection pointer. (connection to try cancel on) *----------------------------------------------------------------*/ static PGconn *cancelConn = NULL; /*------------------------------------------------------------------ * SQLCA variables visible to the programs. *----------------------------------------------------------------*/ static struct sqlca sqlca_init = { {'S', 'Q', 'L', 'C', 'A', ' ', ' ', ' '}, sizeof(struct sqlca), 0, {0, {0}}, {'N', 'O', 'T', ' ', 'S', 'E', 'T', ' '}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0}, }; static struct sqlca sqlca = { {'S', 'Q', 'L', 'C', 'A', ' ', ' ', ' '}, sizeof(struct sqlca), 0, {0, {0}}, {'N', 'O', 'T', ' ', 'S', 'E', 'T', ' '}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0}, }; /* * ################################################################# * The exec_sql main routine for PostgreSQL. * ################################################################# */ static sigjmp_buf exec_sql_main_jump; int exec_sql_main(Option * option, char *singleQuery) /**************************************************************** * The exec_sql main routine for PostgreSQL. * * return code * r= 0 : normal end * r= -1 : error ****************************************************************/ { EXEC_SQL_OPTION *saved_option; PSconnSet pset; /* Setting for D/B access */ char target_name[TARGET_NAME_MAXLEN]; char connect_name[CONNECT_NAME_MAXLEN]; char user_name[USER_NAME_MAXLEN]; char passwd[PASSWD_MAXLEN]; char sql_word[SQL_WORD_LEN]; int ret; bool success = true; /*------------------------------------------------------- * initial set. *------------------------------------------------------- */ memset(&pset, 0, sizeof(PSconnSet)); saved_option = get_exec_sql_options(); initPSconnSet(singleQuery, option, saved_option, &pset ); sql_word[0] = '\0'; /*------------------------------------------------------- * Interactive defaults(cntl-C=>cancel) - *------------------------------------------------------- */ if (!isatty(0) || !isatty(1)) pset.notty = 1; /* Noninteractive */ else signal(SIGINT, handle_sigint); /****************************************************************** * Return from siglongjmp() of handle_sigint(). ******************************************************************/ if (sigsetjmp(exec_sql_main_jump,1) == 0 ) { /* * ===================================================== * HELP (or Usage) * ===================================================== */ if (option->hflg.flg) { usage(pset.fout, (char *) option->hflg.opt); goto normal_option_end; } /* * ===================================================== * display VERSION * ===================================================== */ if (option->vflg) { fprintf(pset.fout, "# %s %s\n", pgbash_version_string(), get_CGI_BR()); goto normal_option_end; } /* * ===================================================== * print SQL status * ===================================================== */ if (option->sflg && singleQuery == NULL) { printStatusSHELLvar(pset.fout); goto normal_option_end; } /* * ===================================================== * list all connected databases. * ===================================================== */ if (option->mflg) { int encoding; if(pset.dbset == NULL) encoding = 0; else encoding = pset.dbset->encoding; list_AllconnectDB(pset.fout, &(pset.opt), encoding); goto normal_option_end; } /* * ===================================================== * Set EXEC_SQL options * ===================================================== */ ret = set_exec_sql_options(&pset, singleQuery); if (ret == 0) { strcpy(sql_word, "SET"); goto normal_option_end; } else if(ret < -1) goto syntax_error; /* *------------------------------------------------------ * clear SQLCA for executing SQL. *------------------------------------------------------ */ memcpy((char *) &sqlca, (char *) &sqlca_init, sizeof(sqlca)); bind_SQLCA(pset.sqlca); /* * ===================================================== * Connect to Database * ===================================================== */ ret = parse_connect(&pset, singleQuery, target_name, connect_name, user_name, passwd); if (ret == 0) { strcpy(sql_word, "CONNECT"); if (exec_connect(&pset, target_name, connect_name, user_name, passwd) == 0) goto normal_end; else goto exec_error; } else if (ret < -1) goto syntax_error; /* * ===================================================== * DisConnect connect-name * ===================================================== */ ret = parse_disconnect(&pset, singleQuery, connect_name); if (ret == 0) { strcpy(sql_word, "DISCONNECT"); if (exec_disconnect(&pset, connect_name) == 0) { if (!pset.quiet && !pset.notty) fprintf(pset.fout, "# DISCONNECT %s%s\n", connect_name, get_CGI_BR()); goto normal_end; } else goto exec_error; } else if (ret < -1) goto syntax_error; /* * ===================================================== * Set Connection connect_name * ===================================================== */ ret = parse_set_connection(&pset, singleQuery, connect_name); if (ret == 0) { strcpy(sql_word, "SET"); if (exec_set_connection(&pset, connect_name) == 0) { if (!pset.quiet && !pset.notty) fprintf(pset.fout, "# SET CONNECTION %s%s\n", connect_name, get_CGI_BR()); goto normal_end; } else goto exec_error; } else if (ret < -1) goto syntax_error; /* ******************************************************* * Connect to Database automatically ******************************************************* */ if (psconninfo.maxno == 0) { parse_connect(&pset, "connect to default", target_name, connect_name, user_name, passwd); if (exec_connect(&pset, target_name, connect_name, user_name, passwd) != 0) goto exec_error; } /* ******************************************************* * check CURRENT connection ******************************************************* */ if (psconninfo.currentp != 0) { pset.dbset = psconninfo.currentp->dbset; cancelConn = pset.dbset->db; } else { setSQLCA(pset.sqlca, SQL_CONNECT_ERROR, "Error: Current database not found. ", 0, 0); goto exec_error; } /* * ===================================================== * '-d'option (set connection) * ===================================================== */ if (option->dflg.flg) { PSconnList *work = psconninfo.currentp; if (strUcmp(option->dflg.opt, "DEFAULT", strlen(option->dflg.opt)) == 0) ret = exec_set_connection(&pset, DEFAULT_VALUE); else ret = exec_set_connection(&pset, option->dflg.opt); if (ret == 0) { pset.dbset = psconninfo.currentp->dbset; cancelConn = pset.dbset->db; psconninfo.currentp = work; wrap_bind_char_variable(POSTGRESQL_VERSION, work->dbset->ver_no); } else goto exec_error; } /* * ===================================================== * "Copy TABLE()" client_side_copy statement * ===================================================== */ if ( singleQuery && strUcmp(singleQuery, "COPY", 4) == 0) { FILE *fp = NULL; char *copy_query = NULL; char delim[2]; char nullstring[16]; ret = parse_copy(&pset, singleQuery, ©_query, &fp, delim, nullstring); if (ret == 0) { strcpy(sql_word, "COPY"); pset.opt.fieldSep = delim; if (nullstring[0] != '\0') pset.opt.nullstr = nullstring; if(execCopy(&pset, singleQuery, fp,copy_query)==0) goto normal_end; else goto exec_error; } else if (ret < -1) goto syntax_error; } /* * ===================================================== * execute program(e.g. lo_export) * * option->xflg.opt : prog_name (e.g. "lo_export") * singleQuery : parameters.(e.g. "12345,'/tmp/test.dat'") * ===================================================== */ if (option->xflg.flg && option->xflg.opt && singleQuery) { ret = lo_exec(&pset, option->xflg.opt, singleQuery); if (ret == 0) { strcpy(sql_word, "LARGE_OBJECT"); goto normal_end; } else if (ret < -1) goto syntax_error; } /* * ===================================================== * send Query and execute Query * ===================================================== */ if (singleQuery) { if (SendQuery(&pset, singleQuery)) { get_sql_word(singleQuery, sql_word); goto normal_end; } else goto exec_error; } /* * ===================================================== * The end of process. * ===================================================== */ syntax_error: /*------------ display Syntax Error Message --------------*/ if (!pset.quiet) printSQLerror(pset.fout, pset.sqlca); exec_error: success = false; normal_end: /*------------ write shell variables. --------------------*/ bind_SQLCA(pset.sqlca); wrap_bind_char_variable(SQL_WORD, sql_word); if (option->sflg && singleQuery != NULL) printStatusSHELLvar(pset.fout); } /*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< end of sigsetjmp() <<<<<<*/ /******************************************************************/ normal_option_end: /*-------------- set signal default ----------------------*/ signal(SIGINT,SIG_DFL); if (success) return (0); else return (-1); } /* * ################################################################# * The local subroutines for exec_sql. * ################################################################# */ static void initPSconnSet(char *singleQuery, Option *option, EXEC_SQL_OPTION *saved_option, PSconnSet *pset) { /*------------------------------------------------------- * initial set. *------------------------------------------------------- */ pset->fout = stdout; pset->sqlca = &sqlca; /*------------ print form --------------*/ pset->opt.html3 = 0; pset->opt.align = 1; pset->opt.header = 1; pset->opt.rowcount = 1; pset->opt.caption = NULL; pset->opt.outerframe = 0; pset->opt.fieldSep= DEFAULT_FIELD_SEP; pset->opt.nullstr = DEFAULT_NULL_STRING; pset->opt.zerostr = DEFAULT_ZERO_STRING; pset->opt.table_tag = NULL; pset->opt.header_tr = saved_option->header_tr; pset->opt.header_th = saved_option->header_th; pset->opt.body_tag = saved_option->body_tag; pset->opt.input_tag = saved_option->input_tag; pset->opt.input_size = saved_option->input_size; pset->opt.nFields = 0; pset->opt.nTups = 0; pset->opt.fieldName = NULL; pset->opt.fieldValue = NULL; pset->opt.fieldMax = NULL; pset->opt.fieldNotNum = NULL; /*----- echo query sent to backend ------*/ if (option->eflg) pset->echoQuery = 1; /*------------ run quietly --------------*/ if (option->qflg) pset->quiet = 1; /*-------- print format options ---------*/ if (option->Hflg)/* HTML table output */ pset->opt.html3 = 1; if (option->Xflg) /* expanded output */ pset->opt.expanded = 1; if (option->Cflg.flg) /* Caption */ pset->opt.caption = option->Cflg.opt; if (option->Oflg.flg) /* Table_TAG option */ pset->opt.table_tag = option->Oflg.opt; if (option->Qflg.flg) /* Header tag */ pset->opt.header_tr = option->Qflg.opt; if (option->Rflg.flg) /* Header tag */ pset->opt.header_th = option->Rflg.opt; if (option->Dflg.flg) /* Body tag */ pset->opt.body_tag = option->Dflg.opt; if (option->Iflg) /* Body tag */ pset->opt.input_tag = option->Iflg; if (option->Lflg) /* tern on printing of outer frame */ pset->opt.outerframe = 1; if (option->Tflg) /* tern off printing of header */ pset->opt.header = 0; if (option->Bflg) /* tern off printing of row count */ pset->opt.rowcount = 0; if (option->Aflg) /* tern off alignment */ pset->opt.align = 0; /*------------- COPY TABLE() mode ----------*/ if ( singleQuery && strUcmp(singleQuery, "COPY", 4) == 0) { pset->opt.html3 = 0; pset->opt.expanded = 0; pset->opt.caption = NULL; pset->opt.table_tag = NULL; pset->opt.header_tr = NULL; pset->opt.header_th = NULL; pset->opt.body_tag = NULL; pset->opt.outerframe = 0; pset->opt.header = 0; pset->opt.rowcount = 0; pset->opt.align = 0; pset->opt.fieldSep = COPY_FIELD_SEP; pset->opt.nullstr = COPY_NULL_STRING; pset->opt.zerostr = COPY_ZERO_STRING; } if (option->Sflg.flg) /* set the field separator */ { pset->opt.fieldSep = option->Sflg.opt; if (strcmp(option->Sflg.opt, TAB_FIELD_SEP_STRING) == 0) pset->opt.fieldSep = TAB_FIELD_SEP; } if (option->Nflg.flg) /* set NULL string */ pset->opt.nullstr = option->Nflg.opt; if (option->Zflg.flg) /* set ZERO string */ pset->opt.zerostr = option->Zflg.opt; } static int execCopy(PSconnSet *pset, char *singleQuery, FILE *fp, char *copy_query) /****************************************************************** * execute COPY statement * * return=0 : normal * =-1: syntax error * =-2: exec error *****************************************************************/ { int ret = 0; /*----------------- COPY from ------------------------*/ if (strncmp(copy_query, "insert", 6) == 0) { if(exec_copy_insert(pset, copy_query, false, fp) < 0) ret = -2; } /*----------------- COPY to --------------------------*/ else if (strncmp(copy_query, "select", 6) == 0) { if(exec_copy_select(pset, copy_query, fp) < 0) ret = -2; } /*---------------- end process ------------------------*/ if (copy_query != NULL) free(copy_query); if (fp != NULL && fp != stdin && fp != stdout) fclose(fp); return(ret); } static void usage(FILE * fout, char *optarg) /******************************************************************* * The usage for the application program. *******************************************************************/ { int i; /*------------ display usage ----------------*/ if (optarg == NULL || optarg[0] == '\0') { fprintf(fout, "# HELP: 'help exec_sql'%s\n", get_CGI_BR()); } else /*------------ help options ------------------*/ if (strUcmp(optarg, "OP", 2) == 0) /* OPTION */ { if (get_Content_type() == 1) fprintf(fout, "
");

		i = 0;
		fprintf(fout, "# Exec_sql options:\n");
		while (exec_sql_doc[i] != NULL)
			fprintf(fout, "    %s\n", exec_sql_doc[i++]);

		if (get_Content_type() == 1)
			fprintf(fout, "
"); } else /*------------ help err code -----------------*/ if (strUcmp(optarg, "ER", 2) == 0) /* OPTION */ { if (get_Content_type() == 1) fprintf(fout, "
");

		fprintf(fout, "# SQL error code:\n");
		for (i = 0; i < 100; i++)
		{
			if (exec_sql_code[i].name == NULL)
				break;

			fprintf(fout, "    %-22.22s : %4d : %s \n",
				exec_sql_code[i].name, exec_sql_code[i].code, exec_sql_code[i].comment);
		}

		if (get_Content_type() == 1)
			fprintf(fout, "
"); } else /*------------ help Commands Name ------------*/ if (strUcmp(optarg, "HE", 2) == 0) /* HELP */ printHelp(fout, "HE"); else /*------------ help SQLs or all --------------*/ if (strUcmp(optarg, "AL", 2) == 0) /* ALL */ printHelp(fout, "AL"); else /*------------ help item --------------------*/ { printHelp(fout, optarg); } return; } static void printHelp(FILE * fout, char *topic) /******************************************************************* * HELP statement is displayed. *******************************************************************/ { int i; bool help_found; help_found = false; /*-------------- Commands Name List ----------------*/ if (strUcmp(topic, "HE", 2) == 0) /* HELP */ { char left_center_right; int i; if (get_Content_type() == 1) fprintf(fout, "
");

		fprintf(fout, "# HELP: Command Name List:\n");

		left_center_right = 'L';	/* Start with left column */
		i = 0;

		while (QL_HELP[i].cmd != NULL)
		{
			switch (left_center_right)
			{
			case 'L':
				fprintf(fout, "    %-26s", QL_HELP[i].cmd);
				left_center_right = 'C';
				break;
			case 'C':
				fprintf(fout, "%-26s", QL_HELP[i].cmd);
				left_center_right = 'R';
				break;
			case 'R':
				fprintf(fout, "%-25s\n", QL_HELP[i].cmd);
				left_center_right = 'L';
				break;
			}
			i++;
		}

		if (left_center_right != 'L')
			fprintf(fout, "\n");

		if (get_Content_type() == 1)
			fprintf(fout, "
");

	for (i = 0; QL_HELP[i].cmd; i++)
	{
		if (strcasecmp(QL_HELP[i].cmd, topic) == 0 ||
		    strUcmp(topic, "AL", 2) == 0)
		{
			help_found = true;
			fprintf(fout, "# (%s) SQL command: %s\n", 
					SQLHELP_VERSION, QL_HELP[i].cmd);
			fprintf(fout, "  Description: %s\n", QL_HELP[i].help);
			fprintf(fout, "  Syntax :\n");
			fprintf(fout, "%s\n", QL_HELP[i].syntax);
			fprintf(fout, "\n");
		}
	}

	if (get_Content_type() == 1)
		fprintf(fout, "
"); /*--------------- Help command error ------------------*/ if (!help_found) fprintf(get_Ferr(), "> Error: help command(%s) not found.%s%s\n", topic, EXEC_SQL_USAGE, get_CGI_BR()); } static void printStatusSHELLvar(FILE * fout) /******************************************************************* * print SQL status of bash shell variable. ******************************************************************/ { if (get_Content_type() == 1) fprintf(fout, "
");

	fprintf(fout, "# Status after executing SQL\n");

	print_SQLCA(fout);

	if (get_Content_type() == 1)
		fprintf(fout, "
"); } static void safe_write_stderr(const char *s) /******************************************************************* * A safe output. *******************************************************************/ { char *buf; if (get_Content_type() == 1) { buf = wrapMalloc(strlen(s) + 5); strcpy(buf, s); strcat(buf, get_CGI_BR()); } else buf = (char *) s; #ifdef WIN32 fputs(buf, get_Ferr()); #else write(fileno(get_Ferr()), buf, strlen(buf)); #endif if (get_Content_type() == 1) free(buf); } static void handle_sigint(int sig) /******************************************************************* * signal handler routine. (Interactive mode only) *******************************************************************/ { /*----- accept signal if no connection -----*/ if (cancelConn == NULL) { safe_write_stderr("\n>>> CANCEL request >>> \n"); } /*----- Try to send cancel request ---------*/ else if (PQrequestCancel(cancelConn)) { safe_write_stderr("\n>>> CANCEL request sent >>>\n"); } else { safe_write_stderr("\n>>> CANCEL request >>> \n"); safe_write_stderr("Cannot send cancel request:\n"); safe_write_stderr(PQerrorMessage(cancelConn)); } siglongjmp(exec_sql_main_jump,1); /*>>>> go to exec_sql_main >>>>*/ } static int bind_SQLCA(SQLCA * sqlca) /******************************************************************* * bind SQLCA variables. *******************************************************************/ { if (wrap_bind_int_variable(SQLCODE, (int) sqlca->sqlcode) < 0) return (-1); if (wrap_bind_int_variable(SQLERRML, (int) sqlca->sqlerrm.sqlerrml) < 0) return (-1); if (wrap_bind_char_variable(SQLERRMC, sqlca->sqlerrm.sqlerrmc) < 0) return (-1); if (wrap_bind_int_variable(SQLERRD2, (int) sqlca->sqlerrd[2]) < 0) return (-1); if (wrap_bind_int_variable(SQLNTUPLE, (int) sqlca->sqlerrd[2]) < 0) return (-1); if (wrap_bind_int_variable(SQLERRD3, (int) sqlca->sqlerrd[3]) < 0) return (-1); if (wrap_bind_int_variable(SQLNFIELD, (int) sqlca->sqlerrd[3]) < 0) return (-1); return (0); } static int print_SQLCA(FILE *fout) /******************************************************************* * print SQLCA shell variables. *******************************************************************/ { char value[256]; if (wrap_find_variable(SQLOID, value) == 0 && value[0] != '\0') fprintf(fout, " %-9.9s = %-10.10s(OID of recent insert)\n", SQLOID, value); if (wrap_find_variable(SQLCODE, value) == 0) fprintf(fout, " %-9.9s = %-10.10s(SQL error code)\n", SQLCODE, value); if (wrap_find_variable(SQLNTUPLE, value) == 0) fprintf(fout, " %-9.9s = %-10.10s(number of tuples)\n", SQLNTUPLE, value); if (wrap_find_variable(SQLNFIELD, value) == 0) fprintf(fout, " %-9.9s = %-10.10s(number of fields)\n", SQLNFIELD, value); if (wrap_find_variable(SQLERRML, value) == 0) fprintf(fout, " %-9.9s = %-10.10s(length of SQLERRMC)\n", SQLERRML, value); if (wrap_find_variable(SQLERRMC, value) == 0) fprintf(fout, " %-9.9s = %s\n", SQLERRMC, value); return(0); } static void get_sql_word(char *singleQuery, char *sql_word) { char *p; strncpy(sql_word, singleQuery, SQL_WORD_LEN-1); sql_word[SQL_WORD_LEN-1]='\0'; if ( (p=strchr(sql_word,' ')) != NULL ) *p = '\0'; p=sql_word; while(*p) { *p = toupper(*p); p++; } }