1 /*  Copyright (c) MediaArea.net SARL. All Rights Reserved.
2  *
3  *  Use of this source code is governed by a BSD-style license that can
4  *  be found in the License.html file in the root of the source tree.
5  */
6 
7 //---------------------------------------------------------------------------
8 #include <vector>
9 #include <algorithm>
10 #ifdef __BORLANDC__
11     #pragma hdrstop
12 #endif
13 //---------------------------------------------------------------------------
14 
15 //---------------------------------------------------------------------------
16 #include "Common/Core.h"
17 #include "CommandLine_Parser.h"
18 #include "Help.h"
19 #if defined(_MSC_VER) && defined(UNICODE)
20     #include "io.h"
21     #include "fcntl.h"
22 #endif
23 using namespace std;
24 using namespace MediaInfoNameSpace;
25 #include "MediaInfo/MediaInfo_Events.h"
26 //---------------------------------------------------------------------------
27 
28 //---------------------------------------------------------------------------
29 #if defined(_MSC_VER) && defined(UNICODE)
30     extern bool CLI_Option_Bom;
31 #endif //defined(_MSC_VER) && defined(UNICODE)
32 //---------------------------------------------------------------------------
33 
34 //****************************************************************************
35 // Event to manage
36 //****************************************************************************
37 
Log_0(struct MediaInfo_Event_Log_0 * Event,struct UserHandle_struct * UserHandler)38 void Log_0 (struct MediaInfo_Event_Log_0* Event, struct UserHandle_struct* UserHandler)
39 {
40     String MessageString;
41 
42     if (Event->Type>=0xC0)
43         MessageString+=__T("E: ");
44 
45     #if defined(UNICODE) || defined (_UNICODE)
46         MessageString+=Event->MessageStringU;
47     #else //defined(UNICODE) || defined (_UNICODE)
48         MessageString+=Event->MessageStringA;
49     #endif //defined(UNICODE) || defined (_UNICODE)
50 
51     //Special cases
52     switch (Event->MessageCode)
53     {
54         case 0xF1010101 : MessageString+=__T(" If you want to use such protocols, compile libcurl with SSL/SSH support"); break;
55         case 0xF1010102 :
56         case 0xF1010103 : MessageString+=__T(" If you are in a secure environment, do \"ssh %YourServerName%\" in order to add the fingerprint to the known_hosts file. If you want to ignore security issues, use --Ssh_IgnoreSecurity option"); break;
57         case 0xF1010104 : MessageString+=__T(" If you want to ignore security issues, use --Ssl_IgnoreSecurity option."); break;
58         default         : ;
59     }
60 
61     if (Event->Type>=0x80)
62         STRINGERR(MessageString);
63     else
64         STRINGOUT(MessageString);
65 }
66 
67 //****************************************************************************
68 // The callback function
69 //****************************************************************************
70 
Event_CallBackFunction(unsigned char * Data_Content,size_t Data_Size,void * UserHandler_Void)71 void __stdcall Event_CallBackFunction(unsigned char* Data_Content, size_t Data_Size, void* UserHandler_Void)
72 {
73     //*integrity tests
74     if (Data_Size<4)
75         return; //There is a problem
76 
77     //*Retrieving UserHandler
78     struct UserHandle_struct*           UserHandler=(struct UserHandle_struct*)UserHandler_Void;
79     struct MediaInfo_Event_Generic*     Event_Generic=(struct MediaInfo_Event_Generic*) Data_Content;
80 
81 
82     //*Retrieving EventID
83     //MediaInfo_int8u     ParserID    =(MediaInfo_int8u) ((Event_Generic->EventCode&0xFF000000)>>24);
84     MediaInfo_int16u    EventID     =(MediaInfo_int16u)((Event_Generic->EventCode&0x00FFFF00)>>8 );
85     MediaInfo_int8u     EventVersion=(MediaInfo_int8u) ( Event_Generic->EventCode&0x000000FF     );
86 
87     //*Global to all parsers
88     switch (EventID)
89     {
90         case MediaInfo_Event_Log                                                    : if (EventVersion==0 && Data_Size>=sizeof(struct MediaInfo_Event_Log_0)) Log_0((struct MediaInfo_Event_Log_0*)Data_Content, UserHandler); break;
91         default                                                                     : ;
92     }
93 }
94 
95 //***************************************************************************
96 // Main
97 //***************************************************************************
98 
main(int argc,char * argv_ansi[])99 int main(int argc, char* argv_ansi[])
100 {
101     //Localisation
102     setlocale(LC_ALL, "");
103     MediaInfo::Option_Static(__T("CharSet"), __T(""));
104 
105     //Initialize terminal (to fix Unicode output on Win32)
106     #if defined(_MSC_VER) && defined(UNICODE)
107         _setmode(_fileno(stdout), _O_U8TEXT);
108         _setmode(_fileno(stderr), _O_U8TEXT);
109         CLI_Option_Bom=false;
110     #endif
111     MediaInfo::Option_Static(__T("LineSeparator"), __T("\n")); //Using sdtout
112 
113     //Configure MediaInfo core
114     Core MI;
115     MI.Menu_View_Text(); //Default to text with CLI.
116 
117     //Retrieve command line (mainly for Unicode)
118     GETCOMMANDLINE();
119 
120     //Get real program name, if aviable
121     if(argc && argv_ansi[0] && argv_ansi[0][0])
122         Set_Program_Name(argv[0]);
123 
124     //Parse command line
125     vector<String> List;
126     for (int Pos=1; Pos<argc; Pos++)
127     {
128         //First part of argument (before "=") should be case insensitive
129         String Argument(argv[Pos]);
130         size_t Egal_Pos=Argument.find(__T('='));
131         if (Egal_Pos==string::npos)
132             Egal_Pos=Argument.size();
133         transform(Argument.begin(), Argument.begin()+Egal_Pos, Argument.begin(), (int(*)(int))tolower); //(int(*)(int)) is a patch for unix
134         int Return=Parse (MI, Argument);
135         if (Return==MI_STOP)
136             return MI_OK; //no more tasks to do
137         else if (Return==MI_ERROR)
138             return Return; //error
139         else if (Return==MI_ADD)
140             List.push_back(argv[Pos]); //Append the filename to the list of filenames to parse
141     }
142 
143     //If no filenames (and no options)
144     if (List.empty())
145         return Usage();
146 
147     //Callback for error handling
148     CallBack_Set(MI, (void*)Event_CallBackFunction);
149 
150     //Parse files
151     MI.Menu_File_Open_Files_Begin();
152     size_t Files_Count=0;
153     for (size_t Pos=0; Pos<List.size(); Pos++)
154         Files_Count+=MI.Menu_File_Open_Files_Continue(List[Pos]);
155 
156     //Output
157     STRINGOUT(MI.Inform_Get());
158 
159     //Output, in a file if needed
160     LogFile_Action(MI.Inform_Get());
161 
162     if (Files_Count)
163         return MI_OK;
164 
165     return MI_ERROR;
166 }
167 //---------------------------------------------------------------------------
168 
169