Fix FS#11007: Lua didn't parse negative numbers correct when reading from files
[kugel-rb.git] / apps / plugins / md5sum.c
blob973ffb323732dd1ede63fd25a39a81b2a79eb5f1
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 #define BUFFERSIZE 16384
29 static int count = 0;
30 static int done = 0;
31 static bool quit = false;
33 static int hash( char *string, const char *path )
35 static char buffer[BUFFERSIZE];
36 ssize_t len;
37 struct md5_s md5;
38 int in = rb->open( path, O_RDONLY );
39 if( in < 0 ) return -1;
41 InitMD5( &md5 );
42 while( !quit && ( len = rb->read( in, buffer, sizeof(buffer) ) ) > 0 )
44 AddMD5( &md5, buffer, len );
46 if( rb->get_action(CONTEXT_STD, TIMEOUT_NOBLOCK) == ACTION_STD_CANCEL )
47 quit = true;
50 EndMD5( &md5 );
52 psz_md5_hash( string, &md5 );
54 rb->close( in );
55 return 0;
58 static void hash_file( int out, const char *path )
60 if( out < 0 )
61 count++;
62 else
64 char string[MD5_STRING_LENGTH+1];
65 int status;
66 done++;
67 rb->splashf( 0, "%d / %d : %s", done, count, path );
68 status = hash( string, path );
70 if( quit )
71 return;
73 if( status )
74 rb->write( out, "error", 5 );
75 else
76 rb->write( out, string, MD5_STRING_LENGTH );
77 rb->write( out, " ", 2 );
78 rb->write( out, path, rb->strlen( path ) );
79 rb->write( out, "\n", 1 );
81 rb->yield();
85 static void hash_dir( int out, const char *path )
87 DIR *dir;
88 struct dirent *entry;
90 dir = rb->opendir( path );
91 if( dir )
93 while( !quit && ( entry = rb->readdir( dir ) ) )
95 char childpath[MAX_PATH];
96 rb->snprintf( childpath, MAX_PATH, "%s/%s",
97 rb->strcmp( path, "/" ) ? path : "", entry->d_name );
98 if( entry->attribute & ATTR_DIRECTORY )
100 if( rb->strcmp( entry->d_name, "." )
101 && rb->strcmp( entry->d_name, ".." ) )
103 /* Got a sub directory */
104 hash_dir( out, childpath );
107 else
109 /* Got a file */
110 hash_file( out, childpath );
113 rb->closedir( dir );
117 static void hash_list( int out, const char *path )
119 int list = rb->open( path, O_RDONLY );
120 char newpath[MAX_PATH];
121 if( list < 0 ) return;
123 while( !quit && rb->read_line( list, newpath, MAX_PATH ) > 0 )
125 DIR *dir = rb->opendir( newpath );
126 if( dir )
128 rb->closedir( dir );
129 hash_dir( out, newpath );
131 else
133 hash_file( out, newpath );
137 rb->close( list );
140 static void hash_check( int out, const char *path )
142 int list = rb->open( path, O_RDONLY );
143 char line[MD5_STRING_LENGTH+1+MAX_PATH+1];
144 int len;
145 if( list < 0 ) return;
147 while( !quit && ( len = rb->read_line( list, line, MD5_STRING_LENGTH+1+MAX_PATH+1 ) ) > 0 )
149 if( out < 0 )
150 count++;
151 else
153 const char *filename = rb->strchr( line, ' ' );
154 done++;
155 rb->splashf( 0, "%d / %d : %s", done, count, filename );
156 if( !filename || len < MD5_STRING_LENGTH + 2 )
158 const char error[] = "Malformed input line ... skipping";
159 rb->write( out, error, rb->strlen( error ) );
161 else
163 char string[MD5_STRING_LENGTH+1];
164 while( *filename == ' ' )
165 filename++;
166 rb->write( out, filename, rb->strlen( filename ) );
167 rb->write( out, ": ", 2 );
168 if( hash( string, filename ) )
169 rb->write( out, "FAILED open or read", 19 );
170 else if( rb->strncasecmp( line, string, MD5_STRING_LENGTH ) )
171 rb->write( out, "FAILED", 6 );
172 else
173 rb->write( out, "OK", 2 );
175 rb->write( out, "\n", 1 );
179 rb->close( list );
182 enum plugin_status plugin_start(const void* parameter)
184 const char *arg = (const char *)parameter; /* input file name, if any */
185 int out = -1; /* output file descriptor */
186 char filename[MAX_PATH]; /* output file name */
188 void (*action)( int, const char * ) = NULL;
190 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
191 rb->cpu_boost( true );
192 #endif
194 if( arg && *arg )
196 const char *ext = rb->strrchr( arg, '.' );
197 DIR *dir;
198 rb->snprintf( filename, MAX_PATH, "%s.md5sum", arg );
200 if( ext )
202 if( !rb->strcmp( ext, ".md5" ) || !rb->strcmp( ext, ".md5sum" ) )
204 rb->snprintf( filename + ( ext - arg ),
205 MAX_PATH + rb->strlen( ext ) - rb->strlen( arg ),
206 ".md5check" );
207 /* Lets check the sums */
208 action = hash_check;
210 else if( !rb->strcmp( ext, ".md5list" ) ) /* ugly */
212 /* Hash listed files */
213 action = hash_list;
217 if( !action )
219 dir = rb->opendir( arg );
220 if( dir )
222 rb->closedir( dir );
224 /* Hash the directory's content recursively */
225 action = hash_dir;
227 else
229 /* Hash the file */
230 action = hash_file;
234 else
236 rb->snprintf( filename, MAX_PATH, "/everything.md5sum" );
237 /* Hash the whole filesystem */
238 action = hash_dir;
239 arg = "/";
242 rb->lcd_puts( 0, 1, "Output file:" );
243 rb->lcd_puts( 0, 2, filename );
245 count = 0;
246 done = 0;
247 action( out, arg );
249 out = rb->open( filename, O_WRONLY|O_CREAT|O_TRUNC );
250 if( out < 0 ) return PLUGIN_ERROR;
251 action( out, arg );
252 rb->close( out );
253 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
254 rb->cpu_boost( false );
255 #endif
256 return PLUGIN_OK;