                          [The qDecoder Project]
  ------------------------------------------------------------------------

qDecoder Function Reference

   * Query and Cookie Handling Functions
        o qDecoder()
        o qValue()
        o qiValue()
        o qValueDefault()
        o qValueNotEmpty()
        o qValueReplace()
        o qGetFirstEntry()
        o qValueFirst()
        o qValueNext()
        o qValueAdd()
        o qValueRemove()
        o qCookieSet()
        o qCookieRemove()
        o qPrint()
        o qFree()

   * Session Functions
        o qSession()
        o qSessionAdd()
        o qSessionAddInteger()
        o qSessionUpdateInteger()
        o qSessionValue()
        o qSessionValueInteger()
        o qSessionRemove()
        o qSessionGetID()
        o qSessionGetCreated()
        o qSessionSetTimeout()
        o qSessionPrint()
        o qSessionSave()
        o qSessionFree()
        o qSessionDestroy()

   * Configuration File Parsing Functions
        o qfDecoder()
        o qfValue()
        o qfiValue()
        o qfValueFirst()
        o qfValueNext()
        o qfPrint()
        o qfFree

   * Configuration String Parsing Functions
        o qsDecoder()
        o qsValue()
        o qsiValue()
        o qsValueFirst()
        o qsValueNext()
        o qsPrint()
        o qsFree

   * SED: Context Generation Functions
        o qSedArgAdd()
        o qSedArgPrint()
        o qSedArgFree()
        o qSedFile()
        o qSedStr()

   * AWK: Pattern Scanning Functions
        o qAwkOpen()
        o qAwkNext()
        o qAwkClose()

   * Search Key Words & Pattern Matching Functions
        o qArgMake()
        o qArgMatch()
        o qArgEmprint()
        o qArgPrint()
        o qArgFree()

   * HTTP Response Functions
        o qContentType()
        o qGetContentFlag()
        o qResetContentFlag()
        o qRedirect()

   * Encoding/decoding Functions
        o qURLencode()
        o qURLdecode
        o qMD5Str()
        o qMD5File()

   * String Handling Functions
        o qPrintf()
        o qPuts()
        o qRemoveSpace()
        o qStrReplace()
        o qStr09AZaz()
        o qStrupr()
        o qStrlwr()
        o qStristr()
        o qStricmp()
        o qStrincmp()
        o qitocomma()

   * File Handling Functions
        o qCheckFile()
        o qCatFile()
        o qReadFile()
        o qSaveStr()
        o qFileSize()
        o qfGetLine()

   * Validation Functions
        o qCheckEmail()
        o qCheckURL()

   * Download Handling Functions
        o qDownload()
        o qDownloadMime()

   * Counter Handling Functions
        o qCountRead()
        o qCountSave()
        o qCountUpdate()

   * Environment Related Functions
        o qCGIenv()
        o qCGIname()
        o qGetenvDefault()

   * Time Functions
        o qGetTime()
        o qGetGMTime()

   * Error Handling Functions
        o qError()
        o qErrorContact()
        o qErrorLog()

   * Miscellaneous Functions
        o qFreeAll()
        o qReset()
        o qUniqueID()

  ------------------------------------------------------------------------

Query and Cookie Handling Functions

qDecoder()

  Syntax: int qDecoder(void);
Function: Interprets encoded query strings and stores them in the linked-list.
          COOKIE, GET, POST(including multipart/form-data encoding) are
          supported.
  Return: In case of success, returns the number of received arguments. In case
          of failure, return -1.
    Note: The parsing sequence is (1)COOKIE (2)GET (3)POST. Thus if same query
          names (which are sent by different method) exist, qValue() will return
          the value of COOKIE.

          This function, qDecoder(), is called automatically when you use
          qValue() or related functions, so you do not need to call directly.

          In case of multipart/form-data encoding(used for file uploading), the
          variables of "variable_name.length" and "variable_name.name" are
          automatically inserted. The number of bytes of data is stored in
          "variable_name.length", and the file names(file name itself, path
          information will be removed) transmitted by users are stored in
          "variable_name.name". (In case of "C:Dataa.gif", only "a.gif" is
          stored.) In counter of return values, a total of 3 lists are stored
          but since the 3 lists are for one data, they are regarded as 1 list.
 Example: Example 1: application/x-www-form-urlencoded (GET/POST Method)

          [HTML]
          <form method="post" action="input.cgi">
            User ID <input type="text" name="userID"><br>
            <input type="submit">
          </form>

          [Parsed Queries]
          name  = "userID"
          value = "character strings users input"

          [C]
          #include <stdio.h>
          #include "qDecoder.h"
          void main(void) {
            char *id;
            qContentType("text/html");
            id = qValue("userID");
            printf("%s", id);
          }

          Example 2: multipart/form-data

          [HTML]
          <form method="post" action="upload.cgi" enctype="multipart/form-data">
            User ID <input type="text" name="userID"><br>
            Attachment <input type="file" name="binary"><br>
            <input type="submit">
          </form>

          [Parsed Queries]
          name  = "userID"
          value = "character strings users input"

          name  = "binary"
          value = "binary data of a.gif"
          name  = "binary.length"
          value = "128"
          name  = "binary.filename"
          value = "a.gif"

          [C]
          #include <stdio.h>
          #include <stdlib.h>
          #include "qDecoder.h"

          void main(void) {
            FILE *fp;
            char *userID;
            char *filedata, *filename;
            int  filelength, i;

            qContentType("text/plain");

            userID = qValue("userID");

            filedata   = qValue("binary");
            filelength = qiValue("binary.length");
            filename   = qValue("binary.filename");

            fp = fopen(filename, "wb");
            for(i = filelength; i > 0; i--) fprintf(fp, "%c", *(filedata++));
            fclose(fp);

            printf("%s : %s(%s bytes) saved.", userID, filename, filelength);
          }

qValue()

   Syntax: char *qValue(char *format, ...);
 Function: Finds out the value (COOKIE, GET, POST) for variable names at
           the linked-list and hands over the pointers.
   Return: The pointer of the variable value if a variable name exists.
           NULL if there is no variable name.
     Note: qValue() returns only the pointers of query index created by
           qDecoder().Accordingly, you should not free() the pointers
           received at qValue. The deallocation of allocated memory should
           be performed through the qFree() function (generally before the
           program is shut down).

           Internally calls qDecoder if qDecoder() has not been called
           before.
  Example: char *test;
           test = qValue("VARIABLE NAME");

           char *test;
           int i = 1;
           test = qValue("COUNT.%d", i);

qiValue()

   Syntax: int qiValue(char *format, ...);
 Function: Same as that of qValue(). But this returns the value(numeric
           character string) after converting it into integers.
   Return: In case of success, returns the integer value for the variable
           value (numericcharacter string). If a variable name does not
           exist or cannot be converted, returns 0.
  Example: int test;
           test = qiValue("VARIABLE NAME");

           int test, i = 1;
           test = qValue("COUNT.%d", i);

qValueDefault()

   Syntax: char *qValueDefault(char *defstr, char *format, ...);
 Function: This is a simple function of qValue() used for setting up a
           primary argument when there is no query.
   Return: Same as that of qValue(). But this returns the pointer of
           defstr when there is no query.
  Example: value = qValueDefault("Seoul", "COUNTRY");

qValueNotEmpty()

   Syntax: char *qValueNotEmpty(char *errmsg, char *format, ...);
 Function: Displays specified error messages by using the qError()
           function when there is no query or blank character strings ("")
           are returned.
   Return: Same as qValue except that it has "error handling" within for
           NULL.
  Example: value = qValueNotEmpty("Enter country name", "COUNTRY");

