#include <stdio.h>
#include <stdlib.h>

/* header files for dblib */
#include "sqlfront.h"
#include "sqldb.h"

DBPROCESS *dbproc; 
LOGINREC  *login; 

int err_handler();
int msg_handler();

char x2c(char *what);
void unescape_url(char *url);
void plustospace(char *str);

main() {

  char line[512];
  DBINT len;
  RETCODE row_code;
  int  column_count;
  int  columnI;
  int  pos;

  /* initialize dblib */
  dbinit();  

  /* identify error and message handlers for dblib */
  dberrhandle( err_handler);
  dbmsghandle( msg_handler);

  /* login to SQL Server */
  login = dblogin();
  DBSETLUSER (login, "sa");
  DBSETLPWD(login, "");
  DBSETLAPP(login, "");
  dbproc = dbopen(login, "");

  /* use the pubs database */
  dbcmd(dbproc, "use pubs");
  dbsqlexec(dbproc);
  dbresults(dbproc);

  /* Grab the SQL statement entered by the user 
     from the standard input device. 
  */
  scanf( "%s", line);

  /* remove formatting */
  strcpy( line, &line[6]);
  plustospace(line);
  unescape_url(line);

  /* Print document header */
  printf("Content-type: text/html%c%c",10,10);
  printf("<H1>Query Results</H1>");
 
  /* Print SQL statement */
  printf( "command line = [%s]\n", line);
 
  /* place SQL statement in dblib command buffer */ 
  dbcmd(dbproc, line);

  /* send SQL statement to server */ 
  dbsqlexec(dbproc);

  /* check results */
  if (dbresults(dbproc) == SUCCEED) {
    column_count = dbnumcols(dbproc);

    /* print column names from result set */
    printf( "<PRE>");
    for (columnI = 0;columnI < column_count; columnI++) 
      printf( "%s ", dbcolname(dbproc, columnI + 1));
    printf( "\n");

	/* process each row in result set */
    while ((row_code = dbnextrow( dbproc)) != NO_MORE_ROWS) {
	  pos = 0;
 
      /* assemble line containing values for current row */
	  line[ 0] = '\0';
      for (columnI = 0;columnI < column_count; columnI++) {
        strncpy( 
          &line[ pos], (DBCHAR *)dbdata(dbproc, columnI + 1),
          (len = dbdatlen(dbproc, columnI + 1)));
		strcpy( &line[ pos + len], " | ");
		pos += len + 3;
	  }
	  line[ pos] = 0;

	  /*  print line */
      printf( "%s\n", line);
	  
	}
    printf( "</PRE>\n");
    printf( "<P>\n");
  }

  /*  close connection to server */
  dbclose(dbproc);
  dbexit();
  return(STDEXIT);
}

char x2c(char *what) {
  register char digit;

  digit = (what[0] >= 'A' ? ((what[0] & 0xdf) - 'A')+10 : (what[0] - '0'));
  digit *= 16;
  digit += (what[1] >= 'A' ? ((what[1] & 0xdf) - 'A')+10 : (what[1] - '0'));
  return(digit);
}

void unescape_url(char *url) {
  register int x,y;

  for(x=0,y=0;url[y];++x,++y) {
    if((url[x] = url[y]) == '%') {
      url[x] = x2c(&url[y+1]);
      y+=2;
    }
  }
  url[x] = '\0';
}

void plustospace(char *str) {
  /* replaces plus characters with spaces */
  register int x;

  for(x=0;str[x];x++) 
    if(str[x] == '+') str[x] = ' ';
}

int err_handler(dbproc, severity, dberr, oserr, dberrstr, oserrstr)
  DBPROCESS *dbproc;
  int severity;
  int dberr;
  int oserr;
  char *dberrstr;
  char *oserrstr;

  {
    printf("DB-LIBRARY error:\n\t%s\n", dberrstr);

    if (oserr != DBNOERR)
      printf("Operating-system error:\n\t%s\n", oserrstr);

    if ((dbproc == NULL) || (DBDEAD(dbproc)))
      return(INT_EXIT);

    return(INT_CANCEL);
  }

int msg_handler(dbproc, msgno, msgstate, severity, msgtext)
  DBPROCESS *dbproc;
  DBINT msgno;
  int msgstate;
  int severity;
  char *msgtext;
  {
    printf(
      "SQL Server message %ld, state %d, severity %d:\n\t%s\n",
      msgno, msgstate, severity, msgtext);
    return(0);
  }

