/*
 *  excite.c
 *      exciteブログ 投稿処理
 *      written by H.Tsujimura    27 Aug 2004 / 2 Oct 2006
 *
 * History:
 * $Log: /makeRSS/cocousagi/excite.c $
 * 
 * 4     08/09/10 23:17 Tsujimura543
 * ソースを整理
 * 
 * 3     08/09/10 23:12 Tsujimura543
 * loginExciteBlog(), postExciteBlog() を xmlRPC.dll から移管
 * 
 * 2     06/10/02 20:08 Tsujimura543
 * cocousagi.h をインクルードするようにする
 * 
 * 1     06/10/02 19:50 Tsujimura543
 * cocousagi.c から exciteブログ 特有の処理を分離
 */

#ifdef  WIN32
#include <time.h>
#else
#include <sys/time.h>
#endif

#include "xmlRPC.h"
#include "cocousagi.h"

/*
 * exciteブログ向け投稿処理
 */

#define IPADDR_LENGTH   ((3 + 1 + 3 + 1 + 3 + 1 + 3) + 1)
                                            /* aaa.bbb.ccc.ddd */
#define EID_LENGTH      32
#define TEMPKEY_LENGTH  32

#ifdef  RESEARCH_FOR_EXCITEBLOG
void    saveReport( const char *htmlSrcCode )
{
    char        filename[MAX_PATH];
    FILE        *fp;
    int         cnt  = 1;
    BOOL        done = FALSE;
    static int  pre  = 0;

    if ( !pre ) {
        do {
            sprintf( filename,
                     cnt > 9999 ? "report%06d.log"
                                : "report%04d.log",
                     cnt );
            fp = fopen( filename, "r" );
            if ( fp ) {
                fclose( fp );
                cnt++;
                if ( cnt > 999999 )
                    cnt = 0;
            }
            else
                done = TRUE;
        } while ( !done );

        pre = cnt;
        fp = fopen( filename, "w" );
    }
    else {
        sprintf( filename,
                 pre > 9999 ? "report%06d.log"
                            : "report%04d.log",
                 pre );
        fp = fopen( filename, "a" );
    }

    if ( fp ) {
        fputs( htmlSrcCode, fp );
        fclose( fp );
    }
}
/* ↑↑↑  ここまで  ↑↑↑ */
#endif  /* RESEARCH_FOR_EXCITEBLOG */

#ifdef  _MSC_VER
#pragma warning ( disable: 4100 )
#endif
static char *
getUserIpOnExciteBlog( char *ipAddr, char *p3p )
{
    char    *p, *q;
    char    url[MAX_URLLENGTH];
    char    *response;
    size_t  sz = MAX_CONTENT_SIZE;

    response = (char *)malloc( sz );
    if ( !response )
        return ( ipAddr );

    strcpy( url, "http://www.exblog.jp/" );
    setUpReceiveBuffer( response, sz );
    http_get( url, response );
#ifdef  RESEARCH_FOR_EXCITEBLOG
    saveReport( "\n===--- getUserIpOnExciteBlog() ---===\n" );
    saveReport( response );
#endif  /* RESEARCH_FOR_EXCITEBLOG */
    p = strstr( response, "<input type=\"hidden\" name=\"userip\" value=\"" );
    if ( p ) {
        p += strlen( "<input type=\"hidden\" name=\"userip\" value=\"" );
        q = strchr( p, '\"' );
        if ( q ) {
            strncpy( ipAddr, p, q - p );
            ipAddr[q - p] = '\0';
        }
    }

    free( response );

    return ( ipAddr );
}
#ifdef  _MSC_VER
#pragma warning ( default: 4100 )
#endif

static char *
getMyBlogURL( char *myBlogURL, const char *htmlSrcCode )
{
    char    *p, *q;

    p = strstr( htmlSrcCode, "self.location.href=\'" );
    if ( p ) {
        p += 20;
        q = strchr( p, '\'' );
        if ( q ) {
            strncpy( myBlogURL, p, q - p );
            myBlogURL[q - p] = '\0';
        }
    }

    return ( myBlogURL );
}


static char *
getEID( char *eid, const char *htmlSrcCode )
{
    char    *p, *q, *r;

    p = strstr( htmlSrcCode,
                "<A HREF=http://www.exblog.jp/blog/insert.asp?" );
    if ( !p )
        p = strstr( htmlSrcCode,
                    "<a href=\"http://www.exblog.jp/myblog/?" );
    if ( p ) {
        p = strchr( p, '?' );
        if ( p ) {
            p = strchr( p, '=' );
            if ( p && *++p ) {
                q = strchr( p, '>' );
                r = strchr( p, '"' );
                if ( q && r && (q > r) )
                    q = r;
                if ( q ) {
                    strncpy( eid, p, q - p );
                    eid[q - p] = '\0';
                }
            }
        }
    }

    return ( eid );
}

