OSDN Git Service

update filename options. in progress.
authorvisor <visor@users.sourceforge.jp>
Mon, 14 Jul 2014 15:32:19 +0000 (00:32 +0900)
committervisor <visor@users.sourceforge.jp>
Mon, 14 Jul 2014 15:32:19 +0000 (00:32 +0900)
lib/ml.h
modules/ml-imagesize.cc
modules/ml-motor.cc
modules/ml-security.cc
modules/ml-security.h
modules/ml-sendmail.cc
modules/ml-sendmail.h
modules/ml-store.cc
modules/ml-store.h

index a96b144..08176bd 100644 (file)
--- a/lib/ml.h
+++ b/lib/ml.h
@@ -324,6 +324,15 @@ class  MNodePtr {
            ans->refcount --;
        return ans;
     };
+    inline ustring  to_string () {
+       return ::to_string (p);
+    };
+    inline ustring  to_asciiword () {
+       return ::to_asciiword (p);
+    };
+    inline bool  to_bool () {
+       return ::to_bool (p);
+    };
 };
 
 class  MNodeList {
index 53a6614..65153b3 100644 (file)
@@ -136,7 +136,8 @@ static bool  imageSize (ustring* data, size_t& x, size_t& y, ustring& type) {
 
 /*DOC:
 ===image-size===
- (image-size FILENAME [#serial | #named | #static | :serial BOOL | :named BOOL | :static BOOL]) -> (WIDTH HEIGHT TYPE) or NIL
+// (image-size FILENAME [#serial | #named | #static | :serial BOOL | :named BOOL | :static BOOL]) -> (WIDTH HEIGHT TYPE) or NIL
+ (image-size [:source-serial FILENAME | :source-named FILENAME | :source-static FILENAME]) -> (WIDTH HEIGHT TYPE) or NIL
 
 TYPEは、gif, jpeg, png, swf。
 
@@ -144,27 +145,44 @@ TYPEは、gif, jpeg, png, swf。
 //#AFUNC       image-size      ml_image_size
 MNode*  ml_image_size (MNode* cell, MlEnv* mlenv) {
     MNode*  arg = cell->cdr ();
-    ustring  filename;
-    StoreType  storetype;
+    StoreType  storetype (mlenv);
+    MNodePtr  t;
     ustring  src;
     std::vector<MNode*>  params;
     std::vector<MNode*>  keywords;
     static paramList  kwlist[] = {
-       {CharConst ("serial"), true}, // 0
-       {CharConst ("named"), true}, // 1
-       {CharConst ("static"), true}, // 2
+       {CharConst ("source-serial"), false},   // 0
+       {CharConst ("source-named"), false},    // 1
+       {CharConst ("source-static"), false},   // 2
+#ifdef SOURCEFILECOMPAT
+       {CharConst ("serial"), true},           // 3
+       {CharConst ("named"), true},            // 4
+       {CharConst ("static"), true},           // 5
+#endif
        {NULL, 0, 0}
     };
 
+#ifdef SOURCEFILECOMPAT
     setParams (arg, 1, &params, kwlist, &keywords, NULL);
-    filename = eval_str (params[0], mlenv);
-    if (keywords[0] && eval_bool (keywords[0], mlenv)) // serial
+    storetype.setParam (eval_str (params[0], mlenv));
+#else
+    setParams (arg, 0, &params, kwlist, &keywords, NULL);
+#endif
+    if (evkw (0, t))
+       storetype.srcSerial (t.to_string ());   // :source-serial
+    if (evkw (1, t))
+       storetype.srcNamed (t.to_string ());    // :source-named
+    if (evkw (2, t))
+       storetype.srcStatic (t.to_string ());   // :source-static
+#ifdef SOURCEFILECOMPAT
+    if (keywords[3] && eval_bool (keywords[3], mlenv)) // serial
        storetype.setSerial ();
-    if (keywords[1] && eval_bool (keywords[1], mlenv)) // named
+    if (keywords[4] && eval_bool (keywords[4], mlenv)) // named
        storetype.setNamed ();
-    if (keywords[2] && eval_bool (keywords[2], mlenv)) // static
+    if (keywords[5] && eval_bool (keywords[5], mlenv)) // static
        storetype.setStatic ();
-    src = storetype.src (mlenv, filename);
+#endif
+    src = storetype.src (mlenv);
 
     if (src.length () > 0) {
        FileMacro  f;
index 48d06b9..888fbce 100644 (file)
@@ -63,73 +63,91 @@ MNode*  ml_output_header (MNode* cell, MlEnv* mlenv) {
 
 /*DOC:
 ===motor-file===
- (motor-file HTMLFILE [:type MIMETYPE] [#error | :error BOOL] [:code ENCODING] [#continue | :continue BOOL]
-               [#serial | #named | #static | :serial BOOL | :named BOOL | :static BOOL]) -> NIL
-
+// (motor-file HTMLFILE [:type MIMETYPE] [#error | :error BOOL] [:code ENCODING] [#continue | :continue BOOL] [#serial | #named | #static | :serial BOOL | :named BOOL | :static BOOL]) -> NIL
+ (motor-file [:source-serial FILENAME | :source-named FILENAME | :source-static FILENAME] [:type MIMETYPE] [#error | :error BOOL] [:code ENCODING] [#continue | :continue BOOL]) -> NIL
 
 */
 //#AFUNC       motor-file      ml_motor_file
 MNode*  ml_motor_file (MNode* cell, MlEnv* mlenv) {
     MNode*  arg = cell->cdr ();
-    ustring  file;
+    ustring  src;
     ustring  type;
     bool  ferr = false;
     ustring  encoding;
     bool  cflag = false;
     StoreType  storetype (mlenv);
     MNodePtr  t;
+#ifdef SOURCEFILECOMPAT
     std::vector<MNode*>  params;
+#endif
     std::vector<MNode*>  keywords;
     static paramList  kwlist[] = {
        {CharConst ("type"), false}, // 0
        {CharConst ("error"), true}, // 1
        {CharConst ("code"), false}, // 2
        {CharConst ("continue"), true}, // 3
-       {CharConst ("serial"), true}, // 4
-       {CharConst ("named"), true}, // 5
-       {CharConst ("static"), true}, // 6
+       {CharConst ("source-serial"), false},   // 4
+       {CharConst ("source-named"), false},    // 5
+       {CharConst ("source-static"), false},   // 6
+#ifdef SOURCEFILECOMPAT
+       {CharConst ("serial"), true}, // 7
+       {CharConst ("named"), true}, // 8
+       {CharConst ("static"), true}, // 9
+#endif
        {NULL, 0, 0}
     };
 
     storetype.setStatic ();
+#ifdef SOURCEFILECOMPAT
     setParams (arg, 1, &params, kwlist, &keywords, NULL, true);
-    file = eval_str (params[0], mlenv);
-    if (evkw (0, t)) {         // type
-       type = to_asciiword (t ());
+    storetype.setParam (eval_str (params[0], mlenv));
+#else
+    setParams (arg, 0, NULL, kwlist, &keywords, NULL, true);
+#endif
+    if (evkw (0, t)) {                         // type
+       type = t.to_asciiword ();
        if (! checkMimeType (type))
            type.resize (0);
     }
-    if (keywords[1])           // error
+    if (keywords[1])                           // error
        ferr = eval_bool (keywords[1], mlenv);
-    if (evkw (2, t))           // code
+    if (evkw (2, t))                           // code
        encoding = to_string (t ());
-    if (keywords[3] && eval_bool (keywords[3], mlenv)) // continue
-       cflag = true;
-    if (keywords[4] && eval_bool (keywords[4], mlenv)) // serial
+    if (keywords[3])                           // continue
+       cflag = eval_bool (keywords[3], mlenv);
+    if (evkw (4, t))
+       storetype.srcSerial (t.to_string ());   // :source-serial
+    if (evkw (5, t))
+       storetype.srcNamed (t.to_string ());    // :source-named
+    if (evkw (6, t))
+       storetype.srcStatic (t.to_string ());   // :source-static
+#ifdef SOURCEFILECOMPAT
+    if (keywords[7] && eval_bool (keywords[7], mlenv)) // serial
        storetype.setSerial ();
-    if (keywords[5] && eval_bool (keywords[5], mlenv)) // named
+    if (keywords[8] && eval_bool (keywords[8], mlenv)) // named
        storetype.setNamed ();
-    if (keywords[6] && eval_bool (keywords[6], mlenv)) // static
+    if (keywords[9] && eval_bool (keywords[9], mlenv)) // static
        storetype.setStatic ();
+#endif
+    src = storetype.src (mlenv);
 
-    if (file.size () == 0)
+    if (src.size () == 0)
        throw (uErrorFilenameEmpty);
-    file = storetype.src (mlenv, file);
 
     if (ferr)
        mlenv->env->setErrorFlag ();
     if (encoding.empty ()) {
        if (type.size () == 0) {
-           mlenv->env->doMotorFile (file, false, mlenv->env->mimetype);
+           mlenv->env->doMotorFile (src, false, mlenv->env->mimetype);
        } else {
-           mlenv->env->doMotorFile (file, false, type);
+           mlenv->env->doMotorFile (src, false, type);
        }
     } else {
        MotorOutputIConvOStream  out (encoding.c_str ());
        if (type.size () == 0) {
-           mlenv->env->doMotorFile (file, false, mlenv->env->mimetype, &out);
+           mlenv->env->doMotorFile (src, false, mlenv->env->mimetype, &out);
        } else {
-           mlenv->env->doMotorFile (file, false, type, &out);
+           mlenv->env->doMotorFile (src, false, type, &out);
        }
     }
 
index 8799a01..056b2c9 100644 (file)
 ==cryptographic functions
 
 */
+static MNode*  ml_hmac_sub (const EVP_MD* fn, MNode* cell, MlEnv* mlenv);
+static MNode*  ml_hash_sub (ustring fn (const ustring& text), ustring fn (FileMacro& f), MNode* cell, MlEnv* mlenv);
+static ustring  fn_md5 (const ustring& text);
+static ustring  fn_md5_file (FileMacro& f);
+static ustring  fn_sha1 (const ustring& text);
+static ustring  fn_sha1_file (FileMacro& f);
+static ustring  fn_sha256 (const ustring& text);
+static ustring  fn_sha256_file (FileMacro& f);
+
 /*DOC:
 ===hmac-sha1===
  (hmac-sha1 KEY_STRING TEXT [#hex] [#base64]) => STRING
+ (hmac-sha1 [:key-serial FILENAME | :key-named FILENAME | :key-static FILENAME | :key-text TEXT] [:message-serial FILENAME | :message-named FILENAME | :message-static FILENAME | :message-text TEXT] [#hex] [#base64]) => STRING
 
 */
 //#AFUNC       hmac-sha1       ml_hmac_sha1
 //#WIKIFUNC    hmac-sha1
 MNode*  ml_hmac_sha1 (MNode* cell, MlEnv* mlenv) {
+    return ml_hmac_sub (EVP_sha1 (), cell, mlenv);
+}
+
+/*DOC:
+===hmac-sha256===
+ (hmac-sha256 KEY_STRING TEXT [#hex] [#base64]) => STRING
+ (hmac-sha256 [:key-serial FILENAME | :key-named FILENAME | :key-static FILENAME | :key-text TEXT] [:message-serial FILENAME | :message-named FILENAME | :message-static FILENAME | :message-text TEXT] [#hex] [#base64]) => STRING
+
+*/
+//#AFUNC       hmac-sha256     ml_hmac_sha256
+//#WIKIFUNC    hmac-sha256
+MNode*  ml_hmac_sha256 (MNode* cell, MlEnv* mlenv) {
+    return ml_hmac_sub (EVP_sha256 (), cell, mlenv);
+}
+
+MNode*  ml_hmac_sub (const EVP_MD* fn, MNode* cell, MlEnv* mlenv) {
     MNode*  arg = cell->cdr ();
     ustring  key;
     ustring  text;
+    StoreType  keyType;
+    StoreType  msgType;
     enum {
        ENC_HEX,
        ENC_BASE64,
     }  encode = ENC_HEX;
     ustring  ans;
+    MNodePtr  t;
     unsigned char  md[EVP_MAX_MD_SIZE];
-    unsigned int  md_len;
+    unsigned int  md_len = 0;
     std::vector<MNode*>  params;
     std::vector<MNode*>  keywords;
     static paramList  kwlist[] = {
-       {CharConst ("hex"), true},
-       {CharConst ("base64"), true},
+       {CharConst ("hex"), true},              // 0
+       {CharConst ("base64"), true},           // 1
+       {CharConst ("key-serial"), false},      // 2
+       {CharConst ("key-named"), false},       // 3
+       {CharConst ("key-static"), false},      // 4
+       {CharConst ("key-text"), false},        // 5
+       {CharConst ("message-serial"), false},  // 6
+       {CharConst ("message-named"), false},   // 7
+       {CharConst ("message-static"), false},  // 8
+       {CharConst ("message-text"), false},    // 9
        {NULL, 0, 0}
     };
 
@@ -51,10 +88,45 @@ MNode*  ml_hmac_sha1 (MNode* cell, MlEnv* mlenv) {
        encode = ENC_HEX;
     if (keywords[1] && eval_bool (keywords[1], mlenv))
        encode = ENC_BASE64;
-
-    HMAC (EVP_sha1 (), key.c_str (), key.length (), uchar_type (text.c_str ()), text.length (), md, &md_len);
-
+    if (evkw (2, t))
+       keyType.srcSerial (t.to_string ());     // :key-serial
+    if (evkw (3, t))
+       keyType.srcNamed (t.to_string ());      // :key-named
+    if (evkw (4, t))
+       keyType.srcStatic (t.to_string ());     // :key-static
+    if (evkw (5, t))
+       keyType.srcText (t.to_string ());       // :key-text
+    if (evkw (6, t))
+       msgType.srcSerial (t.to_string ());     // :message-serial
+    if (evkw (7, t))
+       msgType.srcNamed (t.to_string ());      // :message-named
+    if (evkw (8, t))
+       msgType.srcStatic (t.to_string ());     // :message-static
+    if (evkw (9, t))
+       msgType.srcText (t.to_string ());       // :message-text
+    if (keyType ())
+       key = keyType.read (mlenv);
+
+    if (msgType.isText ()) {
+       text = msgType.read (mlenv);
+       HMAC (fn, key.c_str (), key.length (), uchar_type (text.c_str ()), text.length (), md, &md_len);
+    } else if (! msgType ()) {
+       HMAC (fn, key.c_str (), key.length (), uchar_type (text.c_str ()), text.length (), md, &md_len);
+    } else {
+       HMAC_CTX  hmac;
+       FileMacro  f;
+       ssize_t  len;
+       u_char  buf[S4K];
+       if (f.openRead (msgType.src (mlenv).c_str ())) {
+           HMAC_Init (&hmac, key.c_str (), key.length (), fn);
+           while ((len = f.read (buf, S4K)) > 0) {
+               HMAC_Update (&hmac, buf, len);
+           }
+           HMAC_Final (&hmac, md, &md_len);
+       }
+    }
     ans.assign (char_type (md), md_len);
+
     switch (encode) {
     case ENC_HEX:
        ans = hexEncode (ans);
@@ -69,29 +141,42 @@ MNode*  ml_hmac_sha1 (MNode* cell, MlEnv* mlenv) {
     return newMNode_str (new ustring (ans));
 }
 
-/*DOC:
+#if 0
+/*--DOC:
 ===hmac-sha256===
  (hmac-sha256 KEY_STRING TEXT [#hex] [#base64]) => STRING
+ (hmac-sha256 [:key-serial FILENAME | :key-named FILENAME | :key-static FILENAME | :key-text TEXT] [:message-serial FILENAME | :message-named FILENAME | :message-static FILENAME | :message-text TEXT] [#hex] [#base64]) => STRING
 
 */
-//#AFUNC       hmac-sha256     ml_hmac_sha256
-//#WIKIFUNC    hmac-sha256
+//--#AFUNC     hmac-sha256     ml_hmac_sha256
+//--#WIKIFUNC  hmac-sha256
 MNode*  ml_hmac_sha256 (MNode* cell, MlEnv* mlenv) {
     MNode*  arg = cell->cdr ();
     ustring  key;
     ustring  text;
+    StoreType  keyType;
+    StoreType  msgType;
     enum {
        ENC_HEX,
        ENC_BASE64,
     }  encode = ENC_HEX;
     ustring  ans;
+    MNodePtr  t;
     unsigned char  md[EVP_MAX_MD_SIZE];
     unsigned int  md_len;
     std::vector<MNode*>  params;
     std::vector<MNode*>  keywords;
     static paramList  kwlist[] = {
-       {CharConst ("hex"), true},
-       {CharConst ("base64"), true},
+       {CharConst ("hex"), true},              // 0
+       {CharConst ("base64"), true},           // 1
+       {CharConst ("key-serial"), false},      // 2
+       {CharConst ("key-named"), false},       // 3
+       {CharConst ("key-static"), false},      // 4
+       {CharConst ("key-text"), false},        // 5
+       {CharConst ("message-serial"), false},  // 6
+       {CharConst ("message-named"), false},   // 7
+       {CharConst ("message-static"), false},  // 8
+       {CharConst ("message-text"), false},    // 9
        {NULL, 0, 0}
     };
 
@@ -102,6 +187,26 @@ MNode*  ml_hmac_sha256 (MNode* cell, MlEnv* mlenv) {
        encode = ENC_HEX;
     if (keywords[1] && eval_bool (keywords[1], mlenv))
        encode = ENC_BASE64;
+    if (evkw (2, t))
+       keyType.srcSerial (t.to_string ());     // :key-serial
+    if (evkw (3, t))
+       keyType.srcNamed (t.to_string ());      // :key-named
+    if (evkw (4, t))
+       keyType.srcStatic (t.to_string ());     // :key-static
+    if (evkw (5, t))
+       keyType.srcText (t.to_string ());       // :key-text
+    if (evkw (6, t))
+       msgType.srcSerial (t.to_string ());     // :message-serial
+    if (evkw (7, t))
+       msgType.srcNamed (t.to_string ());      // :message-named
+    if (evkw (8, t))
+       msgType.srcStatic (t.to_string ());     // :message-static
+    if (evkw (9, t))
+       msgType.srcText (t.to_string ());       // :message-text
+    if (keyType ())
+       key = keyType.read (mlenv);
+    if (msgType ())
+       text = msgType.read (mlenv);
 
     HMAC (EVP_sha256 (), key.c_str (), key.length (), uchar_type (text.c_str ()), text.length (), md, &md_len);
 
@@ -119,7 +224,172 @@ MNode*  ml_hmac_sha256 (MNode* cell, MlEnv* mlenv) {
 
     return newMNode_str (new ustring (ans));
 }
+#endif
+
+static ustring  fn_md5 (const ustring& text) {
+    MD5_CTX  ctx;
+    u_char  buf[16];
+
+    MD5Init (&ctx);
+    MD5Update (&ctx, text.c_str (), text.length ());
+    MD5Final (buf, &ctx);
+    return ustring (char_type (buf), 16);
+}
+
+static ustring  fn_md5_file (FileMacro& f) {
+    MD5_CTX  ctx;
+    ssize_t  len;
+    u_char  buf[S4K];
+
+    MD5Init (&ctx);
+    while ((len = f.read (buf, S4K)) > 0) {
+       MD5Update (&ctx, buf, len);
+    }
+    MD5Final (buf, &ctx);
+    return ustring (char_type (buf), 16);
+}
+
+static ustring  fn_sha1 (const ustring& text) {
+    SHA_CTX  ctx;
+    u_char  buf[SHA_DIGEST_LENGTH];
+
+    SHA1_Init (&ctx);
+    SHA1_Update (&ctx, text.c_str (), text.length ());
+    SHA1_Final (buf, &ctx);
+    return ustring (char_type (buf), SHA_DIGEST_LENGTH);
+}
+
+static ustring  fn_sha1_file (FileMacro& f) {
+    SHA_CTX  ctx;
+    ssize_t  len;
+    u_char  buf[S4K];
+
+    SHA1_Init (&ctx);
+    while ((len = f.read (buf, S4K)) > 0) {
+       SHA1_Update (&ctx, buf, len);
+    }
+    SHA1_Final (buf, &ctx);
+    return ustring (char_type (buf), SHA_DIGEST_LENGTH);
+}
+
+static ustring  fn_sha256 (const ustring& text) {
+    SHA256_CTX  ctx;
+    u_char  buf[32];
+
+    SHA256_Init (&ctx);
+    SHA256_Update (&ctx, text.c_str (), text.length ());
+    SHA256_Final (buf, &ctx);
+    return ustring (char_type (buf), 32);
+}
+
+static ustring  fn_sha256_file (FileMacro& f) {
+    SHA256_CTX  ctx;
+    ssize_t  len;
+    u_char  buf[S4K];
+
+    SHA256_Init (&ctx);
+    while ((len = f.read (buf, S4K)) > 0) {
+       SHA256_Update (&ctx, buf, len);
+    }
+    SHA256_Final (buf, &ctx);
+    return ustring (char_type (buf), 32);
+}
+
+/*DOC:
+===md5===
+ (md5 [:message-serial FILENAME | :message-named FILENAME | :message-static FILENAME | :message-text TEXT] [#hex | #base64 | :hex BOOL | :base64 BOOL]) -> STRING
+
+*/
+//#AFUNC       md5     ml_md5
+//#WIKIFUNC    md5
+MNode*  ml_md5 (MNode* cell, MlEnv* mlenv) {
+    return ml_hash_sub (fn_md5, fn_md5_file, cell, mlenv);
+}
+
+/*DOC:
+===sha1===
+ (sha1 [:message-serial FILENAME | :message-named FILENAME | :message-static FILENAME | :message-text TEXT] [#hex | #base64 | :hex BOOL | :base64 BOOL]) -> STRING
+
+*/
+//#AFUNC       sha1    ml_sha1
+//#WIKIFUNC    sha1
+MNode*  ml_sha1 (MNode* cell, MlEnv* mlenv) {
+    return ml_hash_sub (fn_sha1, fn_sha1_file, cell, mlenv);
+}
+
+/*DOC:
+===sha256===
+ (sha256 [:message-serial FILENAME | :message-named FILENAME | :message-static FILENAME | :message-text TEXT] [#hex | #base64 | :hex BOOL | :base64 BOOL]) -> STRING
+
+*/
+//#AFUNC       sha256  ml_sha256
+//#WIKIFUNC    sha256
+MNode*  ml_sha256 (MNode* cell, MlEnv* mlenv) {
+    return ml_hash_sub (fn_sha256, fn_sha256_file, cell, mlenv);
+}
+
+static MNode*  ml_hash_sub (ustring fn_text (const ustring& text), ustring fn_file (FileMacro& f), MNode* cell, MlEnv* mlenv) {
+    MNode*  arg = cell->cdr ();
+    ustring  text;
+    StoreType  msgType;
+    enum {
+       ENC_HEX,
+       ENC_BASE64,
+    }  encode = ENC_HEX;
+    ustring  ans;
+    MNodePtr  t;
+    std::vector<MNode*>  keywords;
+    static paramList  kwlist[] = {
+       {CharConst ("hex"), true},              // 0
+       {CharConst ("base64"), true},           // 1
+       {CharConst ("message-serial"), false},  // 2
+       {CharConst ("message-named"), false},   // 3
+       {CharConst ("message-static"), false},  // 4
+       {CharConst ("message-text"), false},    // 5
+       {NULL, 0, 0}
+    };
+
+    setParams (arg, 0, NULL, kwlist, &keywords, NULL);
+    if (keywords[0] && eval_bool (keywords[0], mlenv)) // hex
+       encode = ENC_HEX;
+    if (keywords[1] && eval_bool (keywords[1], mlenv)) // base64
+       encode = ENC_BASE64;
+    if (evkw (2, t))
+       msgType.srcSerial (t.to_string ());     // :message-serial
+    if (evkw (3, t))
+       msgType.srcNamed (t.to_string ());      // :message-named
+    if (evkw (4, t))
+       msgType.srcStatic (t.to_string ());     // :message-static
+    if (evkw (5, t))
+       msgType.srcText (t.to_string ());       // :message-text
+
+    if (msgType.isText ()) {
+       text = msgType.read (mlenv);
+       ans = fn_text (text);
+    } else if (! msgType ()) {
+       // error
+    } else {
+       FileMacro  f;
+       if (f.openRead (msgType.src (mlenv).c_str ())) {
+           ans = fn_file (f);
+       }
+    }
+
+    switch (encode) {
+    case ENC_HEX:
+       ans = hexEncode (ans);
+       break;
+    case ENC_BASE64:
+       ans = base64Encode (ans.begin (), ans.end ());
+       break;
+    default:
+       assert (0);
+    }
+    return newMNode_str (new ustring (ans));
+}
+
 
+#ifdef SOURCEFILECOMPAT
 static MNode*  ml_hash_string (MNode* cell, MlEnv* mlenv, ustring fn (const ustring& text)) {
     MNode*  arg = cell->cdr ();
     ustring  text;
@@ -213,76 +483,7 @@ static MNode*  ml_hash_file (MNode* cell, MlEnv* mlenv, ustring fn (FileMacro& f
     return NULL;
 }
 
-static ustring  fn_md5 (const ustring& text) {
-    MD5_CTX  ctx;
-    u_char  buf[16];
-
-    MD5Init (&ctx);
-    MD5Update (&ctx, text.c_str (), text.length ());
-    MD5Final (buf, &ctx);
-    return ustring (char_type (buf), 16);
-}
-
-static ustring  fn_md5_file (FileMacro& f) {
-    MD5_CTX  ctx;
-    ssize_t  len;
-    u_char  buf[S4K];
-
-    MD5Init (&ctx);
-    while ((len = f.read (buf, S4K)) > 0) {
-       MD5Update (&ctx, buf, len);
-    }
-    MD5Final (buf, &ctx);
-    return ustring (char_type (buf), 16);
-}
-
-static ustring  fn_sha1 (const ustring& text) {
-    SHA_CTX  ctx;
-    u_char  buf[SHA_DIGEST_LENGTH];
-
-    SHA1_Init (&ctx);
-    SHA1_Update (&ctx, text.c_str (), text.length ());
-    SHA1_Final (buf, &ctx);
-    return ustring (char_type (buf), SHA_DIGEST_LENGTH);
-}
-
-static ustring  fn_sha1_file (FileMacro& f) {
-    SHA_CTX  ctx;
-    ssize_t  len;
-    u_char  buf[S4K];
-
-    SHA1_Init (&ctx);
-    while ((len = f.read (buf, S4K)) > 0) {
-       SHA1_Update (&ctx, buf, len);
-    }
-    SHA1_Final (buf, &ctx);
-    return ustring (char_type (buf), SHA_DIGEST_LENGTH);
-}
-
-static ustring  fn_sha256 (const ustring& text) {
-    SHA256_CTX  ctx;
-    u_char  buf[32];
-
-    SHA256_Init (&ctx);
-    SHA256_Update (&ctx, text.c_str (), text.length ());
-    SHA256_Final (buf, &ctx);
-    return ustring (char_type (buf), 32);
-}
-
-static ustring  fn_sha256_file (FileMacro& f) {
-    SHA256_CTX  ctx;
-    ssize_t  len;
-    u_char  buf[S4K];
-
-    SHA256_Init (&ctx);
-    while ((len = f.read (buf, S4K)) > 0) {
-       SHA256_Update (&ctx, buf, len);
-    }
-    SHA256_Final (buf, &ctx);
-    return ustring (char_type (buf), 32);
-}
-
-/*DOC:
+/*--DOC:
 ===md5-string===
  (md5-string TEXT [#hex | #base64 | :hex BOOL | :base64 BOOL]) -> STRING
 
@@ -293,7 +494,7 @@ MNode*  ml_md5_string (MNode* cell, MlEnv* mlenv) {
     return ml_hash_string (cell, mlenv, fn_md5);
 }
 
-/*DOC:
+/*--DOC:
 ===md5-file===
  (md5-file FILENAME [#serial | #named | #static | :serial BOOL | :named BOOL | :static BOOL] [#hex | #base64 | :hex BOOL | :base64 BOOL]) -> STRING
 
@@ -303,7 +504,7 @@ MNode*  ml_md5_file (MNode* cell, MlEnv* mlenv) {
     return ml_hash_file (cell, mlenv, fn_md5_file);
 }
 
-/*DOC:
+/*--DOC:
 ===sha1-string===
  (sha1-string TEXT [#hex | #base64 | :hex BOOL | :base64 BOOL]) -> STRING
 
@@ -314,7 +515,7 @@ MNode*  ml_sha1_string (MNode* cell, MlEnv* mlenv) {
     return ml_hash_string (cell, mlenv, fn_sha1);
 }
 
-/*DOC:
+/*--DOC:
 ===sha1-file===
  (sha1-file FILENAME [#serial | #named | #static | :serial BOOL | :named BOOL | :static BOOL] [#hex | #base64 | :hex BOOL | :base64 BOOL]) -> STRING
 
@@ -324,7 +525,7 @@ MNode*  ml_sha1_file (MNode* cell, MlEnv* mlenv) {
     return ml_hash_file (cell, mlenv, fn_sha1_file);
 }
 
-/*DOC:
+/*--DOC:
 ===sha256-string===
  (sha256-string TEXT [#hex | #base64 | :hex BOOL | :base64 BOOL]) -> STRING
 
@@ -335,7 +536,7 @@ MNode*  ml_sha256_string (MNode* cell, MlEnv* mlenv) {
     return ml_hash_string (cell, mlenv, fn_sha256);
 }
 
-/*DOC:
+/*--DOC:
 ===sha256-file===
  (sha256-file FILENAME [#serial | #named | #static | :serial BOOL | :named BOOL | :static BOOL] [#hex | #base64 | :hex BOOL | :base64 BOOL]) -> STRING
 
@@ -344,6 +545,7 @@ MNode*  ml_sha256_string (MNode* cell, MlEnv* mlenv) {
 MNode*  ml_sha256_file (MNode* cell, MlEnv* mlenv) {
     return ml_hash_file (cell, mlenv, fn_sha256_file);
 }
+#endif
 
 /*DOC:
 ===hmac-sha256-n-string===
@@ -397,3 +599,4 @@ MNode*  ml_hmac_sha256_n_string (MNode* cell, MlEnv* mlenv) {
     }
     return newMNode_str (new ustring (key));
 }
+
index 9af538f..ad8339d 100644 (file)
@@ -9,6 +9,9 @@ class  MlEnv;
 
 MNode*  ml_hmac_sha1 (MNode* cell, MlEnv* mlenv);
 MNode*  ml_hmac_sha256 (MNode* cell, MlEnv* mlenv);
+MNode*  ml_md5 (MNode* cell, MlEnv* mlenv);
+MNode*  ml_sha1 (MNode* cell, MlEnv* mlenv);
+MNode*  ml_sha256 (MNode* cell, MlEnv* mlenv);
 MNode*  ml_md5_string (MNode* cell, MlEnv* mlenv);
 MNode*  ml_md5_file (MNode* cell, MlEnv* mlenv);
 MNode*  ml_sha1_string (MNode* cell, MlEnv* mlenv);
index 2ccec4b..bdd46f8 100644 (file)
@@ -14,6 +14,7 @@
 #endif
 #include "util_const.h"
 #include "util_check.h"
+#include "util_file.h"
 #include "util_string.h"
 #include "util_proc.h"
 #include "util_time.h"
@@ -62,7 +63,7 @@ void  SendmailHdr::line (const ustring& t) {
     }
 }
 
-static void  sendmail (ustring& faddr, std::vector<ustring>& taddr, ustring& file, MlEnv* mlenv) {
+static void  sendmail (const ustring& text, const ustring& faddr, std::vector<ustring>& taddr, MlEnv* mlenv) {
 #ifdef UTF8JP
     MotorOutputIConvString  out ("ISO-2022-JP");
 #else
@@ -78,20 +79,16 @@ static void  sendmail (ustring& faddr, std::vector<ustring>& taddr, ustring& fil
     char**  argv;
     int  i;
     FILE*  fd;
-//    MotorOutput*  ob;
     static uregex  re_white ("^[ \\t]+");
 
-    if (file.size () == 0) 
+    if (text.size () == 0) 
        return;
 
-//    ob = mlenv->env->output;
-//    mlenv->env->output = &out;
     {
        AutoSwapMotor  swap (mlenv->env->output, out);
-       motor.compile_file (file);
+       motor.compile (text);
        motor.output (&out, mlenv->env);
     }
-//    mlenv->env->output = ob;
     b = out.ans.begin ();
     e = out.ans.end ();
     line.resize (0);
@@ -170,9 +167,18 @@ static void  sendmail (ustring& faddr, std::vector<ustring>& taddr, ustring& fil
     fclose (fd);
 }
 
+static void  sendmail_file (const ustring& file, const ustring& faddr, std::vector<ustring>& taddr, MlEnv* mlenv) {
+    if (file.size () == 0) 
+       return;
+
+    ustring  text;
+    if (readFile (file, text))
+       sendmail (text, faddr, taddr, mlenv);
+}
+
 /*DOC:
 ===mail===
- (mail FILENAME [#serial |:serial BOOL | #named | :named BOOL | #static | :static BOOL] :from ADDR :to ADDR_or_LIST) -> NIL
+ (mail [FILENAME | TEXT] [#serial |:serial BOOL | #named | :named BOOL | #static | :static BOOL | #text | :text BOOL] :from ADDR :to ADDR_or_LIST) -> NIL
 
 送り先の最大数は,100。
 
@@ -180,11 +186,9 @@ static void  sendmail (ustring& faddr, std::vector<ustring>& taddr, ustring& fil
 //#AFUNC       mail    ml_mail
 MNode*  ml_mail (MNode* cell, MlEnv* mlenv) {
     MNode*  arg = cell->cdr ();
-    ustring  file;
     StoreType  storetype;      // static
     ustring  faddr;
     std::vector<ustring>  taddr;
-    ustring  subject;
     MNodePtr  tolist;
     ustring  u;
     MNodePtr  t;
@@ -196,12 +200,13 @@ MNode*  ml_mail (MNode* cell, MlEnv* mlenv) {
        {CharConst ("serial"), true}, // 2
        {CharConst ("named"), true}, // 3
        {CharConst ("static"), true}, // 4
+       {CharConst ("text"), true}, // 5
        {NULL, 0, 0}
     };
 
     setParams (arg, 1, &params, kwlist, &keywords, NULL, true);
     storetype.setStatic ();
-    file = eval_str (params[0], mlenv);
+    storetype.setParam (eval_str (params[0], mlenv));
     if (evkw (0, t))
        faddr = to_string (t ());
     if (keywords[1])
@@ -212,6 +217,8 @@ MNode*  ml_mail (MNode* cell, MlEnv* mlenv) {
        storetype.setNamed ();
     if (keywords[4] && eval_bool (keywords[4], mlenv))         // static
        storetype.setStatic ();
+    if (keywords[5] && eval_bool (keywords[5], mlenv))         // text
+       storetype.setText ();
 
     if (! checkMailAddr (faddr)) {
        if (mlenv->log)
@@ -242,8 +249,8 @@ MNode*  ml_mail (MNode* cell, MlEnv* mlenv) {
 
     if (faddr.size () > 0 && taddr.size () > 0) {
        ustring  f;
-       f = storetype.src (mlenv, file);
-       sendmail (faddr, taddr, f, mlenv);
+       f = storetype.src (mlenv);
+       sendmail_file (f, faddr, taddr, mlenv);
     } else {
        if (faddr.size () == 0)
            if (mlenv->log)
@@ -257,6 +264,86 @@ MNode*  ml_mail (MNode* cell, MlEnv* mlenv) {
 }
 
 /*DOC:
+===sendmail===
+ (sendmail FROM_ADDR TO_ADDR_OR_LIST [:source-serial FILENAME | :source-named FILENAME | :source-static FILENAME | :source-text TEXT]) -> NIL
+
+送り先の最大数は,100。
+
+*/
+//#AFUNC       sendmail        ml_sendmail
+MNode*  ml_sendmail (MNode* cell, MlEnv* mlenv) {
+    MNode*  arg = cell->cdr ();
+    ustring  faddr;
+    std::vector<ustring>  taddr;
+    MNodePtr  tolist;
+    StoreType  storetype;      // static
+    ustring  u;
+    MNodePtr  t;
+    std::vector<MNode*>  params;
+    std::vector<MNode*>  keywords;
+    static paramList  kwlist[] = {
+       {CharConst ("source-serial"), false},   // 0
+       {CharConst ("source-named"), false},    // 1
+       {CharConst ("source-static"), false},   // 2
+       {CharConst ("source-text"), false},     // 3
+       {NULL, 0, 0}
+    };
+
+    setParams (arg, 2, &params, kwlist, &keywords, NULL);
+    storetype.setStatic ();
+    faddr = eval_str (params[0], mlenv);       // from
+    tolist = eval (params[1], mlenv);          // to
+    if (keywords[0])
+       storetype.srcSerial (eval_str (keywords[0], mlenv));    // :source-serial
+    if (keywords[1])
+       storetype.srcNamed (eval_str (keywords[1], mlenv));     // :source-named
+    if (keywords[2])
+       storetype.srcStatic (eval_str (keywords[2], mlenv));    // :source-static
+    if (keywords[3])
+       storetype.srcText (eval_str (keywords[3], mlenv));      // :source-text
+
+    if (! checkMailAddr (faddr)) {
+       if (mlenv->log)
+           *mlenv->log << faddr << uErrorBadMailAddr << "\n";
+       faddr.resize (0);
+    }
+
+    if (tolist () && tolist ()->isCons ()) {
+       MNode*  a = tolist ();
+       while (a) {
+           u = to_string (a->car ());
+           if (checkMailAddr (u)) {
+               taddr.push_back (u);
+           }
+           nextNode (a);                   
+       }
+    } else {
+       u = to_string (tolist ());
+       if (! checkMailAddr (u)) {
+           if (mlenv->log)
+               *mlenv->log << u << uErrorBadMailAddr << "\n";
+       } else {
+           taddr.push_back (u);
+       }
+    }
+    if (taddr.size () > TO_LIST_MAX)
+       throw (ustring ("too many addresses"));
+    if (faddr.size () == 0) {
+       if (mlenv->log)
+           *mlenv->log << "From address is undefined or illegal.\n";
+    } else if (taddr.size () == 0) {
+       if (mlenv->log)
+           *mlenv->log << "To address is undefined or illegal.\n";
+    } else {
+       ustring  text;
+       text = storetype.read (mlenv);
+       sendmail (text, faddr, taddr, mlenv);
+    }
+
+    return NULL;
+}
+
+/*DOC:
 ===mail-address-p===
  (mail-address-p STRING) -> BOOL
 
index 643350e..6fe3e4f 100644 (file)
@@ -5,6 +5,7 @@ class  MNode;
 class  MlEnv;
 
 MNode*  ml_mail (MNode* cell, MlEnv* mlenv);
+MNode*  ml_sendmail (MNode* cell, MlEnv* mlenv);
 MNode*  ml_mail_address_p (MNode* cell, MlEnv* mlenv);
 
 #endif /* ML_SENDMAIL_H */
index d830b5d..2543f3d 100644 (file)
@@ -63,7 +63,7 @@ StoreType::StoreType (MlEnv* mlenv) {
     }
 }
 
-ustring  StoreType::src (MlEnv* mlenv, const ustring& name) {
+const ustring  StoreType::src (MlEnv* mlenv, const ustring& name) {
     if (name.size () == 0)
        throw (uErrorFilenameEmpty);
     switch (type) {
@@ -78,6 +78,26 @@ ustring  StoreType::src (MlEnv* mlenv, const ustring& name) {
     }
 }
 
+const ustring  StoreType::src (MlEnv* mlenv) {
+    return src (mlenv, param);
+}
+
+ustring  StoreType::read (MlEnv* mlenv) {
+    if (type == F_TEXT) {
+       return param;
+    } else {
+       ustring  ans;
+       if (readFile (src (mlenv, param), ans, cPOSTLIMITHARD)) {
+           if (encoding.size () > 0 && ans.size () > 0) {
+               UIConv  cd (kCODE_UTF8, encoding.c_str ());
+               ans = cd.cv (ans);
+           }
+           ans = fixUTF8 (ans);
+       }
+       return ans;
+    }
+}
+
 //============================================================
 
 /*DOC:
@@ -545,39 +565,57 @@ MNode*  ml_set_xserial (MNode* cell, MlEnv* mlenv) {
 /*DOC:
 ===read-file===
  (read-file FILENAME [#serial | #named | :serial BOOL | :named BOOL] [:code ENCODING]) -> STRING
+ (read-file [:source-serial FILENAME | :source-named FILENAME | :source-static FILENAME] [:code ENCODING]) -> STRING
 
 */
 //#AFUNC       read-file       ml_read_file
 MNode*  ml_read_file (MNode* cell, MlEnv* mlenv) {
     MNode*  arg = cell->cdr ();
-    ustring  name;
     ustring  src;
     StoreType  storetype (mlenv);
     ustring  encoding;
     ustring  data;
     MNodePtr  t;
+#ifdef SOURCEFILECOMPAT
     std::vector<MNode*>  params;
+#endif
     std::vector<MNode*>  keywords;
     static paramList  kwlist[] = {
-       {CharConst ("code"), false}, // 0
-       {CharConst ("serial"), true}, // 1
-       {CharConst ("named"), true}, // 2
-       {CharConst ("static"), true}, // 3
+       {CharConst ("code"), false},            // 0
+       {CharConst ("source-serial"), false},   // 1
+       {CharConst ("source-named"), false},    // 2
+       {CharConst ("source-static"), false},   // 3
+#ifdef SOURCEFILECOMPAT
+       {CharConst ("serial"), true},           // 4
+       {CharConst ("named"), true},            // 5
+       {CharConst ("static"), true},           // 6
+#endif
        {NULL, 0, 0}
     };
 
+#ifdef SOURCEFILECOMPAT
     setParams (arg, 1, &params, kwlist, &keywords, NULL);
-    name = eval_str (params[0], mlenv);
+    storetype.setParam (eval_str (params[0], mlenv));
+#else
+    setParams (arg, 0, NULL, kwlist, &keywords, NULL);
+#endif
     if (evkw (0, t))
        encoding = to_string (t ());
-    if (keywords[1] && eval_bool (keywords[1], mlenv)) // serial
+    if (evkw (1, t))                           // :source-serial
+       storetype.srcSerial (t.to_string ());
+    if (evkw (2, t))                           // :source-named
+       storetype.srcNamed (t.to_string ());
+    if (evkw (3, t))                           // :source-static
+       storetype.srcStatic (t.to_string ());
+#ifdef SOURCEFILECOMPAT
+    if (keywords[4] && eval_bool (keywords[4], mlenv)) // serial
        storetype.setSerial ();
-    if (keywords[2] && eval_bool (keywords[2], mlenv)) // named
+    if (keywords[5] && eval_bool (keywords[5], mlenv)) // named
        storetype.setNamed ();
-    if (keywords[3] && eval_bool (keywords[3], mlenv)) // static
+    if (keywords[6] && eval_bool (keywords[6], mlenv)) // static
        storetype.setStatic ();
-
-    src = storetype.src (mlenv, name);
+#endif
+    src = storetype.src (mlenv);
 
     if (readFile (src, data, cPOSTLIMITHARD)) {
        if (encoding.size () > 0 && data.size () > 0) {
@@ -600,7 +638,6 @@ MNode*  ml_read_file (MNode* cell, MlEnv* mlenv) {
 //#AFUNC       write-file      ml_write_file
 MNode*  ml_write_file (MNode* cell, MlEnv* mlenv) {
     MNode*  arg = cell->cdr ();
-    ustring  name;
     ustring  tgt;
     StoreType  storetype (mlenv);
     ustring  encoding;
@@ -610,15 +647,15 @@ MNode*  ml_write_file (MNode* cell, MlEnv* mlenv) {
     std::vector<MNode*>  params;
     std::vector<MNode*>  keywords;
     static paramList  kwlist[] = {
-       {CharConst ("code"), false}, // 0
-       {CharConst ("crlf"), true}, // 1
-       {CharConst ("serial"), true}, // 2
-       {CharConst ("named"), true}, // 3
+       {CharConst ("code"), false},    // 0
+       {CharConst ("crlf"), true},     // 1
+       {CharConst ("serial"), true},   // 2
+       {CharConst ("named"), true},    // 3
        {NULL, 0, 0}
     };
 
     setParams (arg, 2, &params, kwlist, &keywords, NULL);
-    name = eval_str (params[0], mlenv);
+    storetype.setParam (eval_str (params[0], mlenv));
     data = eval_str (params[1], mlenv);
     if (evkw (0, t))
        encoding = to_string (t ());
@@ -628,8 +665,7 @@ MNode*  ml_write_file (MNode* cell, MlEnv* mlenv) {
        storetype.setSerial ();
     if (keywords[3] && eval_bool (keywords[3], mlenv)) // named
        storetype.setNamed ();
-
-    tgt = storetype.src (mlenv, name);
+    tgt = storetype.src (mlenv);
 
     if (encoding.size () > 0 && data.size () > 0) {
        UIConv  cd (encoding.c_str (), kCODE_UTF8);
@@ -757,6 +793,7 @@ MNode*  ml_datastore_progn (MNode* cell, MlEnv* mlenv) {
 /*DOC:
 ===new-storage===
  (new-storage NAME) -> NIL
+(set-storage NAME #create)と等価。
 
 */
 //#AFUNC       new-storage     ml_new_storage
@@ -930,31 +967,48 @@ MNode*  ml_restore_file (MNode* cell, MlEnv* mlenv) {
 /*DOC:
 ===delete-file===
  (delete-file NAME_STORAGE [#serial | #named | :serial BOOL | :named BOOL]) -> NIL
+ (delete-file [:target-serial FILENAME | :target-named FILENAME]) -> NIL
 
 */
 //#AFUNC       delete-file     ml_delete_file
 MNode*  ml_delete_file (MNode* cell, MlEnv* mlenv) {
     MNode*  arg = cell->cdr ();
-    ustring  name;
+    MNodePtr  t;
     ustring  tgt;
     StoreType  storetype (mlenv);
+#ifdef SOURCEFILECOMPAT
     std::vector<MNode*>  params;
+#endif
     std::vector<MNode*>  keywords;
     static paramList  kwlist[] = {
-       {CharConst ("serial"), true},
-       {CharConst ("named"), true},
+       {CharConst ("target-serial"), false},   // 1
+       {CharConst ("target-named"), false},    // 2
+#ifdef SOURCEFILECOMPAT
+       {CharConst ("serial"), true},           // 3
+       {CharConst ("named"), true},            // 4
+#endif
        {NULL, 0, 0}
     };
 
+#ifdef SOURCEFILECOMPAT
     setParams (arg, 1, &params, kwlist, &keywords, NULL);
-    name = eval_str (params[0], mlenv);
-    if (keywords[0] && eval_bool (keywords[0], mlenv)) // serial
+    storetype.setParam (eval_str (params[0], mlenv));
+#else
+    setParams (arg, 0, NULL, kwlist, &keywords, NULL);
+#endif
+    if (evkw (0, t))
+       storetype.srcSerial (t.to_string ());   // :source-serial
+    if (evkw (1, t))
+       storetype.srcNamed (t.to_string ());    // :source-named
+#ifdef SOURCEFILECOMPAT
+    if (keywords[2] && eval_bool (keywords[0], mlenv)) // serial
        storetype.setSerial ();
-    if (keywords[1] && eval_bool (keywords[1], mlenv)) // named
+    if (keywords[3] && eval_bool (keywords[1], mlenv)) // named
        storetype.setNamed ();
-
-    tgt = storetype.src (mlenv, name);
-    unlink (tgt.c_str ());
+#endif
+    tgt = storetype.src (mlenv);
+    if (tgt.length () > 0)
+       unlink (tgt.c_str ());
 
     return NULL;
 }
@@ -995,6 +1049,7 @@ MNode*  ml_rename_file (MNode* cell, MlEnv* mlenv) {
     return NULL;
 }
 
+#if 0
 class  ResponseParam {
 public:
     ustring  src;
@@ -1073,28 +1128,95 @@ public:
        src = storetype.src (mlenv, filename);
     };
 };
+#endif
 
 /*DOC:
 ===response-motor===
- (response-motor HTMLFILE [#serial | #named | #static | :serial BOOL | :named BOOL | :static BOOL]
              [:type MIME_TYPE] [#continue | :continue BOOL]) -> NIL
+ (response-motor HTMLFILE [#serial | #named | #static | :serial BOOL | :named BOOL | :static BOOL] [:type MIME_TYPE] [#continue | :continue BOOL]) -> NIL
(response-motor [:source-serial FILENAME | :source-named FILENAME | :source-static FILENAME] [:type MIME_TYPE] [#continue | :continue BOOL]) -> NIL
 
 */
 //#AFUNC       response-motor  ml_response_motor
 MNode*  ml_response_motor (MNode* cell, MlEnv* mlenv) {
+#if 0
     ResponseParam  par;
-
     par.proc (cell, mlenv, true);
-
     if (par.type.size () == 0) {
        mlenv->env->doMotor (par.src);
     } else {
        mlenv->env->doMotor (par.src, par.type);
     }
-
     if (! par.cflag)
        mlenv->breakProg ();
+#endif
+    MNode*  arg = cell->cdr ();
+    StoreType  storetype (mlenv);
+    ustring  type;
+    ustring  src;
+    bool  cflag = false;
+    MNodePtr  t;
+#ifdef SOURCEFILECOMPAT
+    std::vector<MNode*>  params;
+#endif
+    std::vector<MNode*>  keywords;
+    static paramList  kwlist[] = {
+       {CharConst ("type"), false},            // 0
+       {CharConst ("continue"), true},         // 1
+       {CharConst ("source-serial"), false},   // 2
+       {CharConst ("source-named"), false},    // 3
+       {CharConst ("source-static"), false},   // 4
+#ifdef SOURCEFILECOMPAT
+       {CharConst ("serial"), true},           // 5
+       {CharConst ("named"), true},            // 6
+       {CharConst ("static"), true},           // 7
+#endif
+       {NULL, 0, 0}
+    };
+
+#ifdef SOURCEFILECOMPAT
+    setParams (arg, 1, &params, kwlist, &keywords, NULL);
+    storetype.setParam (eval_str (params[0], mlenv));
+#else
+    setParams (arg, 0, NULL, kwlist, &keywords, NULL);
+#endif
+    if (evkw (0, t))                           // type
+       type = t.to_string ();
+    if (evkw (1, t))                           // continue
+       cflag = t.to_bool ();
+    if (evkw (2, t))                           // :source-serial
+       storetype.srcSerial (t.to_string ());
+    if (evkw (3, t))                           // :source-named
+       storetype.srcNamed (t.to_string ());
+    if (evkw (4, t))                           // :source-static
+       storetype.srcStatic (t.to_string ());
+#ifdef SOURCEFILECOMPAT
+    if (keywords[5] && eval_bool (keywords[5], mlenv)) // serial
+       storetype.setSerial ();
+    if (keywords[6] && eval_bool (keywords[6], mlenv)) // named
+       storetype.setNamed ();
+    if (keywords[7] && eval_bool (keywords[7], mlenv)) // static
+       storetype.setStatic ();
+#endif
+    src = storetype.src (mlenv);
     
+    if (type.empty ()) {
+       if (! fmotor && dispname.length () > 0) {
+           type = mimetype (getExt (dispname));
+       } else {
+           type = mimetype (getExt (filename));
+       }
+    } else if (! checkMimeType (type)) {
+       type = mimetype (type);
+    }
+
+    if (type.size () == 0) {
+       mlenv->env->doMotor (src);
+    } else {
+       mlenv->env->doMotor (src, type);
+    }
+    if (! cflag)
+       mlenv->breakProg ();
+
     return NULL;
 }
 /*DOC:
@@ -1105,18 +1227,90 @@ MNode*  ml_response_motor (MNode* cell, MlEnv* mlenv) {
 */
 //#AFUNC       response-file   ml_response_file
 MNode*  ml_response_file (MNode* cell, MlEnv* mlenv) {
+#if 0
     ResponseParam  par (mlenv);
-
     par.proc (cell, mlenv, false);
-
     if (par.finline || par.dispname.length () > 0) {
        mlenv->env->outputFile (par.src, par.type, par.finline, par.dispname);
     } else {
        mlenv->env->outputFile (par.src, par.type);
     }
-
     if (! par.cflag)
        mlenv->breakProg ();
+#endif
+    MNode*  arg = cell->cdr ();
+    StoreType  storetype (mlenv);
+    ustring  type;
+    ustring  src;
+    ustring  dispname;
+    bool  cflag = false;
+    bool  finline = false;
+    MNodePtr  t;
+#ifdef SOURCEFILECOMPAT
+    std::vector<MNode*>  params;
+#endif
+    std::vector<MNode*>  keywords;
+    static paramList  kwlist[] = {
+       {CharConst ("type"), false},            // 0
+       {CharConst ("continue"), true},         // 1
+       {CharConst ("inline"), true},           // 2
+       {CharConst ("name"), false},            // 3
+       {CharConst ("source-serial"), false},   // 4
+       {CharConst ("source-named"), false},    // 5
+       {CharConst ("source-static"), false},   // 6
+       {CharConst ("serial"), true},           // 7
+       {CharConst ("named"), true},            // 8
+       {CharConst ("static"), true},           // 9
+       {NULL, 0, 0}
+    };
+
+#ifdef SOURCEFILECOMPAT
+    setParams (arg, 1, &params, kwlist, &keywords, NULL);
+    storetype.setParam (eval_str (params[0], mlenv));
+#else
+    setParams (arg, 0, NULL, kwlist, &keywords, NULL);
+#endif
+    if (evkw (0, t))                           // type
+       type = t.to_string ();
+    if (evkw (1, t))                           // continue
+       cflag = t.to_bool ();
+    if (evkw (2, t))                           // inline
+       finline = t.to_bool ();
+    if (evkw (3, t))                           // name
+       dispname = t.to_string ();
+    if (evkw (4, t))                           // :source-serial
+       storetype.srcSerial (t.to_string ());
+    if (evkw (5, t))                           // :source-named
+       storetype.srcNamed (t.to_string ());
+    if (evkw (6, t))                           // :source-static
+       storetype.srcStatic (t.to_string ());
+#ifdef SOURCEFILECOMPAT
+    if (keywords[7] && eval_bool (keywords[7], mlenv)) // serial
+       storetype.setSerial ();
+    if (keywords[8] && eval_bool (keywords[8], mlenv)) // named
+       storetype.setNamed ();
+    if (keywords[9] && eval_bool (keywords[9], mlenv)) // static
+       storetype.setStatic ();
+#endif
+    src = storetype.src (mlenv);
+
+    if (type.empty ()) {
+       if (! fmotor && dispname.length () > 0) {
+           type = mimetype (getExt (dispname));
+       } else {
+           type = mimetype (getExt (filename));
+       }
+    } else if (! checkMimeType (type)) {
+       type = mimetype (type);
+    }
+
+    if (finline || dispname.length () > 0) {
+       mlenv->env->outputFile (src, type, finline, dispname);
+    } else {
+       mlenv->env->outputFile (src, type);
+    }
+    if (! cflag)
+       mlenv->breakProg ();
     
     return NULL;
 }
@@ -1124,35 +1318,56 @@ MNode*  ml_response_file (MNode* cell, MlEnv* mlenv) {
 /*DOC:
 ===filesize===
  (filesize FILENAME [#serial | #named | :serial BOOL | :named BOOL]) -> INTEGER or NIL
+ (filesize [:source-serial FILENAME | :source-named FILENAME | :source-static FILENAME]) -> INTEGER or NIL
 
 */
 //#AFUNC       filesize        ml_filesize
 MNode*  ml_filesize (MNode* cell, MlEnv* mlenv) {
     MNode*  arg = cell->cdr ();
-    ustring  filename;
+//    ustring  filename;
     StoreType  storetype (mlenv);
+    MNodePtr  t;
     ustring  src;
     off_t  size;
+#ifdef SOURCEFILECOMPAT
     std::vector<MNode*>  params;
+#endif
     std::vector<MNode*>  keywords;
     static paramList  kwlist[] = {
-       {CharConst ("serial"), true},
-       {CharConst ("named"), true},
-       {CharConst ("static"), true},
+       {CharConst ("source-serial"), false},   // 0
+       {CharConst ("source-named"), false},    // 1
+       {CharConst ("source-static"), false},   // 2
+#ifdef SOURCEFILECOMPAT
+       {CharConst ("serial"), true},           // 3
+       {CharConst ("named"), true},            // 4
+       {CharConst ("static"), true},           // 5
+#endif
        {NULL, 0, 0}
     };
 
+#ifdef SOURCEFILECOMPAT
     setParams (arg, 1, &params, kwlist, &keywords, NULL);
-    filename = eval_str (params[0], mlenv);
-    if (keywords[0] && eval_bool (keywords[0], mlenv)) // serial
+    storetype.setParam (eval_str (params[0], mlenv));
+#else
+    setParams (arg, 0, NULL, kwlist, &keywords, NULL);
+#endif
+    if (evkw (0, t))                           // :source-serial
+       storetype.srcSerial (t.to_string ());
+    if (evkw (1, t))                           // :source-named
+       storetype.srcNamed (t.to_string ());
+    if (evkw (2, t))                           // :source-static
+       storetype.srcStatic (t.to_string ());
+#ifdef SOURCEFILECOMPAT
+    if (keywords[3] && eval_bool (keywords[3], mlenv)) // serial
        storetype.setSerial ();
-    if (keywords[1] && eval_bool (keywords[1], mlenv)) // named
+    if (keywords[4] && eval_bool (keywords[4], mlenv)) // named
        storetype.setNamed ();
-    if (keywords[2] && eval_bool (keywords[2], mlenv)) // static
+    if (keywords[5] && eval_bool (keywords[5], mlenv)) // static
        storetype.setStatic ();
+#endif
+    src = storetype.src (mlenv);
 
-    src = storetype.src (mlenv, filename);
-    if (fileSize (src, size)) {
+    if (src.length () > 0 && fileSize (src, size)) {
        return newMNode_num (size);
     } else {
        return NULL;
@@ -1173,7 +1388,7 @@ MNode*  ml_list_files (MNode* cell, MlEnv* mlenv) {
     static paramList  kwlist[] = {
        {CharConst ("serial"), true},
        {CharConst ("named"), true},
-       {CharConst ("static"), true},
+//     {CharConst ("static"), true},
        {NULL, 0, 0}
     };
 
@@ -1182,8 +1397,8 @@ MNode*  ml_list_files (MNode* cell, MlEnv* mlenv) {
        storetype.setSerial ();
     if (keywords[1] && eval_bool (keywords[1], mlenv)) // named
        storetype.setNamed ();
-    if (keywords[2] && eval_bool (keywords[2], mlenv)) // static
-       storetype.setStatic ();
+//    if (keywords[2] && eval_bool (keywords[2], mlenv))       // static
+//     storetype.setStatic ();
 
     switch (storetype.type) {
     case StoreType::F_SERIAL:
index bde7348..45ccdd6 100644 (file)
@@ -13,13 +13,27 @@ class  StoreType {
        F_SERIAL,
        F_NAMED,
        F_STATIC,
+       F_TEXT,
     }  type;
 
+    ustring  param;
+    ustring  encoding;
+
     StoreType () {
        type = F_NONE;
     };
     StoreType (MlEnv* mlenv);
     virtual  ~StoreType () {};
+
+    virtual void  setParam (const ustring& name) {
+       param = name;
+    };
+    virtual bool  operator () () {
+       return type != F_NONE;
+    };
+    virtual bool  isText () {
+       return type == F_TEXT;
+    };
     virtual void  setSerial () {
        type = F_SERIAL;
     };
@@ -29,7 +43,31 @@ class  StoreType {
     virtual void  setStatic () {
        type = F_STATIC;
     };
-    virtual ustring  src (MlEnv* mlenv, const ustring& name);
+    virtual void  setText () {
+       type = F_TEXT;
+    };
+    virtual void  srcSerial (const ustring& name) {
+       param = name;
+       setSerial ();
+    };
+    virtual void  srcNamed (const ustring& name) {
+       param = name;
+       setNamed ();
+    };
+    virtual void  srcStatic (const ustring& name) {
+       param = name;
+       setStatic ();
+    };
+    virtual void  srcText (const ustring& name) {
+       param = name;
+       setText ();
+    };
+    virtual void  srcEncoding (const ustring& name) {
+       encoding = name;
+    };
+    virtual const ustring  src (MlEnv* mlenv, const ustring& name);
+    virtual const ustring  src (MlEnv* mlenv);
+    virtual ustring  read (MlEnv* mlenv);
 };
 
 void  newStoreSerial (MlEnv* mlenv);