summaryrefslogtreecommitdiff
path: root/apps/plugins/md5sum.c
diff options
context:
space:
mode:
authorAntoine Cellerier <dionoea@videolan.org>2008-06-10 13:20:05 +0000
committerAntoine Cellerier <dionoea@videolan.org>2008-06-10 13:20:05 +0000
commit34d4165f7b8a36419c417f164ccdebbe04808247 (patch)
tree236281d7a79b46322564ba0506b0178e864a9291 /apps/plugins/md5sum.c
parentf52696ef8a6e46b8379a0b2bc3d0661df3f9312e (diff)
downloadrockbox-34d4165f7b8a36419c417f164ccdebbe04808247.tar.gz
rockbox-34d4165f7b8a36419c417f164ccdebbe04808247.zip
New md5sum plugin. Open a file, a directory or just launch it from the plugin menu to create an md5sum of the file, the directory's contents or the whole filesystem. If the file's extension is .md5 or .md5sum, it will check the md5 sums in the file instead. If the file's extension is .md5list it will compute md5 sums for all the files listed.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@17709 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/plugins/md5sum.c')
-rw-r--r--apps/plugins/md5sum.c206
1 files changed, 206 insertions, 0 deletions
diff --git a/apps/plugins/md5sum.c b/apps/plugins/md5sum.c
new file mode 100644
index 0000000000..6845c4c473
--- /dev/null
+++ b/apps/plugins/md5sum.c
@@ -0,0 +1,206 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id: $
9 *
10 * Copyright (C) 2008 Antoine Cellerier <dionoea -at- videolan -dot- org>
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20#include "plugin.h"
21#include "lib/md5.h"
22
23PLUGIN_HEADER
24
25static const struct plugin_api *rb;
26
27int hash( char *string, const char *path )
28{
29 char *buffer[512];
30 ssize_t len;
31 struct md5_s md5;
32 int in = rb->open( path, O_RDONLY );
33 if( in < 0 ) return -1;
34
35 InitMD5( &md5 );
36 while( ( len = rb->read( in, buffer, 512 ) ) > 0 )
37 AddMD5( &md5, buffer, len );
38 EndMD5( &md5 );
39
40 psz_md5_hash( string, &md5 );
41
42 rb->close( in );
43 return 0;
44}
45
46void hash_file( int out, const char *path )
47{
48 char string[MD5_STRING_LENGTH+1];
49 if( hash( string, path ) )
50 rb->write( out, "error", 5 );
51 else
52 rb->write( out, string, MD5_STRING_LENGTH );
53 rb->write( out, " ", 1 );
54 rb->write( out, path, rb->strlen( path ) );
55 rb->write( out, "\n", 1 );
56}
57
58void hash_dir( int out, const char *path );
59void hash_dir( int out, const char *path )
60{
61 DIR *dir;
62 struct dirent *entry;
63
64 dir = rb->opendir( path );
65 if( dir )
66 {
67 while( ( entry = rb->readdir( dir ) ) )
68 {
69 char childpath[MAX_PATH];
70 rb->snprintf( childpath, MAX_PATH, "%s/%s",
71 path, entry->d_name );
72 if( entry->attribute & ATTR_DIRECTORY )
73 {
74 if( rb->strcmp( entry->d_name, "." )
75 && rb->strcmp( entry->d_name, ".." ) )
76 {
77 /* Got a sub directory */
78 hash_dir( out, childpath );
79 }
80 }
81 else
82 {
83 /* Got a file */
84 hash_file( out, childpath );
85 }
86 }
87 rb->closedir( dir );
88 }
89}
90
91void hash_list( int out, const char *path )
92{
93 int list = rb->open( path, O_RDONLY );
94 char newpath[MAX_PATH];
95 if( list < 0 ) return;
96
97 while( rb->read_line( list, newpath, MAX_PATH ) > 0 )
98 {
99 DIR *dir = rb->opendir( newpath );
100 if( dir )
101 {
102 rb->closedir( dir );
103 hash_dir( out, newpath );
104 }
105 else
106 {
107 hash_file( out, newpath );
108 }
109 }
110
111 rb->close( list );
112}
113
114void hash_check( int out, const char *path )
115{
116 int list = rb->open( path, O_RDONLY );
117 char line[MD5_STRING_LENGTH+1+MAX_PATH+1];
118 int len;
119 if( list < 0 ) return;
120
121 while( ( len = rb->read_line( list, line, MD5_STRING_LENGTH+1+MAX_PATH+1 ) ) > 0 )
122 {
123 const char *filename = rb->strchr( line, ' ' );
124 if( !filename || len < MD5_STRING_LENGTH + 2 )
125 {
126 const char error[] = "Malformed input line ... skipping";
127 rb->write( out, error, rb->strlen( error ) );
128 }
129 else
130 {
131 char string[MD5_STRING_LENGTH+1];
132 filename++;
133 rb->write( out, filename, rb->strlen( filename ) );
134 rb->write( out, ": ", 2 );
135 if( hash( string, filename ) )
136 rb->write( out, "FAILED open or read", 19 );
137 else if( rb->memcmp( line, string, MD5_STRING_LENGTH ) )
138 rb->write( out, "FAILED", 6 );
139 else
140 rb->write( out, "OK", 2 );
141 }
142 rb->write( out, "\n", 1 );
143 }
144}
145
146enum plugin_status plugin_start(const struct plugin_api* api, const void* parameter)
147{
148 const char *arg = (const char *)parameter; /* input file name, if any */
149 int out = -1; /* output file descriptor */
150 char filename[MAX_PATH]; /* output file name */
151
152 md5_init( api );
153 rb = api;
154
155 if( arg && *arg )
156 {
157 const char *ext = rb->strrchr( arg, '.' );
158 DIR *dir;
159 rb->snprintf( filename, MAX_PATH, "%s.md5sum", arg );
160 out = rb->open( filename, O_WRONLY|O_CREAT );
161 if( out < 0 ) return PLUGIN_ERROR;
162
163 if( ext )
164 {
165 if( !rb->strcmp( ext, ".md5" ) || !rb->strcmp( ext, ".md5sum" ) )
166 {
167 /* Lets check the sums */
168 hash_check( out, arg );
169 goto exit;
170 }
171 else if( !rb->strcmp( ext, ".md5list" ) ) /* ugly */
172 {
173 /* Hash listed files */
174 hash_list( out, arg );
175 goto exit;
176 }
177 }
178
179 dir = rb->opendir( arg );
180 if( dir )
181 {
182 api->closedir( dir );
183
184 /* Hash the directory's content recursively */
185 hash_dir( out, arg );
186 }
187 else
188 {
189 /* Hash the file */
190 hash_file( out, arg );
191 }
192 }
193 else
194 {
195 rb->snprintf( filename, MAX_PATH, "/everything.md5sum" );
196 out = rb->open( filename, O_WRONLY|O_CREAT );
197 if( out < 0 ) return PLUGIN_ERROR;
198
199 /* Hash the whole filesystem */
200 hash_dir( out, "/" );
201 }
202
203 exit:
204 rb->close( out );
205 return PLUGIN_OK;
206}