From: Jean-Marc Pigeon (Delson) Date: Tue, 24 Jun 2025 22:45:56 +0000 (-0400) Subject: Adding module unisql.c X-Git-Tag: tag-0.10~41 X-Git-Url: https://jmp-git.ovh.safe.ca/?a=commitdiff_plain;h=8f86d5636073e91106a36605f0abf706a9f1fe4f;p=jmp%2Fmailleur Adding module unisql.c --- diff --git a/lib/Makefile b/lib/Makefile index 97fc739..dff6370 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -24,7 +24,7 @@ OBJS= \ gesspf.o gestcp.o geseml.o \ devlog.o devsoc.o devsql.o \ unidns.o unieml.o unipar.o \ - uniprc.o unisig.o unitls.o \ + uniprc.o unisig.o unisql.o unitls.o \ subafn.o subrou.o LIBS= \ @@ -131,6 +131,9 @@ gesspf.h: \ devsoc.h: \ unitls.h +devsql.h: \ + unisql.h + uniprc.h: \ subrou.h diff --git a/lib/devsql.c b/lib/devsql.c index eb07c7f..4ba5e0d 100644 --- a/lib/devsql.c +++ b/lib/devsql.c @@ -5,6 +5,7 @@ /* to handle SQL request */ /* */ /********************************************************/ +#include #include #include @@ -112,7 +113,20 @@ while (proceed==true) { } break; case 3 : //checking if the database is properly open - if (sql->db.psql==(POSPTR *)0) { + _Bool isok; + + isok=false; + switch (sql->sqldb) { + case db_postgres: + isok=(sql->db.psql!=(POSPTR *)0); + break; + case db_maria : + isok=(sql->db.msql!=(MARPTR *)0); + break; + default : + break; + } + if (isok==false) { (void) rou_alert(0,"%s data-base not properly connected (config?)",OPEP); (void) free(sql); sql=(SQLTYP *)0; @@ -163,7 +177,7 @@ while (proceed==true) { sql->db.psql=pos_closesql(sql->db.psql); break; case db_maria : - sql->db.msql=mar_closesql(sql->db.psql); + sql->db.msql=mar_closesql(sql->db.msql); break; default : (void) rou_alert(0,"%s Unexpected type='%d' (bug?)", @@ -184,3 +198,114 @@ while (proceed==true) { return (SQLPTR *)sql; #undef OPEP } +/* + +*/ +/********************************************************/ +/* */ +/* Procedure to make sure a string to be use to */ +/* access database is clean. */ +/* (no character to be misunderstood by database) */ +/* */ +/********************************************************/ +PUBLIC char *sql_cleanstr(SQLPTR *sqlptr,char *str) + +{ +#define OPEP "devsql.c:sql_cleanstr," +char *cleanstr; +SQLTYP *sql; + +cleanstr=(char *)0; +sql=(SQLTYP *)sqlptr; +if (str!=(char *)0) { + (void) sql_checkencoding(str); + switch(sql->sqldb) { + case (db_postgres) : + cleanstr=pos_cleanquote(str); + break; + case (db_maria) : + cleanstr=mar_cleanquote(str); + break; + case (db_unknown) : + default : + (void) rou_alert(0,"%s Unknown SQL daemon (type='%d')",OPEP,sql->sqldb); + break; + } + } +else + cleanstr=strdup("NULL"); +return cleanstr; + +#undef OPEP +} +/* + +*/ +/********************************************************/ +/* */ +/* Procedure to retreive information about user */ +/* known within database. */ +/* */ +/********************************************************/ +PUBLIC USRTYP *sql_getusr(SQLPTR *sqlptr,char *email) + +{ +#define OPEP "devsql.c:sql_getuser," + +USRTYP *usr; +SQLTYP *sql; +int phase; +_Bool proceed; + +usr=(USRTYP *)0; +sql=(SQLTYP *)sqlptr; +phase=0; +proceed=true; +while (proceed==true) { + switch (phase) { + case 0 : //checking SQL + if (sql==(SQLTYP *)0) { + (void) rou_alert(0,"%s SQL pointer is NUll (Bug?)",OPEP); + phase=999; + } + break; + case 1 : //is email defined? + if ((email==(char *)0)||(strlen(email)==0)) { + (void) rou_alert(0,"%s Email <%s> is NUll or empty (Bug?)",OPEP,email); + phase=999; + } + break; + case 2 : //check email structure + for (int i=0,l=strlen(email);i not accepted, '%c' not an email char", + OPEP,email,car); + phase=999; + } + break; + case 3 : //opening specific database + switch (sql->sqldb) { + case db_postgres : + break; + case db_maria : + break; + default : + (void) rou_alert(0,"%s Unexpected type='%d' (bug?)",OPEP,sql->sqldb); + break; + } + break; + default : + proceed=false; + break; + } + phase++; + } +return usr; +#undef OPEP +} diff --git a/lib/devsql.h b/lib/devsql.h index 7507cf0..d128216 100644 --- a/lib/devsql.h +++ b/lib/devsql.h @@ -8,6 +8,8 @@ #ifndef DEVSQL #define DEVSQL +#include "unisql.h" + //reference to a SQL pointer reference typedef void SQLPTR; @@ -17,4 +19,11 @@ extern SQLPTR *sql_opensql(); //procedure to close an previously opened SQL channel extern SQLPTR *sql_closesql(SQLPTR *sqlptr); +//procedure to make sure a string with database +//is clean +extern char *sql_cleanstr(SQLPTR *sqlptr,char *str); + +//procedure to get information on exiting user +extern USRTYP *sql_getusr(SQLPTR *sqlptr,char *email); + #endif diff --git a/lib/unimar.c b/lib/unimar.c index a3013c1..419721b 100644 --- a/lib/unimar.c +++ b/lib/unimar.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -91,5 +92,60 @@ return marptr; #undef OPEP } +/* + +*/ +/********************************************************/ +/* */ +/* Procedure to detect and 'clean' any single quote*/ +/* within a string, this is mandatory for string */ +/* variable in the database. */ +/* Single quote and double quote are translated to */ +/* '\'' and '\"' */ +/* */ +/********************************************************/ +char *mar_cleanquote(char *dstr) + +{ +char *cleanstr; +int taille; +char *ptr; +taille=3; +cleanstr=calloc(3,sizeof(char)); +cleanstr[0]='\''; +if (dstr!=(char *)0) { + char *nptr; + + ptr=dstr; + while (((nptr=strchr(ptr,'\''))!=(char *)0)||((nptr=strchr(ptr,'\"'))!=(char *)0)) { + char lit[3]; + char *newclean; + + (void) strcpy(lit,"\\'"); + if (*nptr=='"') + lit[1]='"'; + *nptr='\000'; /*to segment string */ + taille+=strlen(ptr)+2; + if ((newclean=(char *)realloc(cleanstr,taille))!=(char *)0) { + cleanstr=newclean; + (void) strcat(cleanstr,ptr); + (void) strcat(cleanstr,lit); + *nptr=lit[1]; /*to glue back string */ + ptr=nptr+1; + } + } + if (*ptr!='\000') { + char *newclean; + + taille+=strlen(ptr); + if ((newclean=(char *)realloc(cleanstr,taille))!=(char *)0) { + cleanstr=newclean; + (void) strcat(cleanstr,ptr); + } + } + } +(void) strcat(cleanstr,"'"); +return cleanstr; +} diff --git a/lib/unimar.h b/lib/unimar.h index b353cf0..efb8c22 100644 --- a/lib/unimar.h +++ b/lib/unimar.h @@ -8,7 +8,6 @@ #ifndef UNIMAR #define UNIMAR - //reference to a SQL pointer reference typedef void MARPTR; @@ -18,4 +17,7 @@ extern MARPTR *mar_opensql(const char *host,const char *sqlport,const char *dbna //closing a postscript database extern MARPTR *mar_closesql(MARPTR *marptr); +//Procedure to detect and 'clean' any single quote within a string +extern char *mar_cleanquote(char *sequence); + #endif diff --git a/lib/unipos.c b/lib/unipos.c index df2c23a..bf59fa2 100644 --- a/lib/unipos.c +++ b/lib/unipos.c @@ -7,6 +7,8 @@ /********************************************************/ #include #include +#include +#include #include "subrou.h" #include "unipos.h" @@ -90,5 +92,56 @@ return posptr; #undef OPEP } +/* + +*/ +/********************************************************/ +/* */ +/* Procedure to detect and 'clean' any single quote*/ +/* within a string, this is mandatory for string */ +/* variable in the database. */ +/* Single quote "'" are doubled becoming "''" */ +/* */ +/********************************************************/ +char *pos_cleanquote(register char *dstr) +{ +char *cleanstr; +int taille; + +cleanstr=strdup("E'"); +taille=strlen(cleanstr)+2; +if (dstr!=(char *)0) { + int max; + int i,p; + char *newclean; + /*to double char ' in the string */ + max=strlen((const char *)dstr); + taille+=max; + if ((newclean=(char *)realloc(cleanstr,taille))!=(char *)0) { + cleanstr=newclean; + p=strlen(cleanstr); + for (i=0;i +#include +#include +#include +#include +#include + +#include "subrou.h" +#include "unisql.h" + +#define DLANG "UNICODE" + +/* + +*/ +/************************************************/ +/* */ +/* Procedure to convert an char sequence */ +/* from on char set to another. */ +/* if successful return a new pointer */ +/* */ +/************************************************/ +static char *cnvconvert(char *lfrom,char *lto,char *encoded) + +{ +#define OPEP "rousql.c:cnvconvert," + +char *converted; +char *marker; +iconv_t hconv; +size_t inbuflft; +char *inbuf; +size_t outbuflft; +char *outbuf; +int phase; +int proceed; + +converted=(char *)0; +marker=(char *)0; +hconv=(iconv_t)0; +inbuflft=(size_t)0; +inbuf=(char *)0; +outbuflft=(size_t)0; +outbuf=(char *)0; +phase=0; +proceed=1; +while (proceed==true) { + switch (phase) { + case 0 : /*opening conv channel */ + if ((hconv=iconv_open(lto,lfrom))==(iconv_t)-1) { + (void) rou_alert(0,"%s Unexpected lang conversion request " + "from=<%s> to=<%s> (errno=<%s>)", + OPEP,lfrom,lto,strerror(errno)); + phase=999; /*trouble trouble */ + } + break; + case 1 : /*doing convertion */ + inbuflft=strlen(encoded); + outbuflft=(inbuflft*4)+1; /*spare room */ + inbuf=encoded; + marker=(char *)calloc(outbuflft,sizeof(char)); + outbuf=marker; + if (iconv(hconv,&inbuf,&inbuflft,&outbuf,&outbuflft)==(size_t)(-1)) { + (void) rou_alert(2,"%s Unable to convert <%s> " + "from=<%s> to=<%s> (errno=<%s>)", + OPEP,encoded,lfrom,lto,strerror(errno)); + (void) free(marker); + marker=(char *)0; + } + break; + case 2 : /*doing convertion */ + if (iconv_close(hconv)<0) + (void) rou_alert(0,"%s Unexpected close conversion error " + "(errno=<%s>) (bug?)",OPEP,strerror(errno)); + break; + default : /*SAFE Guard */ + converted=marker; + proceed=false; + break; + } + phase++; + } +return converted; + +#undef OPEP +} +/* + +*/ +/********************************************************/ +/* */ +/* Procedure to free memory used by a user */ +/* definition. */ +/* */ +/********************************************************/ +PUBLIC USRTYP *sql_freeusr(USRTYP *usr) + +{ +if (usr!=(USRTYP *)0) { + usr->email=rou_freestr(usr->email); + (void) free(usr); + usr=(USRTYP *)0; + } +return usr; +} +/* + +*/ +/************************************************/ +/* */ +/* Routine to check if string is properly */ +/* coded, if it is not the case replace all*/ +/* dubious charactere with plain ASCII */ +/* */ +/************************************************/ +PUBLIC void sql_checkencoding(char *strencoded) + +{ +char *ptr; +int phase; +int proceed; + +ptr=(char *)0; +phase=0; +proceed=true; +while (proceed==true) { + switch (phase) { + case 0 : /*autoconvert string */ + if (((ptr=getenv("DB_LANG"))==(char *)0)||(strlen(ptr)==0)) + ptr=DLANG; + if ((ptr=cnvconvert(ptr,ptr,strencoded))!=(char *)0) { + (void) free(ptr); + phase=999; /*everything fine */ + } + break; + case 1 : /*setting to plain ASCII*/ + if (strencoded!=(char *)0) { /*alway */ + while (*strencoded!='\000') { + if (isascii(*strencoded)==0) + *strencoded='_'; + strencoded++; + } + } + break; + default : /*SAFE Guard */ + proceed=false; + break; + } + phase++; + } +} diff --git a/lib/unisql.h b/lib/unisql.h new file mode 100644 index 0000000..59c3f8d --- /dev/null +++ b/lib/unisql.h @@ -0,0 +1,25 @@ +// vim: smarttab tabstop=8 shiftwidth=2 expandtab +/************************************************/ +/* */ +/* Low level SQL subroutine declaration */ +/* */ +/************************************************/ +#ifndef UNISQL +#define UNISQL + +#include + +//structure about user within the database +typedef struct { + char *email; //user emails + u_long space; //user space used; + u_long mxspace; //user maximun space + }USRTYP; + +//procedure to free space used by an USRTYP +extern USRTYP *sql_freeusr(USRTYP *usr); + +//PRocedure to check if string is properly coded according DB_LANG +extern void sql_checkencoding(char *strencoded); + +#endif