qValueReplace()

   Syntax:char *qValueReplace(char *mode, char *name, char *tokstr, char
          *word);
 Function:Transposes tokens and character strings for the linked-list
          character strings.
   Return:Transposed character-string pointers.
     Note:Basically, qValueReplace() is the wrapping function of
          qStrReplace(). The difference is that the source character
          string is the query value (the value of the linked-list for
          names) in it, and the conversion can be directly done to the
          linked-list itself.
          Accordingly, the usage of arguments of qValueReplace() is
          basically the same as that of qStrReplace().

          The 'name' argument is the query name of the linked-list to be
          used as source character strings. And it is the source character
          string to be used when the corresponding value is transposed.

          The 'mode' argument is a character string made up of two
          separate characters like "sr".

          The first character defines the transposition method. 't' or 's'
          can be located in its place. 't' stands for [t]oken. It compares
          the source character strings (the value character string of the
          linked-list for given names) using each character of the tokstr
          character string as a token and transposes the matching
          characters into a word character string. 's' stands for
          [s]tring. It transposes into a word character string the tokstr
          matching character strings appearing inside the source string
          using the tokstr string itself as a token.

          The second character stands for the recording type of the
          transposed character string. Eigher 'n' or 'r' can be used for
          it. 'n' stands for [n]ew. It makes the corresponding pointer
          returned by storing the transposed result character string in a
          new memory space. Accordingly, the source string linked-list
          should be maintained in its original state, and the pertinent
          memory needs to be free() from the user's aspect. 'r' stands for
          [r]eplace and means overwriting the transposition results on the
          linked-list itself. This is accomplished through the internal
          reallocation of memory.

          As a result, there are 4 possible occasions in which the 'mode'
          argument can be assembled.

           Mode "tn" : [t]oken transposition & stores results in a [n]ew
          space and returns
           Mode "tr" : [t]oken transposition & [r]eplaces the linked-list
          itself
           Mode "sn" : [s]tring transposition & stores results in a [n]ew
          space and returns
           Mode "sr" : [s]tring transposition & [r]eplaces the linked-list
          itself
  Example:Example 1)
            char *retstr, *mode;
            mode = qValue("mode");
            qContentType("text/plain");

            printf("before %s : srcstr = %s\n", mode, qValue("srcstr"));
            retstr = qValueReplace(mode, "srcstr", "hello", "[?]");
            printf("after  %s : srcstr = %s\n", mode, qValue("srcstr"));
            printf("            retstr = %s\n\n", retstr);
            if(mode[1] == 'n') free(retstr);
            return 0;

          Result 'tn')
            before tn : srcstr = hello world
            after  tn : srcstr = hello world
                        retstr = [?][?][?][?][?] w[?]r[?]d

          Result 'tr')
            before tr : srcstr = hello world
            after  tr : srcstr = [?][?][?][?][?] w[?]r[?]d
                        retstr = [?][?][?][?][?] w[?]r[?]d

          Result 'sn')
            before sn : srcstr = hello world
            after  sn : srcstr = hello world
                        retstr = [?] world

          Result 'sr')
            before sr : srcstr = hello world
            after  sr : srcstr = [?] world
                        retstr = [?] world

qGetFirstEntry()

   Syntax: Q_Entry *qGetFirstEntry(void);
 Function: Returns the first Q_Entry pointer of the linked-list.
   Return: If there is stored data in linked-list, return Q_Entry first
           pointer. Or return NULL.
     Note: This is used to acquire a root pointer when the linked-list
           used by qDecoder() is to be directly manipulated.
  Example: Q_Entry *first;
           first = qGetFirstEntry();

qValueFirst()

  Syntax: char *qValueFirst(char *format, ...);
Function: Used for patching the arguments having an identical variable name
          inregular sequence.
  Return: In case of success, returns the first variable-value pointer for
          the arguments having an identical variable name. If there is no
          variable name, returns NULL.
 Example: char *list;
          for(list = qValueFirst("checklist"); list; list = qValueNext()) {
            printf("checklist = %s<br>\n", list);
          }

qValueNext()

  Syntax: char *qValueNext(void);
Function: Continues to find out with qValueFirst().
  Return: In case of success, returns the pointer of the variable value. If
          there is no more identical variable name, returns NULL.
 Example: char *list;
          for(list = qValueFirst("checklist"); list; list = qValueNext()) {
            printf("checklist = %s<br>\n", list);
          }

qValueAdd()

   Syntax: char *qValueAdd(char *name, char *format, ...);
 Function: Force to add given name and value to linked list.
   Return: String pointer of added entry in linked-list.
     Note: If same name exists, it'll be replaced.
  Example: qValueAdd("NAME", "Seung-young Kim");
           name = qValue("NAME");

qValueRemove()

   Syntax: void qValueRemove(char *format, ...);
 Function: Remove entry from linked list.
  Example: qValueRemove("NAME");

qCookieSet()

  Syntax: void qCookieSet(char *name, char *value, int exp_days, char *path, char *domain,
          char *secure);
Function: Sets up those cookies that correspond to name=value.
    Note: When cookies are set up through qCookieSet(), the point of time when values are
          handed over through qValue() is when the next program is called. In some
          implementations, however, cookies need to be set up for the simplicity of logic
          while, at the same time, this needs to be applied to other routines. In this case,
          qValueAdd() can prevent the alteration of logic and the waste of additional codes
          by adding values to the cookie linked-list. But with regard to qCookieSet(),
          setting up cookies at clients (browsers) does not succeed always. Thus, users
          should be careful when using qValueAdd().

          This should be used before qContentType() is called.
 Example: char *name = "NAME", *value = "Kim";

          // Apply the NAME=Kim information in the current domain and directory for 30 days.
          qSetCookie(name, value, 30, NULL, NULL, NULL);

          // Apply the NAME=Kim information to the "/" directory of "ANYTHING.qdecoder.org"
          // until the browser is shut down.
          qSetCookie(name, value, 0, "/", ".qdecoder.org", NULL);

          // As for the followings, cookies will be set up only when security
          // requirements are satisfied.
          qSetCookie(name, value, 0, NULL, NULL, "SECURE");

          // As for the followings, you can remove cookies.
          qSetCookie(name, "", -1, NULL, NULL, NULL);

qCookieRemove()

   Syntax:void qCookieRemove(char *name, char *path, char *domain, char
          *secure);
 Function:Remove cookie from client(browser).
     Note:The arguments(path, domain, secure) must be exactly same as the
          arguments of qCookieSet().

          When cookies are removed through qCookieRemove(), the point of
          time when values in linked-list removed is when the next program
          is called. In some implementations, however, cookies need to be
          removed for the simplicity of logic while, at the same time,
          this needs to be applied to other routines. In this case,
          qValueRemove() can prevent the alteration of logic and the waste
          of additional codes by removing values to the linked-list. But
          with regard to qCookieRemove(), removing cookies at clients
          (browsers) does not succeed always. Thus, users should be
          careful when using qValueRemove().
  Example:qCookieSet("NAME", "VALUE", 0, NULL, NULL, NULL);
          qCookieRemove("NAME", NULL, NULL, NULL);

          qCookieSet("NAME", "VALUE", 0, "/", NULL, NULL);
          qCookieRemove("NAME", "/", NULL, NULL);

          qCookieSet("NAME", "VALUE", 0, "/", "www.qdecoder.org", NULL);
          qCookieRemove("NAME", "/", "www.qdecoder.org", NULL);