static char *
getTempKey( char *tempkey, const char *htmlSrcCode )
{
    char    *p, *q;

    p = strstr( htmlSrcCode, "<input type=\"hidden\" name=\"tempkey\"" );
    if ( p ) {
        p += strlen( "<input type=\"hidden\" name=\"tempkey\"" );
        p = strchr( p, '\"' );
        if ( p && *++p ) {
            q = strchr( p, '\"' );
            if ( q ) {
                strncpy( tempkey, p, q - p );
                tempkey[q - p] = '\0';
            }
        }
    }

    return ( tempkey );
}

static char *
getCgiID( int *categoryID, char *catName, const char *htmlSrcCode )
{
    getCategoryIDwithName( categoryID, catName, htmlSrcCode, 2,
                           "<select name=\"cgiid\"", "</select>",
                           "<option value=\"", "</option>",
                           CHARSET_UTF8 );

    if ( !(*catName) )
        strcpy( catName, encodeURL( sjis2utf( "未分類" ) ) );

    return ( catName );
}


int
loginExciteBlog( const char *username,
                 const char *password,
                 char       *cookie,
                 char       *myBlogURL,
                 char       *eid )
{
    int     ret = 0;
    char    *request;
    char    *response;
    char    url[MAX_URLLENGTH];
    char    ipAddr[IPADDR_LENGTH];  /* aaa.bbb.ccc.ddd */
    char    p3p[BUFSIZ];
    size_t  sz = MAX_CONTENT_SIZE;

    if ( !username || !(*username) ||
         !password || !(*password) ||
         !cookie )
         return ( ret );

    request  = (char *)malloc( MAX_CONTENT_SIZE );
    if ( !request ) 
        return ( ret );
    response = (char *)malloc( sz );
    if ( !response ) {
        free( request );
        return ( ret );
    }
    memset( request, 0x00, MAX_CONTENT_SIZE );
    memset( p3p,     0x00, BUFSIZ );
    memset( ipAddr,  0x00, IPADDR_LENGTH );

    getUserIpOnExciteBlog( ipAddr, p3p );

    if ( ipAddr[0] != NUL ) {
        strcpy( url,
                "http://www.exblog.jp/authid.asp"
             // "https://sec.exblog.jp/authid.asp"
            );
        sprintf( request,
                 "userip=%s&"
                 "returnurl=http%%3A%%2F%%2Fwww.exblog.jp&"
                 "loginurl=http%%3A%%2F%%2Fwww.exblog.jp&"
                 "userid=%s&"
                 "userpwd=%s&"
                 "ssl=1",
                 ipAddr, username, password );
        setUpReceiveBuffer( response, sz );
        http_postEx( url, "application/x-www-form-urlencoded",
                     request, response, cookie );
        if ( *response ) {
#ifdef  RESEARCH_FOR_EXCITEBLOG
            saveReport( "\n===--- loginExciteBlog() ---===\n" );
            saveReport( response );
#endif  /* RESEARCH_FOR_EXCITEBLOG */
            if ( strstr( response, sjis2utf("ようこそ") ) != NULL ) {
                char    *cookie2;

                ret = 1;    /* ログイン成功 */
                getMyBlogURL( myBlogURL, response );
                getEID( eid, response );
                cookie2 = (char *)malloc( strlen(cookie) + 1 );
                if ( cookie2 )
                    strcpy( cookie2, strstr( cookie, "Cookie: " ) + 8 );

                /* login 済み状態を示す cookie を取得 */
                setUpReceiveBuffer( response, sz );
                http_getEx( myBlogURL, response, cookie );
                if ( cookie2 ) {
                    /* 2つの cookie を合体 */
                    char    *p = strstr( cookie, "; " );
                    strcpy( p ? p + 2 : cookie + strlen( cookie ) - 2,
                            cookie2 );
                    free( cookie2 );
                }
            }
            else
                ret = 0;    /* ログイン失敗 */
        }
    }

    free( response );
    free( request  );

    return ( ret );
}

