fix some problems with the menu code:
[kugel-rb.git] / apps / plugins / md5sum.c
blob6479f204a2737a252d25bf77eaf4c2edb8a41bec
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id: $
10 * Copyright (C) 2008 Antoine Cellerier <dionoea -at- videolan -dot- org>
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
22 #include "plugin.h"
23 #include "lib/md5.h"
25 PLUGIN_HEADER
27 static const struct plugin_api *rb;
29 MEM_FUNCTION_WRAPPERS(rb);
31 #define BUFFERSIZE 16384
33 static int count = 0;
34 static int done = 0;
35 static bool quit = false;
37 static int hash( char *string, const char *path )
39 static char buffer[BUFFERSIZE];
40 ssize_t len;
41 struct md5_s md5;
42 int in = rb->open( path, O_RDONLY );
43 if( in < 0 ) return -1;
45 InitMD5( &md5 );
46 while( !quit && ( len = rb->read( in, buffer, sizeof(buffer) ) ) > 0 )
48 AddMD5( &md5, buffer, len );
50 if( rb->get_action(CONTEXT_STD, TIMEOUT_NOBLOCK) == ACTION_STD_CANCEL )
51 quit = true;
54 EndMD5( &md5 );
56 psz_md5_hash( string, &md5 );
58 rb->close( in );
59 return 0;
62 static void hash_file( int out, const char *path )
64 if( out < 0 )
65 count++;
66 else
68 char string[MD5_STRING_LENGTH+1];
69 int status;
70 done++;
71 rb->splashf( 0, "%d / %d : %s", done, count, path );
72 status = hash( string, path );
74 if( quit )
75 return;
77 if( status )
78 rb->write( out, "error", 5 );
79 else
80 rb->write( out, string, MD5_STRING_LENGTH );
81 rb->write( out, " ", 2 );
82 rb->write( out, path, rb->strlen( path ) );
83 rb->write( out, "\n", 1 );
85 rb->yield();
89 static void hash_dir( int out, const char *path )
91 DIR *dir;
92 struct dirent *entry;
94 dir = rb->opendir( path );
95 if( dir )
97 while( !quit && ( entry = rb->readdir( dir ) ) )
99 char childpath[MAX_PATH];
100 rb->snprintf( childpath, MAX_PATH, "%s/%s",
101 rb->strcmp( path, "/" ) ? path : "", entry->d_name );
102 if( entry->attribute & ATTR_DIRECTORY )
104 if( rb->strcmp( entry->d_name, "." )
105 && rb->strcmp( entry->d_name, ".." ) )
107 /* Got a sub directory */
108 hash_dir( out, childpath );
111 else
113 /* Got a file */
114 hash_file( out, childpath );
117 rb->closedir( dir );
121 static void hash_list( int out, const char *path )
123 int list = rb->open( path, O_RDONLY );
124 char newpath[MAX_PATH];
125 if( list < 0 ) return;
127 while( !quit && rb->read_line( list, newpath, MAX_PATH ) > 0 )
129 DIR *dir = rb->opendir( newpath );
130 if( dir )
132 rb->closedir( dir );
133 hash_dir( out, newpath );
135 else
137 hash_file( out, newpath );
141 rb->close( list );
144 static void hash_check( int out, const char *path )
146 int list = rb->open( path, O_RDONLY );
147 char line[MD5_STRING_LENGTH+1+MAX_PATH+1];
148 int len;
149 if( list < 0 ) return;
151 while( !quit && ( len = rb->read_line( list, line, MD5_STRING_LENGTH+1+MAX_PATH+1 ) ) > 0 )
153 if( out < 0 )
154 count++;
155 else
157 const char *filename = rb->strchr( line, ' ' );
158 done++;
159 rb->splashf( 0, "%d / %d : %s", done, count, filename );
160 if( !filename || len < MD5_STRING_LENGTH + 2 )
162 const char error[] = "Malformed input line ... skipping";
163 rb->write( out, error, rb->strlen( error ) );
165 else
167 char string[MD5_STRING_LENGTH+1];
168 while( *filename == ' ' )
169 filename++;
170 rb->write( out, filename, rb->strlen( filename ) );
171 rb->write( out, ": ", 2 );
172 if( hash( string, filename ) )
173 rb->write( out, "FAILED open or read", 19 );
174 else if( rb->strncasecmp( line, string, MD5_STRING_LENGTH ) )
175 rb->write( out, "FAILED", 6 );
176 else
177 rb->write( out, "OK", 2 );
179 rb->write( out, "\n", 1 );
183 rb->close( list );
186 enum plugin_status plugin_start(const struct plugin_api* api, const void* parameter)
188 const char *arg = (const char *)parameter; /* input file name, if any */
189 int out = -1; /* output file descriptor */
190 char filename[MAX_PATH]; /* output file name */
192 void (*action)( int, const char * ) = NULL;
194 md5_init( api );
195 rb = api;
196 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
197 rb->cpu_boost( true );
198 #endif
200 if( arg && *arg )
202 const char *ext = rb->strrchr( arg, '.' );
203 DIR *dir;
204 rb->snprintf( filename, MAX_PATH, "%s.md5sum", arg );
206 if( ext )
208 if( !rb->strcmp( ext, ".md5" ) || !rb->strcmp( ext, ".md5sum" ) )
210 rb->snprintf( filename + ( ext - arg ),
211 MAX_PATH + rb->strlen( ext ) - rb->strlen( arg ),
212 ".md5check" );
213 /* Lets check the sums */
214 action = hash_check;
216 else if( !rb->strcmp( ext, ".md5list" ) ) /* ugly */
218 /* Hash listed files */
219 action = hash_list;
223 if( !action )
225 dir = rb->opendir( arg );
226 if( dir )
228 api->closedir( dir );
230 /* Hash the directory's content recursively */
231 action = hash_dir;
233 else
235 /* Hash the file */
236 action = hash_file;
240 else
242 rb->snprintf( filename, MAX_PATH, "/everything.md5sum" );
243 /* Hash the whole filesystem */
244 action = hash_dir;
245 arg = "/";
248 rb->lcd_puts( 0, 1, "Output file:" );
249 rb->lcd_puts( 0, 2, filename );
251 count = 0;
252 done = 0;
253 action( out, arg );
255 out = rb->open( filename, O_WRONLY|O_CREAT|O_TRUNC );
256 if( out < 0 ) return PLUGIN_ERROR;
257 action( out, arg );
258 rb->close( out );
259 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
260 rb->cpu_boost( false );
261 #endif
262 return PLUGIN_OK;