void QgsAuthSslImportDialog::socketEncrypted()
{
  QgsDebugMsg( "socketEncrypted entered" );
  if ( !mSocket )
    return;  // might have disconnected already

  appendString( tr( "Socket ENCRYPTED" ) );

  appendString( QStringLiteral( "%1: %2" ).arg( tr( "Protocol" ),
                QgsAuthCertUtils::getSslProtocolName( mSocket->protocol() ) ) );

  QSslCipher ciph = mSocket->sessionCipher();
  QString cipher = QStringLiteral( "%1: %2, %3 (%4/%5)" )
                   .arg( tr( "Session cipher" ), ciph.authenticationMethod(), ciph.name() )
                   .arg( ciph.usedBits() ).arg( ciph.supportedBits() );
  appendString( cipher );



  wdgtSslConfig->setEnabled( true );
  QString hostport( QStringLiteral( "%1:%2" ).arg( mSocket->peerName() ).arg( mSocket->peerPort() ) );
  wdgtSslConfig->setSslCertificate( mSocket->peerCertificate(), hostport.trimmed() );
  if ( !mSslErrors.isEmpty() )
  {
    wdgtSslConfig->appendSslIgnoreErrors( mSslErrors );
    mSslErrors.clear();
  }

//  checkCanSave();

  // must come after last state change, or gets reverted
  leServer->setStyleSheet( QgsAuthGuiUtils::greenTextStyleSheet() );

  destroySocket();
}
Example #2
0
int
tcp_connect(char *host, char *serv)
{
    struct sockaddr_in sin;
    int sock;

    if (!hostport(serv, &sin)) {
	fprintf(stderr, "Can't resolve Empire port %s\n", serv);
	exit(1);
    }
    if (!hostaddr(host, &sin)) {
	fprintf(stderr, "Can't resolve Empire host %s\n", host);
	exit(1);
    }
    if ((sock = hostconnect(&sin)) < 0) {
	fprintf(stderr, "Can't connect to %s:%s: %s\n",
		serv, host, strerror(errno));
	exit(1);
    }
    return sock;
}
Example #3
0
static CConn_IOStream::TConn_Pair
s_SocketConnectorBuilder(const SConnNetInfo* net_info,
                         const STimeout*     timeout,
                         const void*         data,
                         size_t              size,
                         TSOCK_Flags         flags)
{
    EIO_Status status = eIO_Success;
    bool       proxy = false;
    SOCK       sock = 0;

    _ASSERT(net_info);
    if ((flags & (fSOCK_LogOn | fSOCK_LogDefault)) == fSOCK_LogDefault
        &&  net_info->debug_printout == eDebugPrintout_Data) {
        flags &= ~fSOCK_LogDefault;
        flags |=  fSOCK_LogOn;
    }
    if (*net_info->http_proxy_host  &&  net_info->http_proxy_port) {
        status = HTTP_CreateTunnel(net_info, fHTTP_NoAutoRetry, &sock);
        _ASSERT(!sock ^ !(status != eIO_Success));
        if (status == eIO_Success
            &&  ((flags & ~(fSOCK_LogOn | fSOCK_LogDefault))  ||  size)) {
            SOCK s;
            status = SOCK_CreateOnTopEx(sock, 0, &s,
                                        data, size, flags);
            _ASSERT(!s ^ !(status != eIO_Success));
            SOCK_Destroy(sock);
            sock = s;
        }
        proxy = true;
    }
    if (!sock  &&  (!proxy  ||  net_info->http_proxy_leak)) {
        const char* host = (net_info->firewall  &&  *net_info->proxy_host
                            ? net_info->proxy_host : net_info->host);
        if (timeout == kDefaultTimeout)
            timeout  = net_info->timeout;
        if (!proxy  &&  net_info->debug_printout) {
            SConnNetInfo* x_net_info = ConnNetInfo_Clone(net_info);
            if (x_net_info) {
                x_net_info->req_method = eReqMethod_Any;
                x_net_info->stateless = 0;
                x_net_info->lb_disable = 0;
                x_net_info->http_proxy_host[0] = '\0';
                x_net_info->http_proxy_port    =   0;
                x_net_info->http_proxy_user[0] = '\0';
                x_net_info->http_proxy_pass[0] = '\0';
                x_net_info->proxy_host[0]      = '\0';
                ConnNetInfo_SetUserHeader(x_net_info, 0);
                if (x_net_info->http_referer) {
                    free((void*) x_net_info->http_referer);
                    x_net_info->http_referer = 0;
                }
                x_net_info->timeout = timeout;
            }
            ConnNetInfo_Log(x_net_info, eLOG_Note, CORE_GetLOG());
            ConnNetInfo_Destroy(x_net_info);
        }
        status = SOCK_CreateEx(host, net_info->port, timeout, &sock,
                               data, size, flags);
        _ASSERT(!sock ^ !(status != eIO_Success));
    }
    string hostport(net_info->host);
    hostport += ':';
    hostport += NStr::UIntToString(net_info->port);
    CONNECTOR c = SOCK_CreateConnectorOnTopEx(sock,
                                              1/*own*/,
                                              hostport.c_str());
    if (!c) {
        SOCK_Abort(sock);
        SOCK_Close(sock);
        status = eIO_Unknown;
    }
    return CConn_IOStream::TConn_Pair(c, status);
}
Example #4
0
int pgr_configure(CONTEXT *c, const char *file, int reload)
{
	int rc;
	FILE *io = stdin;
	if (strcmp(file, "-") != 0) {
		io = fopen(file, "r");
		if (!io) {
			return 1;
		}
	}
	PARSER *p = parser_init(file, io, reload);
	fclose(io);
	if (!p) {
		return 1;
	}

	rc = parse(p);
	if (rc != 0) {
		return rc;
	}

	/* update what can be updated */
	if (p->workers.set) {
		c->workers = p->workers.value;
	}
	if (p->loglevel.set) {
		c->loglevel = p->loglevel.value;
	}

	if (p->health_interval.set) {
		c->health.interval = p->health_interval.value;
	}
	if (p->health_timeout.set) {
		c->health.timeout = p->health_timeout.value;
	}
	if (p->health_database.set) {
		free(c->health.database);
		c->health.database = p->health_database.value;
	}
	if (p->health_username.set) {
		free(c->health.username);
		c->health.username = p->health_username.value;
	}
	if (p->health_password.set) {
		free(c->health.password);
		c->health.password = p->health_password.value;
	}

	if (p->listen.set) {
		if (!reload) {
			c->startup.frontend = p->listen.value;
		} else if (strcmp(p->listen.value, c->startup.frontend) != 0) {
			fprintf(stderr, "ignoring new value for `listen %s`; retaining old value '%s'\n",
			                p->listen.value, c->startup.frontend);
			free(p->listen.value);
			p->listen.value = c->startup.frontend;
		}
	}
	if (p->monitor.set) {
		if (!reload) {
			c->startup.monitor = p->monitor.value;
		} else if (strcmp(p->monitor.value, c->startup.monitor) != 0) {
			fprintf(stderr, "ignoring new value for `monitor %s`; retaining old value '%s'\n",
			                p->monitor.value, c->startup.monitor);
			free(p->monitor.value);
			p->monitor.value = c->startup.monitor;
		}
	}
	if (p->hbafile.set) {
		if (!reload) {
			c->startup.hbafile = p->hbafile.value;
		} else if (strcmp(p->hbafile.value, c->startup.hbafile) != 0) {
			fprintf(stderr, "ignoring new value for `hba %s`; retaining old value '%s'\n",
			                p->hbafile.value, c->startup.hbafile);
			free(p->hbafile.value);
			p->hbafile.value = c->startup.hbafile;
		}
	}
	if (p->pidfile.set) {
		if (!reload) {
			c->startup.pidfile = p->pidfile.value;
		} else if (strcmp(p->pidfile.value, c->startup.pidfile) != 0) {
			fprintf(stderr, "ignoring new value for `pidfile %s`; retaining old value '%s'\n",
			                p->pidfile.value, c->startup.pidfile);
			free(p->pidfile.value);
			p->pidfile.value = c->startup.pidfile;
		}
	}
	if (p->authdb.set) {
		if (!reload) {
			c->authdb.file = p->authdb.value;
		} else if (strcmp(p->authdb.value, c->authdb.file) != 0) {
			fprintf(stderr, "ignoring new value for `authdb %s`; retaining old value '%s'\n",
			                p->authdb.value, c->authdb.file);
			free(p->authdb.value);
			p->authdb.value = c->authdb.file;
		}
	}
	if (p->tls_ciphers.set) {
		if (!reload) {
			c->startup.tls_ciphers = p->tls_ciphers.value;
		} else if (strcmp(p->tls_ciphers.value, c->startup.tls_ciphers) != 0) {
			fprintf(stderr, "ignoring new value for `tls_ciphers %s`; retaining old value '%s'\n",
			                p->tls_ciphers.value, c->startup.tls_ciphers);
			free(p->tls_ciphers.value);
			p->tls_ciphers.value = c->startup.tls_ciphers;
		}
	}
	if (p->tls_certfile.set) {
		if (!reload) {
			c->startup.tls_certfile = p->tls_certfile.value;
		} else if (strcmp(p->tls_certfile.value, c->startup.tls_certfile) != 0) {
			fprintf(stderr, "ignoring new value for `tls_certfile %s`; retaining old value '%s'\n",
			                p->tls_certfile.value, c->startup.tls_certfile);
			free(p->tls_certfile.value);
			p->tls_certfile.value = c->startup.tls_certfile;
		}
	}
	if (p->tls_keyfile.set) {
		if (!reload) {
			c->startup.tls_keyfile = p->tls_keyfile.value;
		} else if (strcmp(p->tls_keyfile.value, c->startup.tls_keyfile) != 0) {
			fprintf(stderr, "ignoring new value for `tls_keyfile %s`; retaining old value '%s'\n",
			                p->tls_keyfile.value, c->startup.tls_keyfile);
			free(p->tls_keyfile.value);
			p->tls_keyfile.value = c->startup.tls_keyfile;
		}
	}
	if (p->user.set) {
		if (!reload) {
			c->startup.user = p->user.value;
		} else if (strcmp(p->user.value, c->startup.user) != 0) {
			fprintf(stderr, "ignoring new value for `user %s`; retaining old value '%s'\n",
			                p->user.value, c->startup.user);
			free(p->user.value);
			p->user.value = c->startup.user;
		}
	}
	if (p->group.set) {
		if (!reload) {
			c->startup.group = p->group.value;
		} else if (strcmp(p->group.value, c->startup.group) != 0) {
			fprintf(stderr, "ignoring new value for `group %s`; retaining old value '%s'\n",
			                p->group.value, c->startup.group);
			free(p->group.value);
			p->group.value = c->startup.group;
		}
	}

	if (!reload) {
		struct _backend *b;
		c->num_backends = 0;
		for (b = p->backends; b->next; b = b->next) {
			c->num_backends++;
		}
		c->backends = calloc(c->num_backends, sizeof(BACKEND));
		if (!c->backends) {
			parser_free(p);
			return 1;
		}

		int i;
		struct _backend *def = p->backends;
		b = def->next;
		for (i = 0; i < c->num_backends; i++, b = b->next) {
			rc = hostport(b->id, &c->backends[i].hostname, &c->backends[i].port);
			if (rc != 0) {
				parser_free(p);
				return 1;
			}
			c->backends[i].serial++;

			c->backends[i].tls              = get_int(BACKEND_TLS_OFF, &def->tls, &b->tls);
			c->backends[i].health.threshold = get_int(BACKEND_TLS_OFF, &def->lag, &b->lag);
			c->backends[i].weight           = get_int(BACKEND_TLS_OFF, &def->weight, &b->weight);
			c->backends[i].health.database  = get_str("postgres", &p->health_database, NULL);
			c->backends[i].health.username  = get_str("postgres", &p->health_username, NULL);
			c->backends[i].health.password  = get_str("",         &p->health_password, NULL);
		}
	}

	parser_free(p);
	return 0;
}
Example #5
0
void mexFunction(int nlhs, mxArray *plhs[],
      int nrhs, const mxArray *prhs[])
{
	int cid=-1;  // Handle of the current connection (invalid until we identify)
	int jarg=0;  // Number of first string arg: becomes 1 if id is specified

	/*********************************************************************/
	// Parse the first argument to see if it is a specific database handle
	if ( nrhs>0 && mxIsNumeric(prhs[0]) )
		{ if ( mxGetM(prhs[0])!=1 || mxGetN(prhs[0])!=1 )
			{ showusage();
			  mexPrintf("First argument is array %d x %d, but it should be a scalar\n",
			      mxGetM(prhs[0]),mxGetN(prhs[0]) );
			  mexErrMsgTxt("Invalid connection handle"); }
		  double xid = *mxGetPr(prhs[0]);
		  cid = int(xid);
		  if ( double(cid)!=xid || cid<0 || cid>=MAXCONN )
			{ showusage();
			  mexPrintf("dbHandle = %g -- Must be integer between 0 and %d\n",
			      xid,MAXCONN-1);
			  mexErrMsgTxt("Invalid connection handle"); }
		  jarg = 1;
		  if (debug) mexPrintf("| Explicit  cid = %d\n",cid); }

	/*********************************************************************/
	//  Check that the remaining arguments are all character strings
	{ for ( int j=jarg ; j<nrhs ; j++ )
		{ if (!mxIsChar(prhs[j]))
			{ showusage();
			  mexErrMsgTxt("All args must be strings, except dbHandle"); }}}

	/*********************************************************************/
	//  Identify what action he wants to do

	enum querytype { OPEN, CLOSE, CLOSEALL, USENAMED, USE,
	                     STATUS, STATSALL, QUOTE, CMD } q;
	char *query = NULL;

	if (nrhs<=jarg)   q = STATSALL;
	else
		{ query = mxArrayToString(prhs[jarg]);
		  if (streq(query,"open"))          q = OPEN;
		  else if (streq(query,"close"))    q = CLOSE;
		  else if (streq(query,"closeall")) q = CLOSEALL;
		  else if (streq(query,"use"))      q = USENAMED;
		  else if (streq(query,"use",3))    q = USE;
		  else if (streq(query,"status"))   q = STATUS;
		  else if (streq(query,"quote"))    q = QUOTE;
		  else q = CMD; }

	if (debug)
		{ switch(q)
			{ case OPEN:     mexPrintf("| q = OPEN\n");     break;
			  case CLOSE:    mexPrintf("| q = CLOSE\n");    break;
			  case CLOSEALL: mexPrintf("| q = CLOSEALL\n"); break;
			  case USENAMED: mexPrintf("| q = USENAMED\n"); break;
			  case USE:      mexPrintf("| q = USE\n");      break;
			  case STATUS:   mexPrintf("| q = STATUS\n");   break;
			  case STATSALL: mexPrintf("| q = STATSALL\n"); break;
			  case QUOTE:    mexPrintf("| q = QUOTE\n");    break;
			  case CMD:      mexPrintf("| q = CMD\n");      break;
			                 mexPrintf("| q = ??\n");              }}

	/*********************************************************************/
	//  If he did not specify the handle, choose the appropriate one
	//  If there are no previous connections, then we will still have
	//     cid=-1, and this will be handled in the appropriate place.
	if (jarg==0)
		{
		if (q==OPEN)
			{ for ( cid=0 ; cid<MAXCONN & c[cid].isopen ; cid++ );
			  if (cid>=MAXCONN) mexErrMsgTxt("Can\'t find free handle"); }
		else if (ncid>0)
			cid=prevcid[ncid-1];
		}

	if (debug) mexPrintf("| cid = %d\n",cid);

	//  Shorthand notation so we don't need to write c[cid]...
	//  These values must not be used if  cid<0
	mp dummyconn;     mp &conn = (cid>=0) ? c[cid].conn : dummyconn;
	bool dummyisopen; bool &isopen = (cid>=0) ? c[cid].isopen : dummyisopen;

	if (q==OPEN)
		{
		if (cid<0)
			{ mexPrintf("cid = %d !\n",cid);
			  mexErrMsgTxt("Internal code error\n"); }
		//  Close connection if it is open
		if (isopen)
			{ mexWarnMsgIdAndTxt("mysql:ConnectionAlreadyOpen",
			    "Connection %d has been closed and overwritten",cid);
			  mysql_close(conn);
			  conn=NULL;  isopen=false;  stackdelete(cid); }

		//  Extract information from input arguments
		char *host=NULL;   if (nrhs>=jarg+2)  host = mxArrayToString(prhs[jarg+1]);
		char *user=NULL;   if (nrhs>=jarg+3)  user = mxArrayToString(prhs[jarg+2]);
		char *pass=NULL;   if (nrhs>=jarg+4)  pass = mxArrayToString(prhs[jarg+3]);
		int port = hostport(host);  // returns zero if there is no port

		if (nlhs<1)
			{ mexPrintf("Connecting to  host=%s", (host) ? host : "localhost" );
			  if (port) mexPrintf("  port=%d",port);
			  if (user) mexPrintf("  user=%s",user);
			  if (pass) mexPrintf("  password=%s",pass);
			  mexPrintf("\n"); }

		//  Establish and test the connection
		//  If this fails, then conn is still set, but isopen stays false
		if (!(conn=mysql_init(conn)))
			mexErrMsgTxt("Couldn\'t initialize MySQL connection object");
		if (!mysql_real_connect( conn, host, user, pass, NULL,port,NULL,0 ))
			mexErrMsgTxt(mysql_error(conn));
		const char *c=mysql_stat(conn);
		if (c)  { if (nlhs<1) mexPrintf("%s\n",c); }
		else    mexErrMsgTxt(mysql_error(conn));

		isopen=true;
		ncid++;
		if (ncid>MAXCONN)
			{ mexPrintf("ncid = %d ?\n",ncid);
			  mexErrMsgTxt("Internal logic error\n"); }
		prevcid[ncid-1] = cid;

		if (debug) stackprint();

		//  Now we are OK -- return the connection handle opened.
		setScalarReturn(nlhs,plhs,cid);
		}

	else if (q==CLOSE)
		{
		if ( cid>=0 && isopen )
			{ if (debug) mexPrintf("| Closing %d\n",cid);
			  mysql_close(conn);
			  conn = NULL; isopen=false;  stackdelete(cid); }
		if (debug) stackprint();
		}

	else if (q==CLOSEALL)
		{ while (ncid>0)
			{ if (debug) stackprint();
			  cid = prevcid[ncid-1];
			  if (debug) mexPrintf("| Closing %d\n",cid);
			  if (!(c[cid].isopen))
				{ mexPrintf("Connection %d is not marked open!\n",cid);
				  mexErrMsgTxt("Internal logic error"); }
			  mysql_close(c[cid].conn);
			  c[cid].conn=NULL;  c[cid].isopen=false;  ncid--; }}

	else if ( q==USE || q==USENAMED )
		{
		if ( cid<0 || !isopen ) mexErrMsgTxt("Not connected");
		if (mysql_ping(conn))
			{ stackdelete(cid);  isopen=false;
			  mexPrintf(mysql_error(conn));
			  mexPrintf("\nClosing connection %d\n",cid);
			  mexErrMsgTxt("Use command failed"); }
		char *db=NULL;
		if (q==USENAMED)
			{ if (nrhs>=2) db=mxArrayToString(prhs[jarg+1]);
			  else         mexErrMsgTxt("Must specify a database to use"); }
		else
			{ db = query + 3;
			  while ( *db==' ' || *db=='\t' ) db++; }
		if (mysql_select_db(conn,db))  mexErrMsgTxt(mysql_error(conn));
		if (nlhs<1) mexPrintf("Current database is \"%s\"\n",db); 
		else        setScalarReturn(nlhs,plhs,1.);
		}

	else if (q==STATUS)
		{
		if (nlhs<1)  //  He wants a report
			{ // print connection handle only if multiple connections
			  char idstr[10];  idstr[0]=0;
			  if ( cid>=0 && ncid>1 )  sprintf(idstr,"(%d) ",cid);
			  if ( cid<0 || !isopen )
			   { mexPrintf("%sNot connected\n",idstr,cid);  return; }
			  if (mysql_ping(conn))
				{ mexErrMsgTxt(mysql_error(conn)); }
			  mexPrintf("%s%-30s   Server version %s\n",
			    idstr, mysql_get_host_info(conn), mysql_get_server_info(conn) ); }
		else         //  He wants a return value for this connection
			{ double *pr=setScalarReturn(nlhs,plhs,0.);
			  if ( cid<0 || !isopen ) { *pr=1.; return; }
			  if (mysql_ping(conn))   { *pr=2.; return; }}
		}

	else if (q==STATSALL)
		{
		if (debug) stackprint();
		if (ncid==0)      mexPrintf("No connections open\n");
		else if (ncid==1) mexPrintf("1 connection open\n");
		else              mexPrintf("%d connections open\n",ncid);
		for ( int j=0 ; j<ncid ; j++ )
			{ cid = prevcid[j];
			  if (mysql_ping(c[cid].conn))
				  mexPrintf("%2d:  %s\n",cid,mysql_error(conn));
			  else
				  mexPrintf("%2d:  %-30s   Server version %s\n",
				        cid, mysql_get_host_info(c[cid].conn),
				        mysql_get_server_info(c[cid].conn) ); }
		}

	// Quote the second string argument and return it (Chris Rodgers)
	else if (q==QUOTE)
		{
		if ((nrhs-jarg)!=2)
			mexErrMsgTxt("mysql('quote','string_to_quote') takes two string arguments!");

		//  Check that we have a valid connection
		if ( cid<0 || !isopen ) mexErrMsgTxt("No connection open");
		if (mysql_ping(conn))
			{ stackdelete(cid);  isopen=false;
			  mexErrMsgTxt(mysql_error(conn)); }

		const mxArray *a = prhs[jarg+1];
		int llen = mxGetM(a)*mxGetN(a)*sizeof(mxChar);
		char *from = (char *) mxCalloc(llen+1,sizeof(char));
		if (mxGetString(a,from,llen)) mexErrMsgTxt("Can\'t copy string");
		int l = strlen(from);

		/* Allocate memory for input and output strings. */
		char *to = (char*) mxCalloc( llen*2+3, sizeof(char));

		/* Call the C subroutine. */
		to[0] = '\'';
		int n = mysql_real_escape_string( conn, to+1, from, l );
		to[n+1] = '\'';

		/* Set C-style string output_buf to MATLAB mexFunction output*/
		plhs[0] = mxCreateString(to);

		mxFree(from);  mxFree(to);  // just in case Matlab forgets
		}

	else if (q==CMD)
		{
		//  Check that we have a valid connection
		if ( cid<0 || !isopen ) mexErrMsgTxt("No connection open");
		if (mysql_ping(conn))
			{ stackdelete(cid);  isopen=false;
			  mexPrintf(mysql_error(conn));
			  mexPrintf("Closing connection %d\n",cid);
			  mexErrMsgTxt("Query failed"); }

		//  Execute the query (data stays on server)
		if (mysql_query(conn,query))  mexErrMsgTxt(mysql_error(conn));

		//  Download the data from server into our memory
		//     We need to be careful to deallocate res before returning.
		//  Matlab's allocation routines return instantly if there is not
		//  enough free space, without giving us time to dealloc res.
		//  This is a potential memory leak but I don't see how to fix it.
		MYSQL_RES *res = mysql_store_result(conn);

		//  As recommended in Paul DuBois' MySQL book (New Riders, 1999):
		//  A NULL result set after the query can indicate either
		//    (1) the query was an INSERT, DELETE, REPLACE, or UPDATE, that
		//        affect rows in the table but do not return a result set; or
		//    (2) an error, if the query was a SELECT, SHOW, or EXPLAIN
		//        that should return a result set but didn't.
		//  Distinguish between the two by checking mysql_field_count()
		//  We return in either case, either correctly or with an error
		if (!res)
			{
			if (!mysql_field_count(conn))
				{ unsigned long nrows=mysql_affected_rows(conn);
				  if (nlhs<1)
					{ mexPrintf("%u rows affected\n",nrows);
					  return; }
				  else
					{ setScalarReturn(nlhs,plhs,nrows);
					  return; }}
			else
				  mexErrMsgTxt(mysql_error(conn));
			}

		unsigned long nrow=mysql_num_rows(res), nfield=mysql_num_fields(res);

		//  If he didn't ask for any output (nlhs=0),
		//       then display the output and return
		if ( nlhs<1 )
			{ fancyprint(res);
			  mysql_free_result(res);
			  return; }

		//  If we are here, he wants output
		//  He must give exactly the right number of output arguments
// 		if ( nlhs != nfield )
// 			{ mysql_free_result(res);
// 			  mexPrintf("You specified %d output arguments, "
// 			         "and got %d columns of data\n",nlhs,nfield);
// 			  mexErrMsgTxt("Must give one output argument for each column"); }
        
        if(nlhs > 1) mexErrMsgIdAndTxt( "MYSQL query: ",
                        "Too many output arguments.");

		//  Fix the column types to fix MySQL C API sloppiness
		MYSQL_FIELD *f = mysql_fetch_fields(res);
		fix_types( f, res );

		//  Create the Matlab arrays for output
// 		double **pr = (double **) mxMalloc( nfield * sizeof(double *) );
// 		{ for ( int j=0 ; j<nfield ; j++ )
// 			{ if ( can_convert(f[j].type) )
// 				{ if (!( plhs[j] = mxCreateDoubleMatrix( nrow, 1, mxREAL ) ))
// 					{ mysql_free_result(res);
// 					  mexErrMsgTxt("Unable to create numeric matrix for output"); }
// 				  pr[j] = mxGetPr(plhs[j]); }
// 			  else
// 				{ if (!( plhs[j] = mxCreateCellMatrix( nrow, 1 ) ))
// 					{ mysql_free_result(res);
// 					  mexErrMsgTxt("Unable to create cell matrix for output"); }
// 				  pr[j] = NULL; }}}
        
         if (!( plhs[0] = mxCreateCellMatrix( nrow, nfield ) )){
					 mysql_free_result(res);
                     mexErrMsgTxt("Unable to create cell matrix for output");                 
         }

		//  Load the data into the cells
		mysql_data_seek(res,0);
		for ( int i=0 ; i<nrow ; i++ ){ 
			  MYSQL_ROW row = mysql_fetch_row(res);
			  if (!row) { 
				mexPrintf("Scanning row %d for data extraction\n",i+1);
				  mexErrMsgTxt("Internal error:  Failed to get a row"); }
// 			  for ( int j=0 ; j<nfield ; j++ ){ 
//                   if (can_convert(f[j].type)) { 
// 					pr[j][i] = field2num(row[j],f[j].type); 
//                   }
// 				  else {
// 					 mxArray *c = mxCreateString(row[j]);
// 					  mxSetCell(plhs[j],i,c); 
//                   }
//               }
             for ( int j=0 ; j <nfield ; j++ ){
                 mxArray *c = mxCreateString(row[j]);
 					  mxSetCell(plhs[0],j*nrow + i,c); 
             }
        }
		mysql_free_result(res);
		}
	else
		{ mexPrintf("Unknown query type q = %d\n",q);
		  mexErrMsgTxt("Internal code error"); }
}