app is parsed from url
[rtmpdump.git] / rtmpdump.c
index 50c509c..be524c9 100644 (file)
 #include <stdlib.h>
 #include <string.h>
 #include <math.h>
-#include <unistd.h>
+#include <stdio.h>
 
 #include <signal.h>            // to catch Ctrl-C
 #include <getopt.h>
 
+#include "rtmp.h"
+#include "log.h"
+#include "parseurl.h"
+
 #ifdef WIN32
 #define fseeko fseeko64
 #define ftello ftello64
-#include <winsock.h>
-#include <stdio.h>
 #include <io.h>
 #include <fcntl.h>
 #define        SET_BINMODE(f)  setmode(fileno(f), O_BINARY)
 #define        SET_BINMODE(f)
 #endif
 
-#include "rtmp.h"
-#include "log.h"
-#include "parseurl.h"
-
-#ifdef CRYPTO
-#include <curl/curl.h>
-#define HASHLEN        32
-extern int SWFVerify(const char *url, unsigned int *size, unsigned char *hash);
-#define        InitCurl()      curl_global_init(CURL_GLOBAL_ALL)
-#define FreeCurl()     curl_global_cleanup()
-#else
-#define        InitCurl()
-#define FreeCurl()
-#endif
-
-#define RTMPDUMP_VERSION       "v2.0"
-
 #define RD_SUCCESS             0
 #define RD_FAILED              1
 #define RD_INCOMPLETE          2
