]> err.no Git - sope/blob - xmlrpc_call/XmlRpcClientTool.m
fixed OGo bug #1899
[sope] / xmlrpc_call / XmlRpcClientTool.m
1 /*
2   Copyright (C) 2004-2005 Helge Hess
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 "XmlRpcClientTool.h"
23 #include "HandleCredentialsClient.h"
24 #include <NGStreams/NGLocalSocketAddress.h>
25 #include <NGExtensions/NSString+Ext.h>
26 #include "common.h"
27
28 #define EXIT_FAIL -1
29
30 @interface NSObject(Printing)
31 - (void)printWithTool:(XmlRpcClientTool *)_tool;
32 @end
33
34 @implementation XmlRpcClientTool
35
36 /* initialization */
37
38 - (id)init {
39   return [self initWithArguments:nil];
40 }
41
42 - (id)initWithArguments:(NSArray *)_arguments {
43   if ((self = [super init])) {
44     NSUserDefaults *ud;
45     NSString *s;
46     int argc;
47
48     argc = [_arguments count];
49     if(argc == 1) {
50       [self help:[_arguments objectAtIndex:0]];
51       return nil;
52     }
53     
54     s = [_arguments objectAtIndex:1];
55     if (![self initXmlRpcClientWithStringURL:s]) {
56       printf("Error initializing the XML-RPC client\n");
57       [self release];
58       return nil;
59     }
60     
61     if (argc > 2) {
62       [self initMethodCall:_arguments];
63     }
64     else {
65       self->methodName = @"system.listMethods";
66       self->parameters = nil;
67     }
68     
69     ud = [NSUserDefaults standardUserDefaults];
70     if ([ud boolForKey:@"forceauth"]) {
71       [self->client setUserName:[ud stringForKey:@"login"]];
72       [self->client setPassword:[ud stringForKey:@"password"]];
73     }
74     else {
75       [self->client setDefLogin:[ud stringForKey:@"login"]];
76       [self->client setDefPassword:[ud stringForKey:@"password"]];
77     }
78   }
79   return self;
80 }
81
82 - (BOOL)initXmlRpcClientWithStringURL:(NSString *)_url {
83   NSURL *url = nil;
84   
85   if (![_url isAbsoluteURL]) {
86     /* make a raw, Unix domain socket connection */
87     NGLocalSocketAddress *addr;
88     
89     addr = [NGLocalSocketAddress addressWithPath:_url];
90     self->client = [[HandleCredentialsClient alloc] initWithRawAddress:addr];
91     return YES;
92   }
93   
94   if ((url = [NSURL URLWithString:_url]) != nil) {
95 #if 0
96     if ((uri = [url path]) == nil)
97       uri = @"/RPC2";
98 #endif
99     
100     self->client = [(HandleCredentialsClient *)
101                      [HandleCredentialsClient alloc] initWithURL:url];
102     return YES;
103
104   }
105   else {
106     printf("Invalid URL\n");
107     return NO;
108   }
109 }
110
111 - (void)initMethodCall:(NSArray *)_arguments {
112   self->methodName = [_arguments objectAtIndex:2];
113
114   if ([_arguments count] > 2) {
115     NSRange range = NSMakeRange(3, [_arguments count] - 3);
116     self->parameters = [[_arguments subarrayWithRange:range] retain];
117   }
118 }
119
120 - (void)dealloc {
121   [self->client      release];
122   [self->methodName  release];
123   [self->parameters  release];
124   [super dealloc];
125 }
126
127 /* printing */
128
129 - (void)printElement:(id)element {
130   [element printWithTool:self];
131 }
132
133 /* printing objects */
134
135 - (void)printDictionary:(NSDictionary *)_dict {
136   NSEnumerator *dictEnum;
137   NSString     *dictKey;
138   
139   dictEnum = [_dict keyEnumerator];
140   while((dictKey = [dictEnum nextObject]) != nil) {
141     printf("%s=", [dictKey cString]);    
142     [self printElement:[_dict objectForKey:dictKey]];
143   }
144 }
145
146 - (void)printArray:(NSArray *)_array {
147   NSEnumerator *arrayEnum;
148   id arrayElem;
149   
150   arrayEnum = [_array objectEnumerator];
151   while((arrayElem = [arrayEnum nextObject]) != nil) {
152     [self printElement:arrayElem];
153   }
154 }
155
156 - (void)help:(NSString *)pn {
157   fprintf(stderr,
158           "usage:    %s <url> [<method-name>] [<arg1>,...]\n"
159           "  sample: %s http://localhost:20000/RPC2 bc 1 2\n",
160           [pn cString], [pn cString]);
161 }
162
163 /* running */
164
165 - (int)run {
166   int  exitCode  = 0;
167   int  loopCount = 0;
168   id   result;
169
170   if (self->client == nil) {
171     NSLog(@"missing XML-RPC client object ...");
172     return EXIT_FAIL;
173   }
174   
175   do {
176     result = [self->client
177                   invokeMethodNamed:self->methodName
178                   parameters:self->parameters];
179     loopCount++;
180   }
181   while ((result == nil) && loopCount < 20);
182
183   if (result == nil) {
184     NSLog(@"call failed, no result (looped %i times) ?!", loopCount);
185     return EXIT_FAIL;
186   }
187
188   if ([[NSUserDefaults standardUserDefaults] boolForKey:@"plist"]) {
189     NSString *s;
190     
191     s = [result description];
192     printf("%s\n", [s cString]);
193   }
194   else
195     [self printElement:result];
196   
197   if ([result isKindOfClass:[NSException class]]) {
198     exitCode = 255;
199   }
200
201   return exitCode;
202 }
203
204 @end /* XmlRpcClientTool */