Prepare new maemo release
[maemo-rb.git] / apps / plugins / md5sum.c
blobc993018852d7a70d4f64f9bfe1ef209e50865ae3
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"
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 );
99 struct dirinfo info = rb->dir_get_info(dir, entry);
100 if (info.attribute & ATTR_DIRECTORY)
102 if( rb->strcmp( entry->d_name, "." )
103 && rb->strcmp( entry->d_name, ".." ) )
105 /* Got a sub directory */
106 hash_dir( out, childpath );
109 else
111 /* Got a file */
112 hash_file( out, childpath );
115 rb->closedir( dir );
119 static void hash_list( int out, const char *path )
121 int list = rb->open( path, O_RDONLY );
122 char newpath[MAX_PATH];
123 if( list < 0 ) return;
125 while( !quit && rb->read_line( list, newpath, MAX_PATH ) > 0 )
127 DIR *dir = rb->opendir( newpath );
128 if( dir )
130 rb->closedir( dir );
131 hash_dir( out, newpath );
133 else
135 hash_file( out, newpath );
139 rb->close( list );
142 static void hash_check( int out, const char *path )
144 int list = rb->open( path, O_RDONLY );
145 char line[MD5_STRING_LENGTH+1+MAX_PATH+1];
146 int len;
147 if( list < 0 ) return;
149 while( !quit && ( len = rb->read_line( list, line, MD5_STRING_LENGTH+1+MAX_PATH+1 ) ) > 0 )
151 if( out < 0 )
152 count++;
153 else
155 const char *filename = rb->strchr( line, ' ' );
156 done++;
157 rb->splashf( 0, "%d / %d : %s", done, count, filename );
158 if( !filename || len < MD5_STRING_LENGTH + 2 )
160 const char error[] = "Malformed input line ... skipping";
161 rb->write( out, error, rb->strlen( error ) );
163 else
165 char string[MD5_STRING_LENGTH+1];
166 while( *filename == ' ' )
167 filename++;
168 rb->write( out, filename, rb->strlen( filename ) );
169 rb->write( out, ": ", 2 );
170 if( hash( string, filename ) )
171 rb->write( out, "FAILED open or read", 19 );
172 else if( rb->strncasecmp( line, string, MD5_STRING_LENGTH ) )
173 rb->write( out, "FAILED", 6 );
174 else
175 rb->write( out, "OK", 2 );
177 rb->write( out, "\n", 1 );
181 rb->close( list );
184 enum plugin_status plugin_start(const void* parameter)
186 const char *arg = (const char *)parameter; /* input file name, if any */
187 int out = -1; /* output file descriptor */
188 char filename[MAX_PATH]; /* output file name */
190 void (*action)( int, const char * ) = NULL;
192 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
193 rb->cpu_boost( true );
194 #endif
196 if( arg && *arg )
198 const char *ext = rb->strrchr( arg, '.' );
199 DIR *dir;
200 rb->snprintf( filename, MAX_PATH, "%s.md5sum", arg );
202 if( ext )
204 if( !rb->strcmp( ext, ".md5" ) || !rb->strcmp( ext, ".md5sum" ) )
206 rb->snprintf( filename + ( ext - arg ),
207 MAX_PATH + rb->strlen( ext ) - rb->strlen( arg ),
208 ".md5check" );
209 /* Lets check the sums */
210 action = hash_check;
212 else if( !rb->strcmp( ext, ".md5list" ) ) /* ugly */
214 /* Hash listed files */
215 action = hash_list;
219 if( !action )
221 dir = rb->opendir( arg );
222 if( dir )
224 rb->closedir( dir );
226 /* Hash the directory's content recursively */
227 action = hash_dir;
229 else
231 /* Hash the file */
232 action = hash_file;
236 else
238 rb->snprintf( filename, MAX_PATH, "/everything.md5sum" );
239 /* Hash the whole filesystem */
240 action = hash_dir;
241 arg = "/";
244 rb->lcd_puts( 0, 1, "Output file:" );
245 rb->lcd_puts( 0, 2, filename );
247 count = 0;
248 done = 0;
249 action( out, arg );
251 out = rb->open( filename, O_WRONLY|O_CREAT|O_TRUNC , 0666);
252 if( out < 0 ) return PLUGIN_ERROR;
253 action( out, arg );
254 rb->close( out );
255 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
256 rb->cpu_boost( false );
257 #endif
258 return PLUGIN_OK;