21d4f715c4a342a68099b13ce5a3d68f3443677d
[platform/upstream/flac.git] / src / monkeys_audio_utilities / flac_mac / main.c
1 /* flac_mac - wedge utility to add FLAC support to Monkey's Audio
2  * Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007,2008,2009  Josh Coalson
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  */
18
19 /*
20  * This program can be used to allow FLAC to masquerade as one of the other
21  * supported lossless codecs in Monkey's Audio.  See the documentation for
22  * how to do this.
23  */
24
25 #if HAVE_CONFIG_H
26 #  include <config.h>
27 #endif
28
29 #include<stdio.h>
30 #include<stdlib.h>
31 #include<string.h>
32 #include<wtypes.h>
33 #include<process.h>
34 #include<winbase.h>
35
36 static int execit(char *prog, char *args);
37 static int forkit(char *prog, char *args);
38
39 int main(int argc, char *argv[])
40 {
41         int flac_return_val = 0, opt_arg = 1, from_arg = -1, to_arg = -1, flac_level = 5, i;
42         char prog[MAX_PATH], cmdline[MAX_PATH*2], from[MAX_PATH], to[MAX_PATH], macdir[MAX_PATH], options[256], *p;
43         enum { WAVPACK, RKAU, SHORTEN } codec;
44
45         /* get the directory where MAC external codecs reside */
46         if(0 != (p = strrchr(argv[0],'\\'))) {
47                 strcpy(macdir, argv[0]);
48                 *(strrchr(macdir,'\\')+1) = '\0';
49         }
50         else {
51                 strcpy(macdir, "");
52         }
53
54         /* determine which codec we were called as and parse the options */
55         if(p == 0)
56                 p = argv[0];
57         else
58                 p++;
59         if(0 == strnicmp(p, "short", 5)) {
60                 codec = SHORTEN;
61         }
62         else if(0 == strnicmp(p, "rkau", 4)) {
63                 codec = RKAU;
64                 if(argv[1][0] == '-' && argv[1][1] == 'l') {
65                         opt_arg = 2;
66                         switch(argv[1][2]) {
67                                 case '1': flac_level = 1; break;
68                                 case '2': flac_level = 5; break;
69                                 case '3': flac_level = 8; break;
70                         }
71                 }
72         }
73         else if(0 == strnicmp(p, "wavpack", 7)) {
74                 codec = WAVPACK;
75                 if(argv[1][0] == '-') {
76                         opt_arg = 2;
77                         switch(argv[1][1]) {
78                                 case 'f': flac_level = 1; break;
79                                 case 'h': flac_level = 8; break;
80                                 default: opt_arg = 1;
81                         }
82                 }
83         }
84         else {
85                 return -5;
86         }
87
88         /* figure out which arguments are the source and destination files */
89         for(i = 1; i < argc; i++)
90                 if(argv[i][0] != '-') {
91                         from_arg = i++;
92                         break;
93                 }
94         for( ; i < argc; i++)
95                 if(argv[i][0] != '-') {
96                         to_arg = i++;
97                         break;
98                 }
99         if(to_arg < 0)
100                 return -4;
101
102         /* build the command to call flac with */
103         flac_snprintf(prog, sizeof (prog), "%sflac.exe", macdir);
104         flac_snprintf(options, sizeof (options), "-%d", flac_level);
105         for(i = opt_arg; i < argc; i++)
106                 if(argv[i][0] == '-') {
107                         strcat(options, " ");
108                         strcat(options, argv[i]);
109                 }
110         flac_snprintf(cmdline, sizeof (cmdline), "\"%s\" %s -o \"%s\" \"%s\"", prog, options, argv[to_arg], argv[from_arg]);
111
112         flac_return_val = execit(prog, cmdline);
113
114         /*
115          * Now that flac has finished, we need to fork a process that will rename
116          * the resulting file with the correct extension once MAC has moved it to
117          * it's final resting place.
118          */
119         if(0 == flac_return_val) {
120                 /* get the destination directory, if any */
121                 if(0 != (p = strchr(argv[to_arg],'\\'))) {
122                         strcpy(from, argv[to_arg]);
123                         *(strrchr(from,'\\')+1) = '\0';
124                 }
125                 else {
126                         strcpy(from, "");
127                 }
128
129                 /* for the full 'from' and 'to' paths for the renamer process */
130                 p = strrchr(argv[from_arg],'\\');
131                 strcat(from, p? p+1 : argv[from_arg]);
132                 strcpy(to, from);
133                 if(0 == strchr(from,'.'))
134                         return -3;
135                 switch(codec) {
136                         case SHORTEN: strcpy(strrchr(from,'.'), ".shn"); break;
137                         case WAVPACK: strcpy(strrchr(from,'.'), ".wv"); break;
138                         case RKAU: strcpy(strrchr(from,'.'), ".rka"); break;
139                 }
140                 strcpy(strrchr(to,'.'), ".flac");
141
142                 flac_snprintf(prog, sizeof (prog), "%sflac_ren.exe", macdir);
143                 flac_snprintf(cmdline, sizeof (smdline), "\"%s\" \"%s\" \"%s\"", prog, from, to);
144
145                 flac_return_val = forkit(prog, cmdline);
146         }
147
148         return flac_return_val;
149 }
150
151 int execit(char *prog, char *args)
152 {
153         BOOL ok;
154         STARTUPINFO startup_info;
155         PROCESS_INFORMATION proc_info;
156
157         GetStartupInfo(&startup_info);
158
159         ok = CreateProcess(
160                 prog,
161                 args,
162                 0, /*process security attributes*/
163                 0, /*thread security attributes*/
164                 FALSE,
165                 0, /*dwCreationFlags*/
166                 0, /*environment*/
167                 0, /*lpCurrentDirectory*/
168                 &startup_info,
169                 &proc_info
170         );
171         if(ok) {
172                 DWORD dw;
173                 dw = WaitForSingleObject(proc_info.hProcess, INFINITE);
174                 ok = (dw != 0xFFFFFFFF);
175                 CloseHandle(proc_info.hThread);
176                 CloseHandle(proc_info.hProcess);
177         }
178
179         return ok? 0 : -1;
180 }
181
182 int forkit(char *prog, char *args)
183 {
184         BOOL ok;
185         STARTUPINFO startup_info;
186         PROCESS_INFORMATION proc_info;
187
188         GetStartupInfo(&startup_info);
189
190         ok = CreateProcess(
191                 prog,
192                 args,
193                 0, /*process security attributes*/
194                 0, /*thread security attributes*/
195                 FALSE,
196                 DETACHED_PROCESS, /*dwCreationFlags*/
197                 0, /*environment*/
198                 0, /*lpCurrentDirectory*/
199                 &startup_info,
200                 &proc_info
201         );
202         if(ok) {
203                 CloseHandle(proc_info.hThread);
204                 CloseHandle(proc_info.hProcess);
205         }
206
207         return ok? 0 : -2;
208 }