List of ssi.c

Sun Sep 23 12:11:32 2018

戻る

TEXTAREA で表示(カット&ペーストむき)

/************************************************************************
ssi.c   ssi もどき gcc 版

98/07/07 Ver.0.02
 うーむ、つかれた。    Perl の方が楽だよね。
 表示の開始は、わずかに速いようだけど、他は perl の方が速いような(^^;;;
 日付時刻の表示は内蔵したので速いとおもう。
99/11/15 Ver.0.03
 パラメータがない時の getenv("QUERY_STRING") の戻り値が変わった?
 BIGLOBE のサーバーの設定変更による?
99/11/15 Ver.0.04
 REMOTE_HOST を REMOTE_ADDR から設定、他
99/12/11 Ver.0.05
99/12/14 Ver.0.06
99/12/14 Ver.0.07 bugfix

コンパイル方法
    >gcc ssi.c -o ssic.cgi

Copyright (c) 1998,1999 がま <gama@mvg.biglobe.ne.jp>
************************************************************************/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>

void ssicmd(char *s);
void exec(const char *tag, const char *val);
void echo(const char *tag, const char *val);
void config(const char *tag, const char *val);
void ip2hostname(char *ip);

/***********************************************************************/
/* 省略時に表示するファイル名  */
char *dflt_filename     = "welcome.htm";
/* timefmt の初期値        Tuesday, 07-Jul-98 11:59:59 JST */
char timefmt[BUFSIZ]    = "%A, %d-%b-%y %H:%M:%S %Z";

/***********************************************************************/
#define errname     "**** ssi: error filename(%s) **** "
#define erropen     "**** ssi: error at fopen(%s) ****"
#define errexec     "**** ssi: error at system(%s) ****"
#define errfmt      "**** ssi: format error near (%s) ****"

/***********************************************************************/
void main()
{
    FILE *HTML;
    char *filename;
    char *i, *j, *k;
    char strbuf[BUFSIZ];

    printf( "Content-type: text/html\n\n");

    filename = getenv("QUERY_STRING");

    if (*filename == NULL) {                        /* ???? */
/*  if (filename == NULL) { */
        filename = dflt_filename;                       /* 省略時のファイル名   */
    }
    if ( strstr(filename,"..")|| *filename == '/' ) {
        printf (errname, filename);
        return;
    } 
    if (!(HTML=fopen(filename,"r"))){
        printf (erropen, filename);
        return;
    }

    while ( fgets(strbuf, BUFSIZ, HTML ) ) {
        /*** 行内に複数の指定は考慮している                     */
        i=strbuf;
        while ( j = strstr( i, "<!--#") ) {
            /*** 複数行にわたる指定は考慮していない             */
            if ( k = strstr ( j+5, "-->") ) {   
                *j=0;
                fputs(i, stdout);               /* <!--# の前   */
                *k=0;
                ssicmd(j+5);                    /* まんなか     */
                i=k+3;                          /* --> の後ろ   */
            } else {
                printf(errfmt, i);              /* error        */
                break;
            }
        }
        fputs(i, stdout);
    }
}
/************************************************************************
SSI の一般形    <!--#command tag1="value1" tag2="value2" -->
    ssicmd, ssitag, ssival      あとの2つは??手抜き(^^;;;
************************************************************************/
void ssicmd(char *s)
{
    char *ssicmd, *ssitag, *ssival, *t;

    /****************************************/
    ssicmd=s;                               /* command          */
    while (*s) {
        if (isspace(*s)) {
            break;
        }
        *s=tolower(*s);
        s++;
    }
    *s++=0;
    while (isspace(*s) && *s ) {
        s++;
    }
    /****************************************/
    ssitag=s;                               /* tag1             */
    while (*s) {
        if (*s == '=') {
            break;
        }
        *s=tolower(*s);
        s++;
    }
    *s++=0;
    while ( *s != '"' && *s ) {
        s++;
    }
    /****************************************/
    if (*s++ !='"' ) {				/* " を読み飛ばし */
        printf(errfmt, ssicmd);     /* error            */
        return;
    }
    ssival=s;                               /* value1           */
    while (*s) {
        if (*s == '"' ) {
            break;
        }
        s++;
    }
    *s=0;
    /***************************************/
    if          (strcmp("exec",ssicmd) == 0 ) {
        t=ssival;
        while (*t++) {
            if (*t == '?') {
                *t = ' ';
            }
        }
        exec(ssitag, ssival);
    } else if   (strcmp("echo",ssicmd) == 0 ) {
        echo(ssitag, ssival);
    } else if   (strcmp("config",ssicmd) == 0 ) {
        config(ssitag, ssival);
    }
}
/***********************************************************************/
void exec(const char *tag, const char *val)
{
    fflush(stdout);
    if ( system(val) == -1 ) {                  /*  system          */
        printf(errexec, val);
    }
}
/***********************************************************************/
void echo(const char *tag, const char *val)
{
    time_t now;
    struct tm *tp;
    char strbuf[BUFSIZ];
    char *env;

    if  (   strcmp("DATE_LOCAL", val) == 0 
        ||  strcmp("DATE_GMT", val) == 0 ) {
        now = time(NULL);
        if  (   strcmp("DATE_GMT",val) == 0 ) {
            tp =gmtime(&now);
        } else {
            tp =localtime(&now);
        }
        strftime(strbuf, BUFSIZ, timefmt, tp);  /* 時刻の形式の変換 */
        printf("%s", strbuf);
        return;
    }
    if  (   strcmp("REMOTE_HOST", val) == 0 ) {
        ip2hostname(getenv("REMOTE_ADDR"));
        return;
    }
    if  ( strcmp("HTTP_X_FORWARDED_FOR", val) == 0 ) {
        ip2hostname(getenv(val));
        return;
    }
    printf("%s", getenv(val));
}
/***********************************************************************/
void ip2hostname(char *ip)      /* IP アドレスからホスト名を表示    */
{
    struct hostent *hostname;
    unsigned char addr[4];
    int  type   = AF_INET;
    int  len    = 4;
    int  j      = 0;
    char *i;

    if (ip == NULL) {
        printf("%s",ip);
        return;
    }
    i   = ip;

    addr[0]=0;
    while (*i) {
        if ( isdigit(*i) ) {
            addr[j]=addr[j]*10+(*i-'0');
        } else if ( *i == '.' ) {
            j++;
            addr[j]=0;
        } else {
            printf("%s",ip);
            return;
        }
        i++;
    }
    if ( NULL != (hostname = gethostbyaddr(addr, len, type))) {
        printf("%s", hostname->h_name);
        return;
    }
    printf("%s",ip);
}
/***********************************************************************/
void config(const char *tag, const char *val)
{
    if  (   strcmp("timefmt",tag) == 0 ) {
        strcpy(timefmt, val);
    }
}

戻る