qPrint()

   Syntax: int qPrint(void);
 Function: Displays all the arguments transmitted for the purpose of
           debugging programs.
   Return: The number of arguments.
  Example: qPrint();

qFree()

   Syntax: void qValueAdd(char *name, char *value);
 Function: Deallocates the allocated memory by qDecoder().
     Note: Please refer qFreeAll() too.
  Example: qFree();

  ------------------------------------------------------------------------

Session Functions

qSession()

  Syntax: void qSession(char *repository);
Function: Start Session.
    Note: To use session, you must call qSession() at the start. qSession() stores
          32 bytes session id to client using cookie, then stores session data to
          server side. By default, session data will be expired in 1800 seconds
          since last access. You can adjust this period by using
          qSessionSetTimeout().

          To use session on clients which does not support cookie such like WAP
          phone.
          add QSESSIONID into your link below.

          http://domain/application?QSESSIONID=ab77bbb49dd61cd510db121a948ab4d9&other=arguments

          qSession() will store default session values below.

           _Q_SESSIONID   : Session ID (ex: ab77bbb49dd61cd510db121a948ab4d9)
           _Q_CREATED-GMT : Created GMT Time (ex: Thu, 19-Jul-2001 21:50:19 GMT)
           _Q_CREATED     : Created Time (ex: 995579419)
           _Q_CONNECTIONS : Connection Count (ex: 15)
           _Q_INTERVAL    : Expire Period/Seconds (ex: 1800)

          Session data is stored in filesystem(unix: "/tmp", win32:
          "C:\Windows\Temp").
          You can change storage path using argument 'repository' when you call
          qSession(). qSession() generates "qsession-" prefixed files in session
          storage and manage automatically. (In case of WIN32 environment, the
          session files in repository are not managed automatically, so you would
          better to clean periodically repository)

          Session data will be stored when qSessionFree(), qSessionSave() or
          qFreeAll() is called.
 Example: qSession(NULL);   // use default storage
          qSession("/tmp"); // use /tmp for session storage

qSessionAdd()

   Syntax: char *qSessionAdd(char *name, char *format, ...);
 Function: Add session value.
   Return: Stored String pointer of value.
  Example: qSessionAdd("name", "qDecoder");
           qSessionAdd("cginame", "%s", qCGIname());

qSessionAddInteger()

   Syntax: int qSessionAddInteger(char *name, int valueint);
 Function: Add session value of integer type.
   Return: Stored integer value.
  Example: qSessionAddInteger("count", 32);

qSessionUpdateInteger()

   Syntax: int qSessionUpdateInteger(char *name, int plusint);
 Function: Update session value of integer type.
   Return: Updated integer value.

qSessionValue()

   Syntax: char *qSessionValue(char *format, ...);
 Function: Return session value.
   Return: Success pointer of value string, Fail NULL.
  Example: char *value;
           value = qSessionValue("name");
           value = qSessionValue("%d.name", i);

qSessionValueInteger()

   Syntax: int qSessionValueInteger(char *format, ...);
 Function: Return session value of integer type.
   Return: Success integer of value, Fail 0.
  Example: int value;
           value = qSessionValueInteger("count");

qSessionRemove()

   Syntax: void qSessionRemove(char *format, ...);
 Function: Remove session variable.
  Example: qSessionRemove("name");
           qSessionRemove("%d.name", i);

qSessionGetID()

   Syntax: char *qSessionGetID(void);
 Function: Return current session id.
   Return: String pointer of session id(32bytes).
  Example: char *sessionid;
           char *sessionidstr[32+1];

           sessionid = qSessionGetID();
           strcpy(sessionidstr, sessionid);

qSessionGetCreated()

   Syntax: time_t qSessionGetCreated(void);
 Function: Return session created time in seconds.
   Return: Value of created time in seconds since 0 hours, 0 minutes, 0
           seconds, January 1, 1970.
  Example: time_t created;
           struct tm *gmtime;
           created = qSessionGetCreated();
           gmtime = gmtime(&created);

qSessionSetTimeout()

   Syntax: void qSessionSetTimeout(time_t seconds);
 Function: Change current session expiration period.
   Return: New expiration period.
     Note: By default, expiration period is 1800 seconds.
  Example: qSessionSetTimeout((time_t)3600);

qSessionPrint()

   Syntax: int qSessionPrint(void);
 Function: Displays all the session variables for the purpose of debugging
           programs.
   Return: The number of variables.
  Example: qSessionPrint();

qSessionSave()

   Syntax: void qSessionSave(void);
 Function: Save session data immediately.
     Note: qSessionSave() will be automatically called, when you
           callqSessionFree() at the end of program. If program can be
           quitted before qSessionFree(), you can use
           qSessionSave() directly to protect session data.
  Example: qSessionSave();

qSessionFree()

   Syntax: void qSessionFree(void);
 Function: Save session data and deallocate memories.
  Example: qSessionFree();

qSessionDestroy()

   Syntax: void qSessionDestroy(void);
 Function: Destroy current session.
  Example: qSessionDestroy();

  ------------------------------------------------------------------------

Configuration File Parsing Functions

