/*
 * WLAH.CPP
 *
 * Active HTML Misc
 */

#include "gcomm.h"
#include "majorbbs.h"
#include "galacth.h"
#include "wlah.h"
#include "wlagent.h"
#include "infwlah.h"

INT errArray[ERR_LASTERROR]={ERROOPS,ERRPMISS,ERRNOUID,ERRDEMO};

MARKSOURCE(wlah);

CHAR*
strprpth(
CHAR* s)
{
     CHAR* dest=s;
     CHAR* src=s;

     while (*src != '\0') {
          if (*src == '.' && *(src+1) == '.') {
               src+=2;
               if (*src == '/') {
                    src++;
               }
          }
          else {
               *dest=*src;
               dest++;
               src++;
          }
     }
     *dest=*src;
     return(s);
}

CHAR *                             //   returns allocated buffer
urlEncodeStr(                      // encode special characters in a URL
const CHAR *src)                   //   unencoded URL
{
     ASSERT(src != NULL);
     size_t len=urlEncodeSize(src);
     CHAR *buf=new CHAR[len];
     return(urlEncodeBuf(buf,src,len));
}

size_t
urlEncodeSize(                     // size of encoded URL (incl '\0')
const CHAR *src)                   //   unencoded URL
{
     size_t len=0;
     CHAR c;
     ASSERT(src != NULL);
     while ((c=*src++) != '\0') {
          if (urlNeedEncode(c)) {
               len+=CSTRLEN("%XX");
          }
          else {
               ++len;
          }
     }
     return(len+1);
}

CHAR *                             //   returns pointer to destination
urlEncodeBuf(                      // encode special characters in URL
CHAR *buf,                         //   buffer to receive encoded string
const CHAR *src,                   //   unencoded URL
size_t bufSiz)                     //   size of destination buffer
{
     if (bufSiz > 0) {
          size_t i=0;
          CHAR c;
          ASSERT(src != NULL);
          ASSERT(buf != NULL);
          while ((c=*src++) != '\0' && i < bufSiz-1) {
               if (urlNeedEncode(c)) {
                    if (i >= bufSiz-CSTRLEN("%XX")) {
                         break;
                    }
                    buf[i++]='%';
                    buf[i++]=hexdig((c>>4)&0x0F);
                    buf[i++]=hexdig(c&0x0F);
               }
               else {
                    buf[i++]=c;
               }
          }
          buf[i]='\0';
     }
     return(buf);
}

size_t
urlDecodeSize(                     // size of decoded URL (incl '\0')
const CHAR *src)                   //   encoded URL
{
     size_t len=0;
     CHAR c;
     ASSERT(src != NULL);
     while ((c=*src++) != '\0') {
          if (c == '%' && isxdigit(*src) && isxdigit(*(src+1))) {
               src+=2;
          }
          ++len;
     }
     return(len+1);
}

CHAR *                             //   returns pointer to destination
urlDecodeBuf(                      // decode special characters in URL
CHAR *buf,                         //   buffer to receive decoded string
const CHAR *src,                   //   unencoded URL
size_t bufSiz)                     //   size of destination buffer
{
     if (bufSiz > 0) {
          size_t i=0;
          CHAR c;
          ASSERT(src != NULL);
          ASSERT(buf != NULL);
          while ((c=*src++) != '\0' && i < bufSiz-1) {
               if (c == '%' && isxdigit(*src) && isxdigit(*(src+1))) {
                    c=(hexval(*src++)<<4)|(hexval(*src++));
               }
               buf[i++]=c;
          }
          buf[i]='\0';
     }
     return(buf);
}

bool
urlNeedEncode(                     // does this character need to be encoded?
CHAR c)                            //   character to check
{
     return(c <= ' ' || c >= '~' || strchr("\t\"#%<>?[\]^`{|}",c) != NULL);
}