int
postExciteBlog( const char *username,
                const char *password,
                char       *cookie,
                const char *myBlogURL,      /* マイブログ トップページ URL */
                                            /*   (login中は管理画面になる) */
                const char *eid,            /* excite ID (blog ID 相当)    */
                int        categoryID,      /* カテゴリID */
                const char *categoryName,   /* カテゴリ名 */
                const char *title,          /* 題名       */
                const char *body,           /* 本文       */
                const char *extend )        /* 追記       */
{
    int     ret = 0;
    char    *request;
    char    *response;
    char    url[MAX_URLLENGTH];
 // char    p3p[BUFSIZ];
    char    tempkey[TEMPKEY_LENGTH];
    char    catName[MAX_CATNAMELENGTH];
    size_t  sz = MAX_CONTENT_SIZE;

    if ( !username || !(*username) ||
         !password || !(*password) ||
         !title    || !(*title)    ||
         !body     || !(*body)     ||
         !cookie   || !(*cookie)   ||
         !eid      || !(*eid)         )
         return ( ret );

    if ( categoryID <= 0 )
        categoryID = 1; /* 未分類 */

    request  = (char *)malloc( MAX_CONTENT_SIZE );
    if ( !request ) 
        return ( ret );
    response = (char *)malloc( sz );
    if ( !response ) {
        free( request );
        return ( ret );
    }
    memset( request,  0x00, MAX_CONTENT_SIZE );

    /* tempkeyの取得 */
 // sprintf( url, "http://www.exblog.jp/blog/insert.asp?eid=%s", eid );
    sprintf( url, "http://www.exblog.jp/myblog/entry/new/?eid=%s", eid );
    setUpReceiveBuffer( response, sz );
    http_getEx( url, response, cookie );
#ifdef  RESEARCH_FOR_EXCITEBLOG
    saveReport( "\n===--- getTempKey() & getCgiID() ---===\n" );
    saveReport( response );
#endif  /* RESEARCH_FOR_EXCITEBLOG */
    getTempKey( tempkey, response );

    if ( categoryName && *categoryName ) {
        /* カテゴリ名 → カテゴリID 変換 */
        char    catID[64];
        char    *p;

        getCategoryIDbyName( catID, categoryName, response,
                             "<select name=\"cgiid\"", "</select>",
                             "<option value=\"", "</option>",
                             CHARSET_UTF8 );
        if ( *catID )
            categoryID = atol( catID );
        p = sjis2utf( categoryName );
        strcpy( catName, p ? p : categoryName );
    }
    else {
        /* categoryID に対応するカテゴリ名の取得 */
        getCgiID( &categoryID, catName, response );
    }

    /* 投稿 */
 // strcpy( url, "http://www.exblog.jp/blog/insert_exec.asp" );
    strcpy( url, "http://www.exblog.jp/myblog/entry/new/new.asp" );

    sprintf( request,
             "eid=%s&"
             "tempkey=%s&"
             "rtnurl=%s&"
             "cgiid=%d&"
             "cgname=%s&"
             "subject=%s&"
             "pstdate=0&"   /* 2004.10.08 管理画面の仕様変更に伴い、追加 */
             "content=%s&"
             "htmlflag=1&",
             eid, tempkey, myBlogURL, categoryID, catName,
             title, body );

    if ( extend && *extend )
        sprintf( request + strlen( request ),
                 "moreflag=1&"
                 "moresubject=%s%%20(%s)&"
                 "morecontent=%s&",
                 title, extend, encodeURL( sjis2utf( "つづき" ) ) );
    else
        strcat( request,
                "moreflag=0&"
                "moresubject=&"
                "morecontent=&" );

    strcat( request,
            "openflag=1&"
            "cmtflag=1&"
            "trbflag=1&"
            "trburl=&tburlslt=" );

    setUpReceiveBuffer( response, sz );
    http_postEx( url, "application/x-www-form-urlencoded",
                 request, response, cookie );
#ifdef  RESEARCH_FOR_EXCITEBLOG
    saveReport( sjis2utf( "\n===--- 投稿 ---===\n" ) );
    saveReport( response );
#endif  /* RESEARCH_FOR_EXCITEBLOG */

    encodeURL( NULL );
    free( response );
    free( request  );

    return ( ret == -1 ? 0 : 1 );
}


int
postArticleOnExcite( const char *username,          /* excite ID    */
                     const char *password,          /* パスワード   */
                     char       *title,             /* 投稿記事題名 */
                     char       *body,              /* 投稿記事本文 */
                     const char *categoryName,      /* カテゴリ名   */
                     int        forceWritingForPet )    /* 強制代筆 */
{
    int     ret     = 0;
    char    *cookie = (char *)malloc( MAX_COOKIE_LEN );
    char    myBlogURL[MAX_URLLENGTH];
    char    eid[EID_LENGTH];

    if ( cookie ) {
        memset( cookie, 0x00, MAX_COOKIE_LEN );
        if ( loginExciteBlog( username, password, cookie, myBlogURL, eid ) ) {
            char    *s, *t;
            s = encodeURL( title );
            strcpy( title, s );
            if ( !forceWritingForPet )
                strcat( title,
                        encodeURL( sjis2utf( " [via cocousagi]" ) ) );
            else {
                time_t      t = time( NULL );
                struct tm   *tm = localtime( &t );

                sprintf( title + strlen( title ),
                         " (%04d/%02d/%02d)",
                         tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday);
            }
            t = encodeURL( sjis2utf( body ) );
            strcpy( body,  t );
            ret = postExciteBlog( username, password, cookie, myBlogURL, eid,
                                  1, /* カテゴリID: 暫定 (1 は「未分類」) */
                                  categoryName, /* カテゴリ名 */
                                  title, body, NULL );
        }

        free( cookie );
    }
    else
        fprintf( stderr, "login に失敗しました。\n" );

    return ( ret );
}