qfDecoder()

   Syntax: Q_Entry *qfDecoder(char *filename);
 Function: Reads file and stores in the linked-list. (no limitations to
           the line length of files)
   Return: The first record pointer of the linked-list, NULL in case of
           failure.
     Note: Reads the file of the following format and stores them in the
           linked-list.

           ---- test.conf ----
           # this is comment.
           name  = Seung-young Kim
           age   = 30
           addr  = Korea
           -------------------

           Regarded as explanatory notes, those lines starting with
           sharps(#) are not interpreted.
  Example: Q_Entry *first;
           first = qfDecoder("test.conf");
           if(first == NULL) qError("File not found.");

qfValue()

   Syntax: char *qfValue(Q_Entry *first, char *format, ...);
 Function: Acquires the variable value of variable names.
   Return: In case of success, returns the pointer of the variable value.
           In case of failure, returns NULL.
  Example: char *value;
           value = qfValue(first, "name");

qfiValue()

   Syntax: int qfiValue(Q_Entry *first, char *format, ...);
 Function: Converts the variable values into integers and hands them over.
   Return: In case of success, reurns the integer value for the variable
           value (numericcharacter strings). When a variable name does not
           exist or the pertinent value cannot be convertedinto integers,
           returns 0.
  Example: int count;
           count = qfiValue(first, "count");

qfValueFirst()

  Syntax: char *qfValueFirst(Q_Entry *first, char *format, ...);
Function: Used for patching the arguments having an identical variable name
          inregular sequence.
  Return: In case of success, returns the first variable-value pointer for
          the arguments having an identical variable name. If there is no
          variable name, returns NULL.
 Example: char *list;
          for(list = qfValueFirst("checklist"); list; list = qfValueNext()) {
            printf("checklist = %s<br>\n", list);
          }

qfValueNext()

  Syntax: char *qfValueNext(void);
Function: Continues to find out with qfValueFirst().
  Return: In case of success, returns the pointer of the variable value. If
          there is no more identical variable name, returns NULL.
 Example: char *list;
          for(list = qfValueFirst("checklist"); list; list = qfValueNext()) {
            printf("checklist = %s<br>\n", list);
          }

qfPrint()

   Syntax: int qfPrint(Q_Entry *first);
 Function: Displays all the interpreted arguments for debugging programs.
   Return: The number of arguments.
  Example: qfPrint(first);

qfFree

   Syntax: void qfFree(Q_Entry *first);
 Function: Deallocates allocated memory.
  Example: qfFree(first);

  ------------------------------------------------------------------------

Configuration String Parsing Functions

qsDecoder()

   Syntax: Q_Entry *qsDecoder(char *str);
 Function: Reads string and stores in the linked-list. (no limitations to
           the line length of files)
   Return: The first record pointer of the linked-list, NULL in case of
           failure.
     Note: Reads the file of the following format and stores them in the
           linked-list.

           ---- test.conf ----
           # this is comment.
           name  = Seung-young Kim
           age   = 30
           addr  = Korea
           -------------------

           Regarded as explanatory notes, those lines starting with
           sharps(#) are not interpreted.
  Example: Q_Entry *FirstRecord;
           char *str="name=Seung-young Kim\nage=26\naddr=Korea";
           FirstRecord = qsDecoder(str);

qsValue()

   Syntax: char *qsValue(Q_Entry *first, char *format, ...);
 Function: Acquires the variable value of variable names.
   Return: In case of success, returns the pointer of the variable value.
           In case of failure, returns NULL.
  Example: char *value;
           value = qsValue(first, "name");

qsiValue()

   Syntax: int qsiValue(Q_Entry *first, char *format, ...);
 Function: Converts the variable values into integers and hands them over.
   Return: In case of success, reurns the integer value for the variable
           value (numericcharacter strings). When a variable name does not
           exist or the pertinent value cannot be convertedinto integers,
           returns 0.
  Example: int count;
           count = qsiValue(first, "count");

qsValueFirst()

  Syntax: char *qsValueFirst(Q_Entry *first, char *format, ...);
Function: Used for patching the arguments having an identical variable name
          inregular sequence.
  Return: In case of success, returns the first variable-value pointer for
          the arguments having an identical variable name. If there is no
          variable name, returns NULL.
 Example: char *list;
          for(list = qsValueFirst("checklist"); list; list = qsValueNext()) {
            printf("checklist = %s<br>\n", list);
          }

qsValueNext()

  Syntax: char *qsValueNext(void);
Function: Continues to find out with qfValueFirst().
  Return: In case of success, returns the pointer of the variable value. If
          there is no more identical variable name, returns NULL.
 Example: char *list;
          for(list = qsValueFirst("checklist"); list; list = qsValueNext()) {
            printf("checklist = %s<br>\n", list);
          }

qsPrint()

   Syntax: int qsPrint(Q_Entry *first);
 Function: Displays all the interpreted arguments for debugging programs.
   Return: The number of arguments.
  Example: qsPrint(first);

qsFree

   Syntax: void qsFree(Q_Entry *first);
 Function: Deallocates allocated memory.
  Example: qsFree(first);

  ------------------------------------------------------------------------

SED: Context Generation Functions

qSedArgAdd()

   Syntax: Q_Entry *qSedArgAdd(Q_Entry *first, char *name, char *format,
           ...);
 Function: Add a variable to argument list for use of qSedFile() and
           qSedStr().
   Return: Pointer of argument list.
  Example: Q_Entry *args;

           args = NULL;
           args = qSedArgAdd(args, "${NAME}", "Seung-young Kim");
           args = qSedArgAdd(args, "${HOBBY}", "Playing Guitar");

qSedArgPrint()

   Syntax: int qSedArgPrint(Q_Entry *first);
 Function: Displays all the variables for debugging programs.
   Return: The number of arguments.
  Example: qSedArgPrint(first);

qSedArgFree()

   Syntax: void qSedArgFree(Q_Entry *first);
 Function: Deallocates allocated memory by qSedArgAdd().
  Example: qSedArgFree(first);

qSedFile()

  Syntax: int qSedFile(Q_Entry *first, char *filename, FILE *fpout);
Function: Replaces specified symbols with defined character strings in files and displays
          them. And supports part of the SSI grammar.
  Return: In case of success, returns 1. When files cannot be opened, returns 0.
    Note: Plays a similar function to the SED command of UNIX systems.

          ---- ex) streamedit.html.in ----
          <!--#include file="streamedit-header.html.in"-->
          <p>Hi <b>${NAME}</b>.
          <p>You got a really cool hobby.
          <br>I'm sure that your hobby, <b>${HOBBY}</b>, can make your life more
          compatible.
          <p>Bye :)
          <!--#include file="streamedit-tailer.html.in"-->
          ---------------------

          By utilizing qSedFile, CGI programming can be performed even without including
          HTML codes in the programs. Thus, UI-related debugging time can be reduced to a
          great extent, and the design and development works can be separately performed.
          Package products can be easily customized by users.
          filename is an input(target) file while fpout stands for output streams. When
          you wish to display the results in files, open files in "w" and then, hand over
          the corresponding file pointers. And if you wish to display them on-screen, just
          specify stdout.

          It interprets the SSI grammar. (Currently, only [an error occurred while
          processing this directive] is supported.) If there is the following lines in a
          document, the corresponding document is included in the display. And the
          replacement and SSI functions are valid for the included document. (Cascading)

          <!--#include file="streamedit-header.html.in"-->

          Note) The included file can be marked by relative paths on the basis of the
          location where CGI is executed. Or it may be marked by system absolute paths.

          If you wish to use the SSI function only without replacing character strings,
          transmit the NULL value using the arg argument as follows:

          ex) qSedFile(NULL, "streamedit.html.in", stdout);
 Example: Q_Entry *args;
          char *name, *hobby;

          qContentType("text/html");

          name = qValueDefault("Not Found", "name");
          hobby = qValueDefault("Not Found", "hobby");

          args = NULL;
          args = qSedArgAdd(args, "${NAME}", name);
          args = qSedArgAdd(args, "${HOBBY}", hobby);

          if(qSedFile(args, "streamedit.html.in", stdout) == 0) qError("File not found.");

          qSedArgFree(args);

qSedStr()

   Syntax: int qSedStr(Q_Entry *first, char *srcstr, FILE *fpout);
 Function: Plays same functions as qSedFile(), but input is done in
           character strings.
   Return: Same as that of qSedFile().
  Example: Q_Entry *args;
           char *sp;

           sp = "My name is ${NAME}.";
           args = NULL;
           args = qSedArgAdd(args, "${NAME}", "Seung-young Kim");

           qSedStr(args, sp, stdout);

           qSedArgFree(args);

  ------------------------------------------------------------------------

AWK: Pattern Scanning Functions

qAwkOpen()

   Syntax: int qAwkOpen(char *filename, char separator);
 Function: Opens files and sets up delimiters.
   Return: In case of success, returns 1. When files cannot be opened,
           return 0.
     Note: Plays a similar function to the AWK command of UNIX systems.

           ---- ex) /etc/passwd ----
           shpark:x:1008:1000:Sang-hyun Park:/home/shpark:/bin/csh
           teamwork:x:1011:1000:Seung-young Kim:/home/teamwork:/bin/csh
           kikuchi:x:1015:2000:KIKUCHI:/home/kikuchi:/bin/csh
           -------------------------
  Example: qAwkOpen("/etc/passwd", ':');

qAwkNext()

  Syntax: int qAwkNext(char array[][256]);
Function: Reads a line and stores it in an array given as a argument.
  Return: In case of success, returns the number of fields. The end of files, -1.
    Note: There is no limitation to the length of lines. But each field should not
          exceed 256 bytes.
 Example: char array[7][256];
          qAwkOpen("/etc/passwd", ':');
          for( ; qAwkNext(array) > 0; ) printf("ID=%s, Name=%s", array[0], array[5]);
          qAwkClose();