bool                               //   returns true if replaced a token
ReplaceStringFirst( // replace first of one string with another
CHAR * buf,                        //   buffer containing string to modify
size_t bufSiz,                     //   size of buffer
CHAR const * strOld,               //   old string to be replaced
CHAR const * strNew)               //   new string to replace with
{
     size_t sizOld=::strlen(strOld); // size of old string
     size_t sizNew=::strlen(strNew); // size of new string
     INT sizDif=(sizNew-sizOld);   // difference in sizes
     CHAR * cp=FindString(buf,strOld);
     if (cp != NULL) {
          if ((::strlen(buf)+sizDif) < bufSiz) {
               ::strmove(cp+sizNew,cp+sizOld);
               ::memcpy(cp,strNew,sizNew);
               return(true);
          }
     }
     return(false);
}

CHAR *                             //   returns a pointer to substring or NULL
FindString(                        // find a string within another
CHAR * str,                        //   string to search
CHAR const * sub)                  //   substring to search for
{
     if (*sub == '\0') {
          return(NULL);
     }
     while (*str != '\0') {
          if (tolower(*str) == tolower(*sub)) {
               CHAR const * scanStr=str+1;
               CHAR const * scanSub=sub+1;
               while (*scanStr != '\0' && *scanSub != '\0'
                   && tolower(*scanStr) == tolower(*scanSub)) {
                    ++scanStr;
                    ++scanSub;
               }
               if (*scanSub == '\0') {
                    return(str);
               }
          }
          ++str;
     }
     return(NULL);
}

CHAR *
SQLFixup(CHAR *stg)
// Certain character will screw up sql, so replace. (single quote, double quote, pipe)
{
   CHAR *s;
#pragma warn -pia
   s=stg; while (s=StrReplace(s,"\'","\'\'"));  // replace all occurances
   s=stg; while (s=StrReplace(s,"\"","\"\""));
   s=stg; while (s=StrReplace(s,"|","\\"));
#pragma warn +pia
   return(stg);
}

CHAR *   // Returns pointer to first location behind where NewStr was inserted
         // or NULL if OldStr was not found. This is useful for multiple replacements.
         // Eventually put this in \gcommlib
StrReplace(char *Str, char *OldStr, char *NewStr)
/*
 * StrReplace: Replace OldStr by NewStr in string Str.
 *
 * Str should have enough allocated space for the replacement, no check
 * is made for this. Str and OldStr/NewStr should not overlap.
 * The empty string ("") is found at the beginning of every string.
 *
 * Returns: pointer to first location behind where NewStr was inserted
 * or NULL if OldStr was not found.
 * This is useful for multiple replacements.
 * (be careful not to replace the empty string this way !)
 */
{
      int OldLen, NewLen;
      char *p, *q;

#pragma warn -pia
      if(!(p = strstr(Str, OldStr)))
#pragma warn +pia           
            return p;
      OldLen = strlen(OldStr);
      NewLen = strlen(NewStr);
      memmove(q = p+NewLen, p+OldLen, strlen(p+OldLen)+1);
      memcpy(p, NewStr, NewLen);
      return q;
}


VOID
logit(CHAR *logstg, ...)   // write to debug logfile
{
   va_list args;
   static CHAR buffer[1000];
   FILE *logp;

   if (!logiton)
      return;
// logfile is opened and closed each time a record is written
// to protect against GP data loss
   if ((logp=fopen(logfile,FOPAA)) == NULL)
      catastro("Cannot open logfile for Tell-a-friend");
// build buffer for variable string (hack because vfprintf not supported in WG2)
   va_start(args, logstg);
   vsprintf(buffer, logstg, args);
   va_end(args);

// write to file
   fprintf(logp,"%s,%-5.5s", ncdate(today()), nctime(now()) );
   fprintf(logp,",\"%s\",", usaptr->userid);
   fprintf(logp,"%s", buffer);
   fprintf(logp,"\n");
   fclose(logp);
}


