]> err.no Git - sope/blob - sope-mime/samples/ImapListTool.m
fixed copyrights for 2005
[sope] / sope-mime / samples / ImapListTool.m
1 /*
2   Copyright (C) 2000-2005 SKYRIX Software AG
3
4   This file is part of SOPE.
5
6   SOPE is free software; you can redistribute it and/or modify it under
7   the terms of the GNU Lesser General Public License as published by the
8   Free Software Foundation; either version 2, or (at your option) any
9   later version.
10
11   SOPE is distributed in the hope that it will be useful, but WITHOUT ANY
12   WARRANTY; without even the implied warranty of MERCHANTABILITY or
13   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
14   License for more details.
15
16   You should have received a copy of the GNU Lesser General Public
17   License along with SOPE; see the file COPYING.  If not, write to the
18   Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
19   02111-1307, USA.
20 */
21
22 #include "ImapListTool.h"
23 #include "common.h"
24 #include <NGImap4/NGImap4.h>
25 #include <EOControl/EOControl.h>
26 #include <NGImap4/NGImap4FileManager.h>
27 #include <NGImap4/NGImap4Message.h>
28
29 @implementation ImapListTool
30
31 /* output */
32
33 - (BOOL)outputResultsAsList:(NSArray *)dirContents
34   fileManager:(NGImap4FileManager *)fm part:(NSString *)_part
35 {
36   unsigned i, count;
37   NSString *path = [fm currentDirectoryPath];
38   
39   for (i = 0, count = [dirContents count]; i < count; i++) {
40     NSString     *cpath, *apath;
41     NSDictionary *info;
42     NSString     *mid;
43         
44     if (!self->useDataSource) {
45       cpath = [dirContents objectAtIndex:i];
46       apath = [path stringByAppendingPathComponent:cpath];
47         
48       info = [fm fileAttributesAtPath:apath
49                  traverseLink:NO];
50     }
51     else {
52       info = [dirContents objectAtIndex:i];
53       cpath = [NSString stringWithFormat:@"%u", [(id)info uid]];
54       apath = [path stringByAppendingPathComponent:cpath];
55       //cpath = [info valueForKey:@"NSFileName"];
56       //apath = [info valueForKey:@"NSFilePath"];
57     }
58     
59     mid = [[info valueForKey:@"NSFileIdentifier"] description];
60     if ([mid length] > 39) {
61       mid = [mid substringToIndex:37];
62       mid = [mid stringByAppendingString:@"..."];
63     }
64         
65     /* id uid date name */
66     if (_part) {
67       printf("%10d ",
68              [[fm contentsAtPath:[info valueForKey:@"NSFilePath"]
69                   part:_part] length]);
70     }
71     printf("%-40s  %8s  %8i  %-32s %s",
72            [mid cString],
73            [[info valueForKey:NSFileOwnerAccountName]      cString],
74            [[info valueForKey:NSFileSize] intValue],
75            [[[info valueForKey:NSFileModificationDate]
76               description] cString],
77            [apath cString]);
78
79     if ([[info valueForKey:NSFileType]
80           isEqualToString:NSFileTypeDirectory])
81       printf("/\n");
82     else
83       printf("\n");
84
85     
86   }
87   return YES;
88 }
89
90 - (BOOL)outputResultsAsXML:(NSArray *)_dirContents
91   fileManager:(NGFileManager *)_fm 
92 {
93   NSLog(@"XML output not implemented ...");
94   return NO;
95 }
96
97 - (BOOL)outputResults:(NSArray *)dirContents
98   fileManager:(NGImap4FileManager *)fm part:(NSString *)_part
99 {
100   NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
101   NSAutoreleasePool *pool;
102   NSString *out;
103   BOOL result;
104   
105   pool = [[NSAutoreleasePool alloc] init];
106   
107   out = [ud stringForKey:@"out"];
108   if ([out length] == 0)
109     result = YES;
110   else if ([out isEqualToString:@"xml"])
111     result = [self outputResultsAsXML:dirContents fileManager:fm];
112   else if ([out isEqualToString:@"ls"]) 
113     result = [self outputResultsAsList:dirContents fileManager:fm part:_part];
114   else {
115     NSLog(@"unknown output module: %@", out);
116     result = NO;
117   }
118   [pool release];
119   return result;
120 }
121
122 /* ops */
123
124 - (void)processFile:(NSString *)path fileManager:(NGImap4FileManager *)fm
125   part:(NSString *)_part
126 {
127   /* a file */
128   NSData   *contents;
129   NSString *s;
130
131   if (_part) {
132     if ((contents = [fm contentsAtPath:path part:_part]) == nil) {
133       NSLog(@"could not get content of message: '%@'", path);
134     }
135     else {
136       s = [[NSString alloc] initWithData:contents
137                             encoding:[NSString defaultCStringEncoding]];
138       printf("%s\n", [s cString]);
139       [s release];
140     }
141   }
142   else {
143     NGImap4Message *contents;
144   
145     if ((contents = [fm messageAtPath:path]) == nil) {
146       NSLog(@"could not get message at path: '%@'", path);
147     }
148     else {
149 #if 0
150       s = [[NSString alloc] initWithData:contents
151                             encoding:[NSString defaultCStringEncoding]];
152       printf("%s\n", [s cString]);
153       [s release];
154 #else
155       printf("%s\n", [[contents description] cString]);
156       printf("%s\n", [[[contents bodyStructure] description] cString]);
157     
158 #endif
159     }
160   }
161 }
162
163 - (void)processFolder:(NSString *)path fileManager:(NGImap4FileManager *)fm
164   part:(NSString *)_part
165 {
166   NSAutoreleasePool *pool;
167   NSTimeInterval startTime, endTime;
168   unsigned int   startSize, endSize;
169   NSProcessInfo  *pi = [NSProcessInfo processInfo];
170   NSArray        *dirContents;
171   unsigned       i;
172   EODataSource   *ds;
173   
174   if (![fm changeCurrentDirectoryPath:path]) {
175     NSLog(@"%s: could not change to directory: '%@'", path);
176   }
177
178   ds = self->useDataSource
179     ? [(id<NGFileManagerDataSources>)fm dataSourceAtPath:path]
180     : nil;
181   
182   /* pre fetches */
183   
184   for (i = 0; i < self->preloops; i++ ) {
185     NSAutoreleasePool *pool;
186     
187     startTime = [[NSDate date] timeIntervalSince1970];
188     startSize = [pi virtualMemorySize];
189     
190     /* fetch */
191     
192     pool = [[NSAutoreleasePool alloc] init];
193     {
194       ds = self->useDataSource
195         ? [(id<NGFileManagerDataSources>)fm dataSourceAtPath:path]
196         : nil;
197   
198       dirContents = (!self->useDataSource)
199         ? [fm directoryContentsAtPath:path]
200         : [ds fetchObjects];
201     }
202     [pool release];
203     
204     /* statistics */
205     
206     endSize = [pi virtualMemorySize];
207     endTime = [[NSDate date] timeIntervalSince1970];
208     
209     if (self->stats) {
210       fprintf(stderr, 
211               "parsing time [%2i]: %.3fs, "
212               "vmem-diff: %8i (%4iK,%4iM), vmem: %8i (%4iK,%4iM))\n", 
213               i, (endTime-startTime), 
214               (endSize - startSize), 
215               (endSize - startSize) / 1024, 
216               (endSize - startSize) / 1024 / 1024, 
217               endSize, endSize/1024, endSize/1024/1024);
218     }
219   }
220   
221   /* actual fetch */
222
223   startTime = [[NSDate date] timeIntervalSince1970];
224   startSize = [pi virtualMemorySize];
225
226   pool = [[NSAutoreleasePool alloc] init];
227   
228   ds = self->useDataSource
229     ? [(id<NGFileManagerDataSources>)fm dataSourceAtPath:path]
230     : nil;
231   
232   dirContents = (!self->useDataSource)
233     ? [fm directoryContentsAtPath:path]
234     : [ds fetchObjects];
235   
236   dirContents = [dirContents retain];
237   [pool release];
238   dirContents = [dirContents autorelease];
239   
240   /* statistics */
241       
242   endSize = [pi virtualMemorySize];
243   endTime = [[NSDate date] timeIntervalSince1970];
244   
245   if (self->stats) {
246     fprintf(stderr, 
247             "parsing time: %.3fs, "
248             "vmem-diff: %8i (%4iK,%4iM), vmem: %8i (%4iK,%4iM))\n", 
249             (endTime-startTime), 
250             (endSize - startSize), 
251             (endSize - startSize) / 1024, 
252             (endSize - startSize) / 1024 / 1024, 
253             endSize, endSize/1024, endSize/1024/1024);
254   }
255   
256   /* output */
257   [self outputResults:dirContents fileManager:fm part:_part];
258 }
259
260 /*
261   path /INBOX/1233?part=1.2
262 */
263
264
265 - (void)processPath:(NSString *)path fileManager:(NGImap4FileManager *)fm {
266   BOOL    isDir;
267   NSArray *array;
268   NSString *part;
269
270   array = [path componentsSeparatedByString:@"?"];
271
272   if ([array count] > 1) {
273     path = [array objectAtIndex:0];
274     part = [[[array objectAtIndex:1] componentsSeparatedByString:@"="]
275                      lastObject]; 
276   }
277   else
278     part = nil;
279   
280   if (![fm fileExistsAtPath:path isDirectory:&isDir]) {
281     NSLog(@"file/directory does not exist: %@", path);
282     return;
283   }
284     
285   if (isDir) {
286     [self processFolder:path fileManager:fm part:part];
287   }
288   else {
289     [self processFile:path fileManager:fm part:part];
290   }
291 }
292
293 /* tool operation */
294  
295 - (int)usage {
296   fprintf(stderr, "usage: imapls <pathes>?part=<part>\n");
297   fprintf(stderr, "usage: imapls <pathes>\n");
298   fprintf(stderr, "  -url        <url>\n");
299   fprintf(stderr, "  -user       <login>\n");
300   fprintf(stderr, "  -password   <pwd>\n");
301   fprintf(stderr, "  -host       <host>\n");
302   fprintf(stderr, "  -datasource YES|NO\n");
303   fprintf(stderr, "  -out        ls|xml\n");
304   fprintf(stderr, "  -statistics YES|NO\n");
305   fprintf(stderr, "  -preloops   <n>\n");
306   return 1;
307 }
308
309 - (int)runWithArguments:(NSArray *)_args {
310   NGImap4FileManager *fm;
311   NSUserDefaults *ud;
312   int            i;
313   
314   _args = [_args subarrayWithRange:NSMakeRange(1, [_args count] - 1)];
315   if ([_args count] == 0)
316     return [self usage];
317   
318   ud = [NSUserDefaults standardUserDefaults];
319   
320   self->useDataSource = [ud boolForKey:@"datasource"];
321   self->stats         = [ud boolForKey:@"statistics"];
322   self->preloops      = [ud integerForKey:@"preloops"];
323   
324   if ((fm = [self fileManager]) == nil) {
325     NSLog(@"could not open IMAP connection (got no filemanager)");
326     return 2;
327   }
328   
329 #if 1
330   NSLog(@"IMAP: %@", fm);
331 #endif
332   
333   for (i = 0; i < [_args count]; i++) {
334     [self processPath:[_args objectAtIndex:i] fileManager:fm];
335   }
336   
337   return 0;
338 }
339
340 @end /* ImapListTool */