qAwkClose()

   Syntax: int qAwkClose(void);
 Function: Closes open files.
   Return: In case of success, returns 1. When there is no open file,
           returns 0.
  Example: qAwkClose();

  ------------------------------------------------------------------------

Search Key Words & Pattern Matching Functions

qArgMake()

   Syntax: int qArgMake(char *str, char **qlist);
 Function: Divides queries into tokens. The delimiters are generally space
           characters. And the redundant spaces between tokens and the
           spaces before and after queries are disregarded.
   Return: The number of divided tokens.
     Note: A group of functions related to search words classifies query
           character strings on the basis of spaces and double quotation
           marks(") and then, stores them in the lists. And it provides a
           group of functions connected with the matching tests and display
           of target character strings.

           ---- Example ----
           Query Input: I am a "pretty girl"
           -----------------
                |  |
                V  V
           ---- qArgMake() ----
           qlist[0] = I
           qlist[1] = am
           qlist[2] = a
           qlist[3] = pretty girl
           qlist[4] = NULL
           Return: 4 (4 Tokens)
           --------------------
                |  |
                V  V
           ---- qArgPrint() ----
           'I' (1 bytes)
           'am' (2 bytes)
           'a' (1 bytes)
           'pretty girl' (11 bytes)
           ---------------------
                |  |
                V  V
           ---- qArgMatch() ----
           Target String: Hi, I'm a pretty boy. Are you pretty girl?
                          =  =   =             =       ===========
                          0  0   2             2             3
           Return: 3 (3 matches: qlist[0], qlist[2], qlist[3])
           ---------------------
                |  |
                V  V
           ---- qArgEmprint() ----
           Target String..: Hi, I'm a pretty boy. Are you pretty girl?
           Result.........: Hi, I'm a pretty boy. Are you pretty girl?
                            =  =   =             =       ===========
                            1  2   3             4             5
           Return: 5 (5 matches)
           -----------------------
  Example: char *query="I am a \"pretty girl\".", *qlist[MAX_TOKENS];
           int queries;
           queries = qArgMake(query, qlist);

qArgMatch()

  Syntax: int qArgMatch(char *str, char **qlist);
Function: Performs token-matching tests without distinguishing lowercase/uppercase
          letters.
  Return: Returns the number of tokens found in a specific character string.
    Note: Counts only once the same tokens even if they are matched repeatedly.
          Refer to the return value of qArgemprint() for the total matching counts
          in a character string including repeated matchings. Being divided into a
          hundred parts by the total number of the tokens acquired at qArgMake(),
          these values can be used for calculating the search accuracy.
 Example: int matches;
          matches = qArgMatch("Hi, I'm a pretty boy. Are you pretty girl?", qlist);

qArgEmprint()

  Syntax: int qArgEmprint(int mode, char *str, char **qlist);
Function: Bold-prints the parts matched with tokens in a character string.
          This does not distinguish lowercase/uppercase letters.
  Return: Returns the number of tokens found in a character string. And unlike
          qArgMatch(), this returns all the matching counts including repeated
          matchings.
    Note: The mode value is same as that of qPrintf(). For a general purpose,
          1 can be generally used.
 Example: qArgEmprint(1, "Hi, I'm a pretty boy. Are you pretty girl?", qlist);

qArgPrint()

   Syntax: int qArgPrint(char **qlist);
 Function: Displays all the tokens interpreted for debugging programs.
  Example: qArgPrint(qlist);

qArgFree()

   Syntax: void qArgFree(char **qlist);
 Function: Deallocates qlist which memory is allocated to.
  Example: qArgFree(qlist);

  ------------------------------------------------------------------------

HTTP Response Functions

qContentType()

   Syntax: void qContentType(char *mimetype);
 Function: Prints MimeType.
     Note: Executed only once even if it is called many times.
  Example: qContentType("text/html");  // when displaying HTML
           qContentType("image/gif");  // when displaying the GIF image

qGetContentFlag()

  Syntax: int qGetContentFlag(void);
Function: Check execution of qContentType().
  Return: If qContentType() is executed before, returns 1. Or returns 0.
 Example: if(qGetContentFlag() == 0) qCookieRemove("NAME", NULL, NULL, NULL);

qResetContentFlag()

   Syntax: void qResetContentFlag(void);
 Function: Sets the internal flag of qContentType() to the initial status.
     Note: qContentType() is executed only once even if it is called many
           times. When you need to forcibly display it again, call
           qContentType() after executing qResetContentFlag().
  Example: qContentType("text/html");
           ...some business logic here...

           qResetContentFlag();
           qContentType("text/html");
           ...some business logic here...

           qResetContentFlag();
           qContentType("text/html");
           ...some business logic here...

qRedirect()

   Syntax: void qRedirect(char *url);
 Function: Jumps to a specific page using the Location: headers of HTTP.
     Note: Since qRedirect uses the HTTP headers, qConteneType() should be
           the only command that streams out in the corresponding process.
  Example: qRedirect("http://www.qdecoder.org/");

  ------------------------------------------------------------------------

Encoding/decoding Functions

qURLencode()

   Syntax: char *qURLencode(char *str);
 Function: Encodes character strings in URL.
   Return: The character strings encoded in URL are returned with memory
           allocation. Deallocation(free) needs to be done by users.
     Note: It does not encode '@', '.', '/', '\', '-', '_', ':'
           characters.
  Example: char *encstr;
           encstr = qURLencode("Hello!");

qURLdecode

   Syntax: char *qURLdecode(char *str);
 Function: Decodes the character string that is URL-encoded into %xx.
   Return: Decoded string pointer.
     Note: It stores decoded string into str directly.
  Example: char *encstr;
           qURLdecode(encstr);

qMD5Str()

   Syntax: char *qMD5Str(char *string);
 Function: Calculate a message-digest fingerprint (checksum) for a string.
   Return: String pointer of 32 bytes fingerprint.
     Note: The return string pointer is declared as static inside the
           functions instead of being returned with memory allocation.
           This is to remove the inconvenience that users have to free()
           memory every tiem. Accordingly, it should be noted that the
           previous value is deleted whenever the functions are performed.
           And you should not modify or free() it directly.
  Example: printf("Hash Result = %s", MD5Str("Hello"));

           [Result]
           Hash Result = 8b1a9953c4611296a827abf8c47804d7

qMD5File()

   Syntax: char *qMD5File(char *string);
 Function: Calculate a message-digest fingerprint (checksum) for a file.
   Return: String pointer of 32 bytes fingerprint.
     Note: The return string pointer is declared as static inside the
           functions instead of being returned with memory allocation.
           This is to remove the inconvenience that users have to free()
           memory every tiem. Accordingly, it should be noted that the
           previous value is deleted whenever the functions are performed.
           And you should not modify or free() it directly.
  Example: printf("Hash Result = %s", MD5File("qDecoder.tar.Z"));

           [Result]
           Hash Result = 499589b930e48996a64317c79e6cc36b

  ------------------------------------------------------------------------

String Handling Functions

qPrintf()

  Syntax: int qPrintf(int mode, char *format, ...);
Function: Usage is same as that of printf(). Checks whether the HTML tag is applied and performs automatic links.
  Return: In case of success - returns the number of displayed bytes. In case of failure, returns EOF.
    Note: The maximum size of the assembled strings should not exceed 10K(1024 * 10 - 1).

          Mode 0 : Same as printf(). Means HTML is applied.
          Mode 1 : Displays the HTML tag itself. No linking parts.
          Mode 2 : Mode 1 + automatic linking.
          Mode 3 : Mode 2 + Displays the previous screen(target=_top) when link is clicked.
          Mode 4 : Disregards the HTML tag. Not displayed.
          Mode 5 : Mode 4 + automatic linking.
          Mode 6 : Mode 5 + Displays the previous screen(target=_top) when link is clicked.
          Mode 10 : Mode 0 + Convert
          Mode 11 : Print HTML TAG + Convert
          Mode 12 : Mode 11 + Auto Link
          Mode 13 : Mode 12 + Auto Link to _top frame
          Mode 14 : Waste HTML TAG + Convert
          Mode 15 : Mode 14 + Auto Link
          Mode 16 : Mode 15 + Auto Link to _top frame

          Convert : " "   -> " "
                   "  "  -> "  "
                   "   " -> "   "
                   "\r"  -> disregard
                   "\n"  -> "<br>\n"

          The Mode values of 10 and over can be efficiently used when successive
          blank is to be displayed on the screen without using the <pre> tag.
          In this case, the line change is automatically performed according to
          the changes of  screen width.
 Example: qPrintf(i, "Mode %d: <font>\"http://www.qdecoder.org\"</font>\n", i);

          Mode 0: <font>"http://www.qdecoder.org"</font>
          Mode 1: &lt;font&gt;&quot;http://www.qdecoder.org&quot;&lt;/font&gt;
          Mode 2: &lt;font&gt;&quot;<a href="http://www.qdecoder.org" target="">http://www.qdecoder.org</a>&quot;&lt;/font&gt;
          Mode 3: &lt;font&gt;&quot;<a href="http://www.qdecoder.org" target="_top">http://www.qdecoder.org</a>&quot;&lt;/font&gt;
          Mode 4: &quot;http://www.qdecoder.org&quot;
          Mode 5: &quot;<a href="http://www.qdecoder.org" target="">http://www.qdecoder.org</a>&quot;
          Mode 6: &quot;<a href="http://www.qdecoder.org" target="_top">http://www.qdecoder.org</a>&quot;
          Mode 10: <font>"http://www.qdecoder.org"</font><br>
          Mode 11: &lt;font&gt;&quot;http://www.qdecoder.org&quot;&lt;/font&gt;<br>
          Mode 12: &lt;font&gt;&quot;<a href="http://www.qdecoder.org" target="">http://www.qdecoder.org</a>&quot;&lt;/font&gt;<br>
          Mode 13: &lt;font&gt;&quot;<a href="http://www.qdecoder.org" target="_top">http://www.qdecoder.org</a>&quot;&lt;/font&gt;<br>
          Mode 14: &quot;http://www.qdecoder.org&quot;<br>
          Mode 15: &quot;<a href="http://www.qdecoder.org" target="">http://www.qdecoder.org</a>&quot;<br>
          Mode 16: &quot;<a href="http://www.qdecoder.org" target="_top">http://www.qdecoder.org</a>&quot;<br>

          qPrintf(i, "Mode %d: ' ', '  ', '   ', '    '\n", i);

          Mode 0: ' ', '  ', '   ', '    '
          Mode 1: ' ', '  ', '   ', '    '
          Mode 2: ' ', '  ', '   ', '    '
          Mode 3: ' ', '  ', '   ', '    '
          Mode 4: ' ', '  ', '   ', '    '
          Mode 5: ' ', '  ', '   ', '    '
          Mode 6: ' ', '  ', '   ', '    '
          Mode 10: ' ', ' &nbsp;', ' &nbsp;&nbsp;', ' &nbsp;&nbsp;&nbsp;'<br>
          Mode 11: ' ', ' &nbsp;', ' &nbsp;&nbsp;', ' &nbsp;&nbsp;&nbsp;'<br>
          Mode 12: ' ', ' &nbsp;', ' &nbsp;&nbsp;', ' &nbsp;&nbsp;&nbsp;'<br>
          Mode 13: ' ', ' &nbsp;', ' &nbsp;&nbsp;', ' &nbsp;&nbsp;&nbsp;'<br>
          Mode 14: ' ', ' &nbsp;', ' &nbsp;&nbsp;', ' &nbsp;&nbsp;&nbsp;'<br>
          Mode 15: ' ', ' &nbsp;', ' &nbsp;&nbsp;', ' &nbsp;&nbsp;&nbsp;'<br>
          Mode 16: ' ', ' &nbsp;', ' &nbsp;&nbsp;', ' &nbsp;&nbsp;&nbsp;'<br>

qPuts()

  Syntax: void qPuts(int mode, char *buf);
Function: Same as that of qPrintf() except that arguments cannot be
          transmitted by formats.
    Note: since the given argument of buf is modified, constant character
          strings(ex: str = "character string") or the variables that need
          to be used again should not be displayed in qPuts(). The reason
          why qPuts() exists is that there is no limitation to the length of
          argument strings unlike in qPrintf() and that the speed is a bit
          faster because the strdup() function is not used.

          The character strings transmitted to arguments are transformed.
          Accordingly if a constant character string like qPuts(mode,
          "character string"); is used, errors occur. In this case, copy the
          arguments as example.
 Example: char buf[100];
          strcpy(buf, "http://www.qdecoder.org mailto:nobreak@hongik.com");
          qPuts(2, buf);

          char *buf;
          buf = strdup("http://www.qdecoder.org mailto:nobreak@hongik.com");
          qPuts(2, buf);
          free(buf);

qRemoveSpace()

  Syntax: char *qRemoveSpace(char *str);
Function: Removes white spaces(including CR, LF) before and after character strings.
  Return: In case of success, returns the pointer of character strings. In case of
          failure, returns NULL.
    Note: If this is used like qRemoveSpace("character string");, errors may occur. In
          this case, copy the arguments as example.
 Example: char teststr[100];
          strcpy(teststr, "  Hello, world    \r\n  ");
          qRemoveSpace(teststr); // After deletion, "Hello, world" is inserted in teststr.

          char *teststr;
          teststr = strdup("  Hello, world    \r\n  ");
          qRemoveSpace(teststr); // After deletion, "Hello, world" is inserted in teststr.

qStrReplace()

   Syntax: char *qStrReplace(char *mode, char *srcstr, char *tokstr, char
           *word);
 Function: Transposes character strings and tokens for character strings.
   Return: Transposed string pointers.
     Note: The 'mode' argument is a character string consisting of two
           separate characters like "sr".
           The first character defines the transposition method, and 't'
           or 's' can be located in its place. 't' stands for [t]oken. It
           compares the source character string of srcstr using each
           character of the tokstr character string as tokens and
           transposes matching characters into the word character strings.
           's' stands for [s]tring. Using the tokstr string itself as the
           token, it transposes into the word character string the tokstr
           matching character strings appearing inside the source strings.

           The second character represents the record type of transposed
           character strings, and 'n' and 'r' can be used in its place.
           'n' stands for [n]ew. It makes the corresponding pointers
           returned by storing the transposed result character strings in
           a new memory space. Accordingly, the source string should
           maintain its original state, and the corresponding memory
           should be free() from the user aspect. 'r' stands for [r]eplace
           and means overwriting the transposition results on srcstr.
           Here, srcstr is assumed to allow some leeway (it's not
           reallocatied for convenience sake). This should be noted when
           the [r]eplace mode is to be used.

           As a result, the 'mode' argument has 4 possible occasions of
           assembly as follows:

            Mode "tn" : [t]oken transposition & stores results in a [n]ew
           space and returns
            Mode "tr" : [t]oken transposition & [r]eplaces the linked-list
           itself
            Mode "sn" : [s]tring transposition & stores results in a [n]ew
           space and returns
            Mode "sr" : [s]tring transposition & [r]eplaces the
           linked-list itself
  Example: Example)
             int  i;
             char srcstr[256], *retstr;
             char mode[4][2+1] = {"tn", "tr", "sn", "sr"};

             for(i = 0; i < 4; i++) {
               strcpy(srcstr, "Welcome to the qDecoder project.");
               printf("before %s : srcstr = %s\n", mode[i], srcstr);

               retstr = qStrReplace(mode[i], srcstr, "the", "_");
               printf("after  %s : srcstr = %s\n", mode[i], srcstr);
               printf("            retstr = %s\n\n", retstr);
               if(mode[i][1] == 'n') free(retstr);
             }

           Result)
             before tn : srcstr = Welcome to the qDecoder project.
             after  tn : srcstr = Welcome to the qDecoder project.
                         retstr = W_lcom_ _o ___ qD_cod_r proj_c_.

             before tr : srcstr = Welcome to the qDecoder project.
             after  tr : srcstr = W_lcom_ _o ___ qD_cod_r proj_c_.
                         retstr = W_lcom_ _o ___ qD_cod_r proj_c_.

             before sn : srcstr = Welcome to the qDecoder project.
             after  sn : srcstr = Welcome to the qDecoder project.
                         retstr = Welcome to _ qDecoder project.

             before sr : srcstr = Welcome to the qDecoder project.
             after  sr : srcstr = Welcome to _ qDecoder project.
                         retstr = Welcome to _ qDecoder project.

           Example 2) Convert to SQL String

             qStrReplace("sr", sqlvalue, "\\", "\\\\");
             qStrReplace("sr", sqlvalue, "'", "\\'");

