summaryrefslogtreecommitdiff
path: root/apps/plugins/md5sum.c
diff options
context:
space:
mode:
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}