@@ -564,8 +549,8 @@ OpenResumeFile(const char *flvFile, // file name [in]
               uint32_t * nMetaHeaderSize,      // length of metaHeader [out]
               double *duration)        // duration of the stream in ms [out]
 {
-  const size_t bufferSize = 1024;
-  char buffer[bufferSize];
+  size_t bufferSize = 0;
+  char hbuf[16], *buffer = NULL;
 
   *nMetaHeaderSize = 0;
   *size = 0;
@@ -584,34 +569,34 @@ OpenResumeFile(const char *flvFile,       // file name [in]
       uint32_t prevTagSize = 0;
 
       // check we've got a valid FLV file to continue!
-      if (fread(buffer, 1, 13, *file) != 13)
+      if (fread(hbuf, 1, 13, *file) != 13)
        {
          Log(LOGERROR, "Couldn't read FLV file header!");
          return RD_FAILED;
        }
-      if (buffer[0] != 'F' || buffer[1] != 'L' || buffer[2] != 'V'
-         || buffer[3] != 0x01)
+      if (hbuf[0] != 'F' || hbuf[1] != 'L' || hbuf[2] != 'V'
+         || hbuf[3] != 0x01)
        {
-         Log(LOGERROR, "Inavlid FLV file!");
+         Log(LOGERROR, "Invalid FLV file!");
          return RD_FAILED;
        }
 
-      if ((buffer[4] & 0x05) == 0)
+      if ((hbuf[4] & 0x05) == 0)
        {
          Log(LOGERROR,
              "FLV file contains neither video nor audio, aborting!");
          return RD_FAILED;
        }
 
-      uint32_t dataOffset = AMF_DecodeInt32(buffer + 5);
+      uint32_t dataOffset = AMF_DecodeInt32(hbuf + 5);
       fseek(*file, dataOffset, SEEK_SET);
 
-      if (fread(buffer, 1, 4, *file) != 4)
+      if (fread(hbuf, 1, 4, *file) != 4)
        {
          Log(LOGERROR, "Invalid FLV file: missing first prevTagSize!");
          return RD_FAILED;
        }
-      prevTagSize = AMF_DecodeInt32(buffer);
+      prevTagSize = AMF_DecodeInt32(hbuf);
       if (prevTagSize != 0)
        {
          Log(LOGWARNING,
@@ -626,18 +611,22 @@ OpenResumeFile(const char *flvFile,       // file name [in]
       while (pos < *size - 4 && !bFoundMetaHeader)
        {
          fseeko(*file, pos, SEEK_SET);
-         if (fread(buffer, 1, 4, *file) != 4)
+         if (fread(hbuf, 1, 4, *file) != 4)
            break;
 
-         uint32_t dataSize = AMF_DecodeInt24(buffer + 1);
+         uint32_t dataSize = AMF_DecodeInt24(hbuf + 1);
 
-         if (buffer[0] == 0x12)
+         if (hbuf[0] == 0x12)
            {
              if (dataSize > bufferSize)
                {
-                 Log(LOGERROR, "%s: dataSize (%d) > bufferSize (%d)",
-                     __FUNCTION__, dataSize, bufferSize);
-                 return RD_FAILED;
+                  /* round up to next page boundary */
+                  bufferSize = dataSize + 4095;
+                 bufferSize ^= (bufferSize & 4095);
+                 free(buffer);
+                  buffer = malloc(bufferSize);
+                  if (!buffer)
+                   return RD_FAILED;
                }
 
              fseeko(*file, pos + 11, SEEK_SET);
@@ -684,6 +673,7 @@ OpenResumeFile(const char *flvFile, // file name [in]
          pos += (dataSize + 11 + 4);
        }
 
+      free(buffer);
       if (!bFoundMetaHeader)
        Log(LOGWARNING, "Couldn't locate meta data!");
     }
@@ -709,7 +699,9 @@ GetLastKeyframe(FILE * file,        // output file [in]
   size = ftello(file);
 
   fseek(file, 4, SEEK_SET);
-  fread(&dataType, sizeof(uint8_t), 1, file);
+  if (fread(&dataType, sizeof(uint8_t), 1, file) != 1)
+    return RD_FAILED;
+
   bAudioOnly = (dataType & 0x4) && !(dataType & 0x1);
 
   Log(LOGDEBUG, "bAudioOnly: %d, size: %llu", bAudioOnly,
@@ -1145,7 +1137,7 @@ main(int argc, char **argv)
 
   LogPrintf("RTMPDump %s\n", RTMPDUMP_VERSION);
   LogPrintf
-    ("(c) 2009 Andrej Stepanchuk, Howard Chu, The Flvstreamer Team; license: GPL\n");
+    ("(c) 2010 Andrej Stepanchuk, Howard Chu, The Flvstreamer Team; license: GPL\n");
 
   if (!InitSockets())
     {
@@ -1154,8 +1146,6 @@ main(int argc, char **argv)
       return RD_FAILED;
     }
 
-  InitCurl();
-
   /* sleep(30); */
 
   int opt;
@@ -1266,7 +1256,7 @@ main(int argc, char **argv)
          LogPrintf("--verbose|-V            Verbose command output.\n");
          LogPrintf("--debug|-z              Debug level command output.\n");
          LogPrintf
-           ("If you don't pass parameters for swfUrl, pageUrl, app or auth these propertiews will not be included in the connect ");
+           ("If you don't pass parameters for swfUrl, pageUrl, or auth these properties will not be included in the connect ");
          LogPrintf("packet.\n\n");
          return RD_SUCCESS;
 #ifdef CRYPTO
@@ -1297,7 +1287,7 @@ main(int argc, char **argv)
          }
         case 'W':
          STR2AVAL(swfUrl, optarg);
-          if (SWFVerify(optarg, &swfSize, hash) == 0)
+          if (RTMP_HashSWF(optarg, &swfSize, hash, 1) == 0)
             {
               swfHash.av_val = (char *)hash;
               swfHash.av_len = HASHLEN;
@@ -1625,7 +1615,7 @@ main(int argc, char **argv)
          first = 0;
          LogPrintf("Connecting ...\n");
 
-         if (!RTMP_Connect(&rtmp))
+         if (!RTMP_Connect(&rtmp, NULL))
            {
              nStatus = RD_FAILED;
              break;
@@ -1718,8 +1708,6 @@ clean:
   if (file != 0)
     fclose(file);
 
-  FreeCurl();
-
   CleanupSockets();
 
 #ifdef _DEBUG