qStr09AZaz()

   Syntax: int qStr09AZaz(char *str);
 Function: Checks to see if character strings consist of 0-9, A-Z, a-z.
   Return: If the condition is satisfied, return 1. If not, return 0.
  Example: if(qStr09AZaz("abc1234") == 1) printf("True");

qStrupr()

   Syntax: char *qStrupr(char *str);
 Function: Converts into uppercase letters the character strings given in
           arguments.
   Return: The pointer of the pertinent characher string.
  Example: char *str;
           str = strdup("Hello World");
           qStrupr(str);

qStrlwr()

   Syntax: char *qStrlwr(char *str);
 Function: Converts into lowercase letters the character strings given in
           arguments.
   Return: The pointer of the pertinent characher string.
  Example: char *str;
           str = strdup("Hello World");
           qStrlwr(str);

qStristr()

   Syntax: char *qStristr(char *big, char *small);
 Function: Same as that of the strstr() function. But makes a comparison
           without distinguishing lowercase/uppercase letters.
   Return: Same as that of strstr().
  Example: printf("%s", qStristr("Hello World", "WORLD"));

qStricmp()

   Syntax: int qStricmp(char *s1, char *s2);
 Function: Same as that of the strcmp() function. But this does not
           distinguish lowercase/uppercase letters.
   Return: Same as that of strcmp().
  Example: if(!qStricmp("Hello", "HELLO")) printf("Equal");
           else printf("Differ");

