#include "HTParse.h" #include "HTUtils.h" #include "HTML.h" /* SCW */ extern int HTClientProtocol; #define PUTC(c) (*target->isa->put_character)(target, c) #define PUTS(s) (*target->isa->put_string)(target, s) #define START(e) (*target->isa->start_element)(target, e, 0, 0) #define END(e) (*target->isa->end_element)(target, e) #define END_TARGET (*target->isa->end_document)(target) #define FREE_TARGET (*target->isa->free)(target) struct _HTStructured { CONST HTStructuredClass * isa; /* ... */ }; struct _HTStream { CONST HTStreamClass * isa; /* ... */ }; #ifndef NO_RULES #include "HTRules.h" #endif #include #include "HTList.h" #include "HText.h" /* See bugs above */ #include "HTAlert.h" #include #include #include /* #include */ #define USERNAME "SCOTT" #define PASSWORD "TIGER" #define SOC_SIZE 4096 #include "HTOracle.h" /* #ifndef MSDOS extern char *malloc(); #else extern unsigned char *malloc(); #endif */ char *nullstring=" "; EXEC SQL BEGIN DECLARE SECTION; char *username = USERNAME; char *password = PASSWORD; VARCHAR statement[4096]; EXEC SQL END DECLARE SECTION; EXEC SQL INCLUDE sqlca; EXEC SQL INCLUDE sqlda; SQLDA *bind_dp; SQLDA *select_dp; extern SQLDA *sqlald(); extern void sqlprc(); int precision, scale; extern void sqlnul(); short null_ok; short *indicator; PRIVATE char badaboum[SOC_SIZE]; #define LIEN_MAX 40 PRIVATE char *LIEN_AVANT; PRIVATE char *LIEN_APRES; PRIVATE char *CLEF[LIEN_MAX]; PRIVATE char *LIEN[LIEN_MAX]; PRIVATE int lien; PRIVATE int lien_suite; extern FILE *logfile; /* oracle_decode ** ------------- ** ** Cette fonction extrait de la question les parties mises en commentaire ** afin de les stocker dans : ** CLEF[] = nom de la colonne ** LIEN[] = lien associe a la colonne */ PRIVATE char *oracle_decode ARGS2(char *, ligne,char *, clef) { char *c, *d, *e, *arg; char *nouveau, *retour; int i, log; arg = ligne; lien = -1; nouveau = (char *)malloc((strlen(ligne) + 1) * sizeof(char)); if(!nouveau) { fprintf(stderr,"oracle_decode : allocation memoire\n"); return (0); } LIEN_AVANT = LIEN_APRES = 0; c = strstr(arg,"/*"); if(c && (c < strstr(arg,"select"))) { c += 2; if(!(d = strstr(c,"*/"))) { fprintf(stderr,"oracle_decode : /* non apparie\n"); return(0); } *d++ = 0; *d++ = 0; arg = d; LIEN_AVANT = c; } i = strlen(arg) - 1; if(((*(arg+i) == '/') && (*(arg+i-1) == '*'))) { *(arg+i-1) = 0; { char *d, *e, *f; for(f=0,e=arg;d=strstr(e,"/*");f=d,e=d+2); if(f) { *f++ = 0; *f++ = 0; LIEN_APRES = f; } } } strcpy(nouveau,""); while(c = strstr(arg,"/*")) { lien++; for(d=c-1; isspace(*d) && (d!=arg); d--) *d = 0; *c++ = 0; *c++ = 0; if(*d == '"') { log = 1; *d = 0; if(!(d = rindex(arg,'"'))) { fprintf(stderr,"oracle_decode : \" non apparie\n"); free(nouveau); return (0); } d++; } else { log = 0; for(;(d>arg) && !(isspace(*d) || *d==',');d--); for(e=++d;*e;e++) *e = toupper(*e); } CLEF[lien] = d; strcat(nouveau,arg); if(log) strcat(nouveau,"\""); strcat(nouveau," "); if(d = strstr(c,"*/")) { *d++ = 0; *d++ = 0; LIEN[lien] = c; } else return 0; arg = d; } strcat(nouveau,arg); retour = (char *)malloc(SOC_SIZE * sizeof(char)); for(d=nouveau,i=0;i* /select a, b "b", c "e" / * !! %s ++ %s == %s !! * / ** from d where %s / * tutu * / ** ** ===> avant chaque individu impression de "
  • " ** ===> impression de la colonne A avec le libelle "A", avec le ** format par defaut defini dans rep: ** ===> impression de la colonne B avec le libelle "b", avec le ** format par defaut defini dans rep: ** ===> impression de la colonne C avec le libelle "e", avec le ** format defini par " !! %s ++ %s == %s !! ** ou le 1er %s est le libelle de la colonne ("e") ** les autres %s pour la valeur retournee par oracle ** ===> la question elle meme est un format C (8 * clef) ** ===> apres chaque individu impression de " tutu " ** ** - pie: bas de la page = format C,8 arguments possibles (8 * clef) ** ** Remarques : ** 1) les retour-chariot et " " sont conserves dans les formats C. ** 2) La clef est encodee (HTEscape) au niveau des individus et du ** bas de page ** La clef est sous forme normale dans le titre et l'entete ** */ PRIVATE void oracle_imprime ARGS3(HTStructured *, target, SQLDA *, select_dp, char *,rep) { int i,j; char parrot[120]; char bidiboum[SOC_SIZE]; char *zezette; lien_suite = 0; if(LIEN_AVANT) PUTS(LIEN_AVANT); for (i=0; iF; i++) { indicator = (short *)select_dp->I[i]; if(*indicator < 0) { if((lien_suite <= lien) && (!strcmp(CLEF[lien_suite],parrot))) lien_suite++; } else { j = ((int)select_dp->C[i]>119)?119:(int)select_dp->C[i]; sprintf(parrot,"%*.*s",j,j,select_dp->S[i]); sprintf(bidiboum,"%*.*s ", (int)select_dp->L[i], (int)select_dp->L[i],select_dp->V[i]); zezette = oracle_chaine(bidiboum); if((lien_suite <= lien) && (!strcmp(CLEF[lien_suite],parrot))) { sprintf(badaboum,LIEN[lien_suite],parrot,zezette,zezette); lien_suite++; } else sprintf(badaboum,rep?rep:"%s=%s",parrot,zezette,zezette); PUTS(badaboum); } } if(LIEN_APRES) PUTS(LIEN_APRES); } PRIVATE int INIT_TABLEAU; /* oracle_tableau ** -------------- ** ** Presentation sous la forme : **
    **	  col1  col2 ... coln
    **        -------------------
    **        aaa   aaa  ... aaa
    **        bbb   bb   ... b
    **	     ...
    **	  
    */ PRIVATE void oracle_tableau ARGS3(HTStructured *, target, SQLDA *, select_dp, char *,rep) { int i; char buffer[SOC_SIZE]; /* @@ */ if(INIT_TABLEAU) { char parrot[31]; char *zezette; INIT_TABLEAU = 0; PUTS("
    \n");
        for (i=0; iF; i++) {
          strncpy(parrot,select_dp->S[i],30);
          if (select_dp->T[i] == 2) {  
    	while ((zezette=strchr(parrot,' ')) != 0) *zezette='\0';  
    	sprintf(buffer,"%*.*s ", (int)select_dp->L[i],
    		(int)select_dp->L[i], parrot);
    	PUTS(buffer);
          } else {
    	sprintf(buffer,"%-*.*s ",(int)select_dp->L[i],
    		(int)select_dp->L[i], parrot);
    	PUTS(buffer);
          }
        }
    
        PUTC('\n');
    
        for (i=0; iF; i++) {
          sprintf(buffer,"%*.*s ", (int)select_dp->L[i],(int)select_dp->L[i],
    	      "------------------------------------------");
          PUTS(buffer);
        } 
        PUTC('\n');
    
      }
    
      for (i=0; iF; i++) {
        indicator = (short *)select_dp->I[i];
        sprintf(buffer,"%-*.*s ", (int)select_dp->L[i],
    	    (int)select_dp->L[i],(*indicator<0)?nullstring:select_dp->V[i]);
        PUTS(buffer);
      }
      PUTC('\n');
    }
    
    /*	oracle_recherche
    **	----------------
    **
    **	Interface a oracle.
    **	Fait l'ouverture de la base
    **	     pose la question et formatte les sorties
    */
    PRIVATE int oracle_recherche ARGS2(RECH *, oracle, HTStructured * ,target) 
    { 
      int i,j;
      char *zozo;
      char *zezette;
      char parrot[50];
      void (*oracle_presente)();
      char *keywords;
      char buffer[SOC_SIZE]; /* @@ */
    
      if (!oracle->que || *oracle->que=='\0') {
    /* #ts: jamais appele theoriquement */
        START(HTML_ISINDEX);
        START(HTML_TITLE);
        PUTS("Oracle Server");
        END(HTML_TITLE);
        PUTS("\n

    This is an Oracle Server.

    \nPlease enter your Request (no semicolon at the end) "); END_TARGET; FREE_TARGET; return HT_LOADED; } INIT_TABLEAU = 1; keywords = oracle_decode(oracle->que,oracle->cle); /* oracle->que = 0; */ if(!keywords) return 0; /* Titre */ START(HTML_ISINDEX); START(HTML_TITLE); sprintf(buffer,"%s",oracle->cle); PUTS(buffer); END(HTML_TITLE); PUTC('\n'); /* Entete de la page */ if(oracle->ent) { sprintf(buffer,oracle->ent,oracle->cle,oracle->cle, oracle->cle,oracle->cle,oracle->cle,oracle->cle, oracle->cle,oracle->cle); PUTS(buffer); PUTC('\n'); } /* Selection de la fonction de formattage */ oracle_presente =(oracle->typ==ORACLE_TABLEAU)?oracle_tableau:oracle_imprime; /* Interface proprement-dit a oracle */ EXEC SQL WHENEVER SQLERROR GOTO sqlerror; strcpy(badaboum,"ORACLE_SID="); strcat(badaboum,oracle->bas); putenv(badaboum); putenv("ORACLE_HOME=/usr/local/oracle"); EXEC SQL CONNECT :username IDENTIFIED BY :password; bind_dp = sqlald (40, 30, 30); bind_dp->N = 40; select_dp = sqlald (40, 30, 30); select_dp->N = 40; strcpy((char *)statement.arr,keywords); statement.len = strlen(statement.arr); EXEC SQL PREPARE S FROM :statement; EXEC SQL DECLARE C CURSOR FOR S; EXEC SQL DESCRIBE BIND VARIABLES FOR S INTO bind_dp; if (bind_dp->F < 0) { PUTS("Too many bind variables for descriptor."); goto sqlerror; } bind_dp->N = bind_dp->F; if (bind_dp->F > 0) { PUTS("\nEnter value for bind variable\n"); goto sqlerror; } EXEC SQL OPEN C USING DESCRIPTOR bind_dp; if ((strncmp(statement.arr, "SELECT", 6) != 0) && (strncmp(statement.arr, "select", 6) != 0)) goto end_main; EXEC SQL DESCRIBE SELECT LIST FOR S INTO select_dp; if (select_dp->F < 0) { sprintf(buffer, "\nToo many select-list variables for descriptor: %d", -(select_dp->F)); PUTS(buffer); goto sqlerror; } select_dp->N = select_dp->F; for (i=0; iF; i++) { sqlnul (&(select_dp->T[i]), &(select_dp->T[i]), &null_ok); switch (select_dp->T[i]) { case 1 : break; case 2 : sqlprc (&(select_dp->L[i]), &precision,&scale); if (precision == 0) precision = 10; select_dp->L[i] = precision + 2; if (scale < 0) select_dp->L[i] += -scale; break; case 8 : select_dp->L[i] = 240; break; case 11 : select_dp->L[i] = 18; break; case 12 : select_dp->L[i] = 9; break; case 23 : break; case 24 : select_dp->L[i] = 240; break; } select_dp->V[i] = malloc(select_dp->L[i]); select_dp->I[i] = (short *)malloc(sizeof(short)); if (select_dp->T[i] != 24) select_dp->T[i] = 1; } EXEC SQL WHENEVER NOT FOUND GOTO end_main; lien_suite = 0; for (j=0;jrep); } end_main: /* fin: on retablit ' ' et '>' */ for(zozo=oracle->cle; *zozo; zozo++) *zozo = (*zozo == ' ') ? '+': ((*zozo == '>') ? '@': *zozo); PUTC('\n'); if(oracle->typ==ORACLE_TABLEAU) PUTS("\n
    "); /* bas de la page */ if(oracle->pie) { if(HTClientProtocol) { char *temp, *a; while(a = strchr(oracle->cle,'+')) *a = ' '; temp = HTEscape(oracle->cle,URL_XALPHAS); sprintf(buffer,oracle->pie,temp,temp,temp,temp,temp,temp,temp,temp); free(temp); } else sprintf(buffer,oracle->pie,oracle->cle,oracle->cle, oracle->cle,oracle->cle,oracle->cle,oracle->cle, oracle->cle,oracle->cle); PUTS(buffer); PUTC('\n'); } for (i=0; iF; i++) { free (select_dp->V[i]); free (select_dp->I[i]); } sqlclu (bind_dp); sqlclu (select_dp); EXEC SQL CLOSE C; EXEC SQL COMMIT WORK RELEASE; END_TARGET; FREE_TARGET; free(keywords); return; sqlerror: sprintf(buffer,"%s

    \n%.70s\n",keywords,sqlca.sqlerrm.sqlerrmc); PUTS(buffer); END_TARGET; FREE_TARGET; EXEC SQL WHENEVER SQLERROR CONTINUE; EXEC SQL ROLLBACK WORK RELEASE; free(keywords); return; } /* test d'acces */ extern test_from(); #define MAX_SELECT_ORACLE 1024 /* oracle_lit_fichier ** ------------------ ** ** Lit le fichier .sql afin d'en extraire : ** typ : type de presentation (tableau, liste, ...) ** ent : entete de page ** que : requete sql ** pie : bas de page ** ** En profite pour verifier si l'interrogation est autorisee */ PRIVATE int oracle_lit_fichier ARGS3(char *, filename,char *,keywords, RECH *, oracle) { char *c, *d, *t; char ligne[256]; FILE *fdd; int cas; char *allow, *deny; oracle->typ = ORACLE_GENERAL; if(strstr(filename,".html")) { c = (char *)rindex(filename, '.'); if(c) *c = 0; strcat(filename,".sql"); } /* verification d'acces */ /* #ts: pas indispensable c = (char *)rindex(filename,'.'); d = (char *)rindex(filename,'/'); *c = *d = 0; if((allow = (char *)malloc((strlen(filename) + strlen("/hosts.allow") + 1) * sizeof(char))) == NULL) return(1); strcpy(allow,filename); strcat(allow,"/hosts.allow"); if((deny = (char *)malloc((strlen(filename) + strlen("/hosts.deny") + 1) * sizeof(char))) == NULL) return(1); strcpy(deny,filename); strcat(deny,"/hosts.deny"); cas = test_from((d+1),allow,deny); free(allow); free(deny); if(cas) return(2); *c = '.'; *d = '/'; */ oracle->pie = oracle->ent = oracle->que = oracle->rep = 0; if((t = malloc(MAX_SELECT_ORACLE * sizeof(char))) == NULL) return (1); *t = 0; /* lecture du fichier */ if((fdd = fopen(filename,"r"))!=NULL) { cas = ORACLE_QUE; while((c=fgets(ligne,256,fdd))) { d = ligne; if(!strncmp("ent:",d,4)) { cas = ORACLE_ENT; d += 4; } else if(!strncmp("pie:",d,4)) { cas = ORACLE_PIE; d += 4; } else if(!strncmp("que:",d,4)) { cas = ORACLE_QUE; d += 4; } else if(!strncmp("typ:",d,4)) { cas = ORACLE_TYP; d += 4; } else if(!strncmp("rep:",d,4)) { cas = ORACLE_REP; d += 4; } switch (cas) { case ORACLE_ENT: if(!oracle->ent) { if((oracle->ent=malloc(MAX_SELECT_ORACLE * sizeof(char))) == NULL) { free(t); return (1); } *oracle->ent = 0; } strcat(oracle->ent, d); break; case ORACLE_REP: if(!oracle->rep) { if((oracle->rep= malloc(MAX_SELECT_ORACLE * sizeof(char))) == NULL) { free(t); return (1); } *oracle->rep = 0; } strcat(oracle->rep, d); break; case ORACLE_PIE: if(!oracle->pie) { if((oracle->pie= malloc(MAX_SELECT_ORACLE * sizeof(char))) == NULL) { free(t); return (1); } *oracle->pie = 0; } strcat(oracle->pie, d); break; case ORACLE_QUE: strcat(t, d); break; case ORACLE_TYP: if(strstr(d,"tableau") || strstr(d,"TABLEAU")) oracle->typ = ORACLE_TABLEAU; else oracle->typ = ORACLE_GENERAL; break; } } fclose(fdd); } else strcat(t, keywords); for(c=t;isspace(*c);c++) ; for(cas=strlen(c)-1;(cas>1) && isspace(*(c+cas));cas--) *(c+cas) = 0; oracle->que = malloc((strlen(c)+1) * sizeof(char)); strcpy(oracle->que,c); free(t); if(oracle->rep) { t=oracle->rep = realloc(oracle->rep,(strlen(oracle->rep)+1)*sizeof(char)); if(isspace(*(t+strlen(t)-1))) *(t+strlen(t)-1) = 0; } if(oracle->ent) { t=oracle->ent = realloc(oracle->ent,(strlen(oracle->ent)+1)*sizeof(char)); if(isspace(*(t+strlen(t)-1))) *(t+strlen(t)-1) = 0; } if(oracle->pie) { t=oracle->pie = realloc(oracle->pie,(strlen(oracle->pie)+1)*sizeof(char)); if(isspace(*(t+strlen(t)-1))) *(t+strlen(t)-1) = 0; } return (0); } /* HTLoadOracle ** ------------ ** ** Interface HTRetrieve ===> oracle_recherche ** */ PUBLIC int HTLoadOracle ARGS4( CONST char *, arg, HTParentAnchor *, anAnchor, HTFormat, format_out, HTStream*, sink) #define REPL_BLANC '+' { char *keywords = strchr(arg,'?'); char *filename; char *c, *d; int erreur; RECH oracle; erreur = 0; *keywords++ = 0; if (!*keywords) keywords = NULL; else { char *p; for (p=keywords; *p; p++) if (*p == REPL_BLANC) *p = ' '; if(HTClientProtocol) HTUnEscape(keywords); } if(keywords) { { char * arg3; if (!(arg3 = HTTranslate(arg))) { if (logfile) { fprintf(logfile, "** SECURITY FAIL FOR ABOVE **\n"); fflush(logfile); } if (TRACE) fprintf(stderr, "HTHandle: Security fail ***\n"); return HTLoadError(sink,500, "Dociment address invalid or access not authorised\n"); } filename = HTParse (arg3, "", PARSE_PATH | PARSE_PUNCTUATION); free(arg3); } /* verification d'acces */ if(d = strstr(filename,"oracle/")) { for(c=keywords; (*c == '+') || isspace(*c); c++) ; oracle.cle = c; for(; *c; c++) if(*c == '@') *c = '>'; if(erreur = oracle_lit_fichier(filename,oracle.cle,&oracle)) { if(erreur == 1) { free(filename); return HTLoadError(sink,500, "Probleme d'allocation memoire\n"); } else { if (logfile) { fprintf(logfile, "** SECURITY FAIL FOR ABOVE **\n"); fflush(logfile); } if (TRACE) fprintf(stderr, "HTHandle: Security fail ***\n"); free(filename); return HTLoadError(sink,500, "Document address invalid or access not authorised\n"); } } /* extraction du nom de la base */ d += 7; /* #ts: !!! */ if(c = index(d,'/')) *c = 0; oracle.bas = malloc((strlen(d) + 1) * sizeof(char)); strcpy(oracle.bas,d); if(c) *c = '/'; { HTStructured * target = HTML_new(anAnchor, format_out, sink); oracle_recherche(&oracle, target); free(filename); } free(oracle.bas); if(oracle.que) free(oracle.que); if(oracle.ent) free(oracle.ent); if(oracle.pie) free(oracle.pie); } else { free(filename); return HTLoadError(sink,500, "Type d'interrogation inconnu ???\n"); } return HT_LOADED; } return HT_LOADED; }