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