qStrincmp()

   Syntax: int qStrincmp(char *s1, char *s2, size_t len);
 Function: Same as that of the strncmp() function. But this does not
           distinguish lowercase/uppercase letters.
   Return: Same as that of strncmp().
  Example: if(!qStrincmp("Hello World", "HELLO", 5)) printf("Equal");
           else printf("Differ");

qitocomma()

   Syntax:char *qitocomma(int value);
 Function:Converts numeric characters into comma character strings.
   Return:The string pointer converted into characters.
     Note:The return string pointer is declared as static inside the
          functions instead of being returned with memory allocation. This
          is to remove the inconvenience that users have to free() memory
          every tiem. Accordingly, qitocomma() comes to return the same
          string pointer every time. And it should be noted that the
          previous value is deleted whenever the functions are performed.
  Example:1) (O) example of right usage, when single arguments are used
             printf("Price = %s", qitocomma(1234567));
             Price = 1,234,567

          2) (O) example of right usage, when plural arguments are used
             char a[14+1], b[14+1];
             strcpy(a, qitocomma(1234));
             strcpy(b, qitocomma(5678));
             printf("Price = %s + %s\n", a, b);
             Price = 1,234 + 5,678

          3) (X) example of wrong usage
             printf("%s %s\n", qitocomma(1234), qitocomma(5678));
             Price = 1,234 + 1,234

  ------------------------------------------------------------------------

File Handling Functions

qCheckFile()

   Syntax: int qCheckFile(char *format, ...);
 Function: Identifies the existence of files.
   Return: If files exist, return 1. If not, return 0.
     Note: When files cannot be accessed due to "permission", it judges
           that there is no file.
  Example: if(qCheckFile("test.dat") == 0) qError("File not found");

qCatFile()

   Syntax: int qCatFile(char *format, ...);
 Function: Displays the contents of files.
   Return: In normal cases, the number of displayed characters. In case of
           errors, returns -1.
  Example: qContentType("image/gif");
           qCatFile("mypic.gif");

           qContentType("text/html");
           qCatFile("myhtml.html");

qReadFile()

   Syntax: char *qReadFile(char *filename, int *size);
 Function: Returns pointers after it reads files and stores them in
           memory.
   Return: In normal cases, returns string pointers. In case of errors,
           returns NULL.
     Note: When memory is allocated to qReadFile, additional 1 byte needs
           to be allocated (1 byte more than the actual file size) for
           string termination character '\0'. This is for easy-to-manage
           purpose by reading text files. The number of characters of
           files is stored in size. The NULL argument is transmitted to
           the size item when the number of characters is not needed.
  Example: char *sp, *sp2;
           int spsize;
           sp  = qReadFile("filename", &spsize);
           sp2 = qReadFile("filename2", NULL);
           ...
           free(sp), free(sp2);

qSaveStr()

  Syntax: int qSaveStr(char *sp, int spsize, char *filename, char *mode);
Function: Stores the contents of strings in the files.
  Return: In normal cases - the number of stored characters(file size). In case of errors,
          returns -1.
    Note: The mode argument is same as the mode value used in case of fopen. qSaveStr will open
          files via corresponding modes. File permission depends on the umask() settings value
          existing before calls.
 Example: char *sp = "To subscribe qDecoder mailing list\nSend mail to majordomo@qdecoder.org";
          int len;
          umask(022);
          len = qSaveStr(sp, strlen(sp), "howto-mailing.txt", "wt");

qFileSize()

   Syntax: long qFileSize(char *filename);
 Function: Returns the file size by the unit of byte.
   Return: In case of success, returns the file size. No files, returns
           -1.
  Example: long size;
           size = qFileSize("/home/nobreak/sample.pdf");

qfGetLine()

   Syntax: char *qfGetLine(FILE *fp);
 Function: Reads lines of files without the length limitations.
   Return: 할당된 메모리 포인터, 파일 끝 NULL.
     Note: Users need to deallocated the memory of the returned string
           pointer.
  Example: line = qfGetLine(fp);

  ------------------------------------------------------------------------

Validation Functions

qCheckEmail()

   Syntax: int qCheckEmail(char *email);
 Function: Checks the validation of e-mail addresses.
   Return: No errors, 1. Invalid email, 0.
  Example: qCheckEmail("nobreak@openbird.com");

qCheckURL()

   Syntax: int qCheckURL(char *url);
 Function: Checks the errors of URL addresses.
   Return: No errors, 1. If the addresses fail to meet rules, return 0.
  Example: qCheckURL("http://www.qdecoder.org/");

  ------------------------------------------------------------------------

Download Handling Functions

qDownload()

   Syntax: int qDownload(char *filename);
 Function: Transmits files to clients. Displays downloading boxes in
           browsers regardless of the kinds of files.
   Return: In case of success, returns the number of transmitted bytes. If
           there is no file, returns -1.
     Note: This function is a shell function of qDownloadMime() that is
           for convenience.
  Example: qDownload("/home/nobreak/myprg.exe");

qDownloadMime()

   Syntax: int qDownloadMime(char *filename, char *mime);
 Function: Transmits files to clients in accordance with MIME.
   Return: In case of success, returns the number of transmitted bytes. If
           there is no file, returns -1.
     Note: The results of this function are the same as those acquired
           when the corresponding files are directly linked to the Web.
           But this is especially useful in preprocessing files to be
           downloaded only with user certification and in enabling
           downloading those files, which cannot be opned on the Web, only
           through specific programs. When MIME is
           'application/octet-stream', it isthe same as qDownload(). And
           since processes are executed until streams are terminated, this
           is a file that can be linked on the Web. When it is to be used
           as preprocessing for the downloading count, it is better to
           utilize qRedirect().
  Example: qDownloadMime("/home/nobreak/myprg.gif", "image/gif");

  ------------------------------------------------------------------------

Counter Handling Functions

qCountRead()

   Syntax: int qCountRead(char *filename);
 Function: Reads counter file.
   Return: In case of success, returns the counter value. In case of
           failure, returns 0.
     Note: Handles the following types of counter files.

           ---- number.dat ----
           74
           --------------------
  Example: int count;
           count = qCountRead("number.dat");

qCountSave()

   Syntax: int qCountSave(char *filename, int number);
 Function: Stores(updates) the counter value in the specified file name.
   Return: In case of success, returns 1. In case of failure, returns 0.
  Example: qCountSave("number.dat", 75);

qCountUpdate()

   Syntax: int qCountUpdate(char *filename, int number);
 Function: Increases the counter value of specified file names as much as
           number.
   Return: In case of success, returns the updated counter value. In case
           of failure, returns 0.
  Example: int count;
           count = qCountUpdate("number.dat", -3);

  ------------------------------------------------------------------------

Environment Related Functions

qCGIenv()

   Syntax: void qCGIenv(Q_CGIenv *env);
 Function: Stores the environment variable of CGI and time in the
           structure.
  Example: Q_CGIenv myenv;
           qCGIenv(&myenv);

           /* Q_CGIenv Data Structure */
           typedef struct Q_CGIenv Q_CGIenv;
           struct Q_CGIenv{
             char *auth_type;
             char *content_length;
             char *content_type;
             char *document_root;
             char *gateway_interface;
             char *http_accept;
             char *http_accept_encoding;
             char *http_accept_language;
             char *http_connection;
             char *http_cookie;
             char *http_host;
             char *http_referer;
             char *http_user_agent;
             char *query_string;
             char *remote_addr;
             char *remote_host;
             char *remote_port;

             char *remote_user;
             char *request_method;
             char *request_uri;
             char *script_filename;
             char *script_name;
             char *server_admin;
             char *server_name;
             char *server_port;
             char *server_protocol;
             char *server_software;
             char *server_signature;
             char *unique_id;

             /* Miscellaneous Informations Supported by qDecoder */
             int  year, mon, day, hour, min, sec;
           };

qCGIname()

   Syntax: char *qCGIname(void);
 Function: Interprets only the program names at the environment variable
           of SCRIPT_NAME and returns.
   Return: The string pointer containing CGI name.
  Example: char *cginame;
           cginame = qCGIname();

qGetenvDefault()

  Syntax: qGetenvDefault(char *nullstr, char *envname);
Function: Operates the same as the getenv() function. But returns default
          strings instead of NULL.
 Example: char *name;
          name = qGetenvDefault("/cgi-bin/CrazyWWWBoard.cgi", "SCRIPT_NAME");
          name = qGetenvDefault(NULL, "SCRIPT_NAME");

  ------------------------------------------------------------------------

Time Functions

qGetTime()

   Syntax: struct tm *qGetTime(void);
 Function: Stores time in the tm structure.
   Return: The pointer of the tm structure.
  Example: struct tm *mytime;
           mytime = qGetTime();

qGetGMTime()

   Syntax: time_t qGetGMTime(char *gmt, time_t plus_sec);
 Function: Converts present time+plus_sec into the GMT character-string
           time that is used in cookies.
   Return: The seconds from 1970/1/1(00:00:00) to the present + plus_sec.
  Example: time_t plus_sec;
           char gmt[32];
           plus_sec = (time_t)300; /* 5min */
           qGetGMTime(gmt, plus_sec);
           printf("%s", gmt); // "Fri, 22-Aug-1997 15:11:30 GMT"

  ------------------------------------------------------------------------

Error Handling Functions

qError()

   Syntax: void qError(char *format, ...);
 Function: Displays the messages for errors. Usage is same as that of the
           printf() function.
     Note: The maximum size of the assembled error message should not
           exceed 1023(1024-1) byte.
  Example: qError("error message");
           qError("errors at %s", buf);

qErrorContact()

   Syntax: void qErrorContact(char *msg);
 Function: As the footer of error messages, always displayed together when
           qError() is called. This is generally used to provide fixed
           information such as producers.
  Example: qErrorContact("- qDecoder Project.");
           qErrorContact(NULL);            // disable (default)

qErrorLog()

   Syntax: void qErrorLog(char *filename);
 Function: Sets up the log files on which the error messages--which are
           transmitted when the qError() function is called--are recorded.
     Note: When logs are recorded, the main file is not directly called.
           Like qErrorLog("logs/error.log"), once it is called at the
           initial period of programs, logs are automatically recorded in
           the 'logs/error.log' file whenever qError() is called
           afterwards.
  Example: qErrorLog("LogFileName.ext");   // enable log
           qErrorLog(NULL);                // disable log (default)

  ------------------------------------------------------------------------

Miscellaneous Functions

qFreeAll()

   Syntax: void qFreeAll(void);
 Function: Deallocates the all allocated memories by qDecoder.
     Note: Internally, qFreeAll() calls qFree(), qSessionFree(). You can
           use qFreeAll() instead qFree() and qSessionFree() at the end of
           program to deallocate all allocated memories by qDecoder.
  Example: qDecoder();
           qSession(NULL);
           ...
           ...
           ...
           qFreeAll();

qReset()

   Syntax: void qReset(void);
 Function: Deallocates the all allocated memories and Initialize qDecoder.
     Note: When you wish to make a daemon-type repetitive program or to
           initialize qDecoder anew, you can use this function. qReset()
           returns all the allocated memory including the linked-list and
           restores internal static variables to the initial condition.
           You do not need to call qFreeAll() when you use qReset().
  Example: while(1) {
             qDecoder();
             qSession(NULL);
             ...
             ...
             ...
             qReset();
           }

qUniqueID()

   Syntax: char *qUniqueID(void);
 Function: Always returns unique 32 bytes string .
   Return: String pointer of 32 bytes unique string.
     Note: The return string pointer is declared as static inside the
           functions instead of being returned with memory allocation.
           This is to remove the inconvenience that users have to free()
           memory every tiem. Accordingly, it should be noted that the
           previous value is deleted whenever the functions are performed.
           And you should not modify or free() it directly.
  Example: char *uniqueid;

           uniqueid = qUniqueID();

  ------------------------------------------------------------------------
