1 /***************************************************************************
2 begin : Mon Mar 01 2004
3 copyright : (C) 2019 by Martin Preuss
4 email : martin@libchipcard.de
5
6 ***************************************************************************
7 * This file is part of the project "AqBanking". *
8 * Please see toplevel file COPYING of that project for license details. *
9 ***************************************************************************/
10
11 /* This file is included by banking.c */
12
13
14 #ifdef AQBANKING_WITH_PLUGIN_BACKEND_AQNONE
15 # include "src/libs/plugins/backends/aqnone/provider_l.h"
16 #endif
17
18 #ifdef AQBANKING_WITH_PLUGIN_BACKEND_AQHBCI
19 # include "src/libs/plugins/backends/aqhbci/banking/provider.h"
20 #endif
21
22 #ifdef AQBANKING_WITH_PLUGIN_BACKEND_AQOFXCONNECT
23 # include "src/libs/plugins/backends/aqofxconnect/provider.h"
24 #endif
25
26 #ifdef AQBANKING_WITH_PLUGIN_BACKEND_AQPAYPAL
27 # include "src/libs/plugins/backends/aqpaypal/provider_l.h"
28 #endif
29
30 #ifdef AQBANKING_WITH_PLUGIN_BACKEND_AQEBICS
31 # include "src/libs/plugins/backends/aqebics/client/provider.h"
32 #endif
33
34 #ifdef AQBANKING_WITH_PLUGIN_BACKEND_AQFINTS
35 # include "src/libs/plugins/backends/aqfints/banking/provider.h"
36 #endif
37
38
39
40
41 /* ------------------------------------------------------------------------------------------------
42 * forward declarations
43 * ------------------------------------------------------------------------------------------------
44 */
45
46
47 static int _sendCommandsInsideProgress(AB_BANKING *ab, AB_TRANSACTION_LIST2 *commandList,
48 AB_IMEXPORTER_CONTEXT *ctx,
49 uint32_t pid);
50
51 static int _sortCommandsByAccounts(AB_BANKING *ab,
52 AB_TRANSACTION_LIST2 *commandList,
53 AB_ACCOUNTQUEUE_LIST *aql,
54 uint32_t pid);
55
56 static int _sortAccountQueuesByProvider(AB_BANKING *ab,
57 AB_ACCOUNTQUEUE_LIST *aql,
58 AB_PROVIDERQUEUE_LIST *pql,
59 uint32_t pid);
60
61 static int _sendProviderQueues(AB_BANKING *ab,
62 AB_PROVIDERQUEUE_LIST *pql,
63 AB_IMEXPORTER_CONTEXT *ctx,
64 uint32_t pid);
65
66
67
68 /* ------------------------------------------------------------------------------------------------
69 * implementations
70 * ------------------------------------------------------------------------------------------------
71 */
72
73
74
75
AB_Banking__CreateInternalProvider(AB_BANKING * ab,const char * modname)76 AB_PROVIDER *AB_Banking__CreateInternalProvider(AB_BANKING *ab, const char *modname)
77 {
78 if (modname && *modname) {
79 #ifdef AQBANKING_WITH_PLUGIN_BACKEND_AQHBCI
80 if (strcasecmp(modname, "aqhbci")==0) {
81 AB_PROVIDER *pro;
82
83 DBG_INFO(AQBANKING_LOGDOMAIN, "Plugin [%s] compiled-in", modname);
84 pro=AH_Provider_new(ab, modname);
85 return pro;
86 }
87 #endif
88
89 #ifdef AQBANKING_WITH_PLUGIN_BACKEND_AQNONE
90 if (strcasecmp(modname, "aqnone")==0) {
91 AB_PROVIDER *pro;
92
93 DBG_INFO(AQBANKING_LOGDOMAIN, "Plugin [%s] compiled-in", modname);
94 pro=AN_Provider_new(ab);
95 return pro;
96 }
97 #endif
98
99 #ifdef AQBANKING_WITH_PLUGIN_BACKEND_AQOFXCONNECT
100 if (strcasecmp(modname, "aqofxconnect")==0) {
101 AB_PROVIDER *pro;
102
103 DBG_INFO(AQBANKING_LOGDOMAIN, "Plugin [%s] compiled-in", modname);
104 pro=AO_Provider_new(ab);
105 return pro;
106 }
107 #endif
108
109 #ifdef AQBANKING_WITH_PLUGIN_BACKEND_AQPAYPAL
110 if (strcasecmp(modname, "aqpaypal")==0) {
111 AB_PROVIDER *pro;
112
113 DBG_INFO(AQBANKING_LOGDOMAIN, "Plugin [%s] compiled-in", modname);
114 pro=APY_Provider_new(ab);
115 return pro;
116 }
117 #endif
118
119 #ifdef AQBANKING_WITH_PLUGIN_BACKEND_AQEBICS
120 if (strcasecmp(modname, "aqebics")==0) {
121 AB_PROVIDER *pro;
122
123 DBG_INFO(AQBANKING_LOGDOMAIN, "Plugin [%s] compiled-in", modname);
124 pro=EBC_Provider_new(ab);
125 return pro;
126 }
127 #endif
128
129 #ifdef AQBANKING_WITH_PLUGIN_BACKEND_AQFINTS
130 if (strcasecmp(modname, "aqfints")==0) {
131 AB_PROVIDER *pro;
132
133 DBG_INFO(AQBANKING_LOGDOMAIN, "Plugin [%s] compiled-in", modname);
134 pro=AF_Provider_new(ab);
135 return pro;
136 }
137 #endif
138
139 }
140 else {
141 DBG_ERROR(AQBANKING_LOGDOMAIN, "Plugin [%s] not compiled-in", modname);
142 }
143 return NULL;
144 }
145
146
147
AB_Banking__FindProvider(AB_BANKING * ab,const char * name)148 AB_PROVIDER *AB_Banking__FindProvider(AB_BANKING *ab, const char *name)
149 {
150 AB_PROVIDER *pro;
151
152 assert(ab);
153 assert(name);
154 pro=AB_Provider_List_First(ab_providers);
155 while (pro) {
156 if (strcasecmp(AB_Provider_GetName(pro), name)==0)
157 break;
158 pro=AB_Provider_List_Next(pro);
159 } /* while */
160
161 return pro;
162 }
163
164
165
AB_Banking__GetProvider(AB_BANKING * ab,const char * name)166 AB_PROVIDER *AB_Banking__GetProvider(AB_BANKING *ab, const char *name)
167 {
168 AB_PROVIDER *pro;
169
170 assert(ab);
171 assert(name);
172
173 pro=AB_Banking__FindProvider(ab, name);
174 if (pro)
175 return pro;
176 pro=AB_Banking__CreateInternalProvider(ab, name);
177 if (pro)
178 return pro;
179
180 if (pro)
181 AB_Provider_List_Add(pro, ab_providers);
182
183 return pro;
184 }
185
186
187
AB_Banking_BeginUseProvider(AB_BANKING * ab,const char * modname)188 AB_PROVIDER *AB_Banking_BeginUseProvider(AB_BANKING *ab, const char *modname)
189 {
190 AB_PROVIDER *pro;
191
192 pro=AB_Banking__GetProvider(ab, modname);
193 if (pro) {
194 GWEN_DB_NODE *db=NULL;
195 int rv;
196
197 rv=AB_Banking_ReadNamedConfigGroup(ab, AB_CFG_GROUP_BACKENDS, modname, 1, 1, &db);
198 if (rv<0) {
199 DBG_INFO(AQBANKING_LOGDOMAIN, "here (%d)", rv);
200 AB_Provider_free(pro);
201 return NULL;
202 }
203
204 rv=AB_Provider_Init(pro, db);
205 if (rv<0) {
206 DBG_ERROR(AQBANKING_LOGDOMAIN, "here (%d)", rv);
207 GWEN_DB_Group_free(db);
208 AB_Provider_free(pro);
209 return NULL;
210 }
211 GWEN_DB_Group_free(db);
212
213 return pro;
214 }
215 else {
216 DBG_INFO(AQBANKING_LOGDOMAIN, "Plugin [%s] not found", modname);
217 return NULL;
218 }
219 }
220
221
222
AB_Banking_EndUseProvider(AB_BANKING * ab,AB_PROVIDER * pro)223 int AB_Banking_EndUseProvider(AB_BANKING *ab, AB_PROVIDER *pro)
224 {
225 int rv;
226 GWEN_DB_NODE *db=NULL;
227
228 assert(pro);
229
230 rv=AB_Banking_ReadNamedConfigGroup(ab, AB_CFG_GROUP_BACKENDS, AB_Provider_GetName(pro), 1, 0, &db);
231 if (rv<0) {
232 DBG_INFO(AQBANKING_LOGDOMAIN, "here (%d)", rv);
233 AB_Provider_free(pro);
234 return rv;
235 }
236
237 rv=AB_Provider_Fini(pro, db);
238 if (rv<0) {
239 DBG_ERROR(AQBANKING_LOGDOMAIN, "here (%d)", rv);
240 GWEN_ConfigMgr_UnlockGroup(ab->configMgr, AB_CFG_GROUP_BACKENDS, AB_Provider_GetName(pro));
241 GWEN_DB_Group_free(db);
242 AB_Provider_free(pro);
243 return rv;
244 }
245
246 rv=AB_Banking_WriteNamedConfigGroup(ab, AB_CFG_GROUP_BACKENDS, AB_Provider_GetName(pro), 0, 1, db);
247 if (rv<0) {
248 DBG_INFO(AQBANKING_LOGDOMAIN, "here (%d)", rv);
249 GWEN_ConfigMgr_UnlockGroup(ab->configMgr, AB_CFG_GROUP_BACKENDS, AB_Provider_GetName(pro));
250 GWEN_DB_Group_free(db);
251 AB_Provider_free(pro);
252 return rv;
253 }
254 GWEN_DB_Group_free(db);
255 AB_Provider_free(pro);
256
257 return 0;
258 }
259
260
261
AB_Banking_ProviderControl(AB_BANKING * ab,const char * backendName,int argc,char ** argv)262 int AB_Banking_ProviderControl(AB_BANKING *ab, const char *backendName, int argc, char **argv)
263 {
264 AB_PROVIDER *pro;
265
266 pro=AB_Banking_BeginUseProvider(ab, backendName);
267 if (pro==NULL) {
268 DBG_INFO(AQBANKING_LOGDOMAIN, "Provider \"%s\" not available", backendName?backendName:"<no name>");
269 return GWEN_ERROR_NOT_FOUND;
270 }
271 else {
272 int rv;
273
274 rv=AB_Provider_Control(pro, argc, argv);
275 if (rv<0) {
276 DBG_INFO(AQBANKING_LOGDOMAIN, "here (%d)", rv);
277 }
278 else if (rv>0) {
279 DBG_INFO(AQBANKING_LOGDOMAIN, "Error in provider control function (%d)", rv);
280 }
281 AB_Banking_EndUseProvider(ab, pro);
282 return rv;
283 }
284 }
285
286
287
AB_Banking_GetProviderDescrs(AB_BANKING * ab)288 GWEN_PLUGIN_DESCRIPTION_LIST2 *AB_Banking_GetProviderDescrs(AB_BANKING *ab)
289 {
290 GWEN_PLUGIN_DESCRIPTION_LIST2 *l;
291 GWEN_PLUGIN_MANAGER *pm;
292
293 pm = GWEN_PluginManager_FindPluginManager("provider");
294 if (!pm) {
295 DBG_ERROR(AQBANKING_LOGDOMAIN,
296 "Could not find plugin manager for \"%s\"",
297 "provider");
298 return 0;
299 }
300
301 l = GWEN_PluginManager_GetPluginDescrs(pm);
302 if (l) {
303 GWEN_PLUGIN_DESCRIPTION_LIST2_ITERATOR *it;
304 GWEN_PLUGIN_DESCRIPTION *pd;
305
306 it=GWEN_PluginDescription_List2_First(l);
307 assert(it);
308 pd=GWEN_PluginDescription_List2Iterator_Data(it);
309 assert(pd);
310 while (pd) {
311 GWEN_PluginDescription_SetIsActive(pd, 1);
312 pd=GWEN_PluginDescription_List2Iterator_Next(it);
313 }
314 GWEN_PluginDescription_List2Iterator_free(it);
315 }
316
317 return l;
318 }
319
320
321
AB_Banking_GetCryptToken(AB_BANKING * ab,const char * tname,const char * cname,GWEN_CRYPT_TOKEN ** pCt)322 int AB_Banking_GetCryptToken(AB_BANKING *ab,
323 const char *tname,
324 const char *cname,
325 GWEN_CRYPT_TOKEN **pCt)
326 {
327 GWEN_CRYPT_TOKEN *ct=NULL;
328 GWEN_CRYPT_TOKEN_LIST2_ITERATOR *it;
329
330 assert(ab);
331
332 assert(pCt);
333
334 if (!tname || !cname) {
335 DBG_ERROR(AQBANKING_LOGDOMAIN,
336 "Error in your configuration: TokenType \"%s\" or TokenName \"%s\" is NULL. Maybe you need to remove your configuration and create it again? Aborting.",
337 tname ? tname : "NULL",
338 cname ? cname : "NULL");
339 return GWEN_ERROR_IO;
340 }
341
342 it=GWEN_Crypt_Token_List2_First(ab->cryptTokenList);
343 if (it) {
344 ct=GWEN_Crypt_Token_List2Iterator_Data(it);
345 assert(ct);
346 while (ct) {
347 const char *s1;
348 const char *s2;
349
350 s1=GWEN_Crypt_Token_GetTypeName(ct);
351 s2=GWEN_Crypt_Token_GetTokenName(ct);
352 assert(s1);
353 assert(s2);
354 if (strcasecmp(s1, tname)==0 &&
355 strcasecmp(s2, cname)==0)
356 break;
357 ct=GWEN_Crypt_Token_List2Iterator_Next(it);
358 }
359 GWEN_Crypt_Token_List2Iterator_free(it);
360 }
361
362 if (ct==NULL) {
363 GWEN_PLUGIN_MANAGER *pm;
364 GWEN_PLUGIN *pl;
365
366 /* get crypt token */
367 pm=GWEN_PluginManager_FindPluginManager(GWEN_CRYPT_TOKEN_PLUGIN_TYPENAME);
368 if (pm==0) {
369 DBG_ERROR(AQBANKING_LOGDOMAIN, "CryptToken plugin manager not found");
370 return GWEN_ERROR_INTERNAL;
371 }
372
373 pl=GWEN_PluginManager_GetPlugin(pm, tname);
374 if (pl==0) {
375 DBG_ERROR(AQBANKING_LOGDOMAIN, "Plugin \"%s\" not found", tname);
376 return GWEN_ERROR_NOT_FOUND;
377 }
378
379 ct=GWEN_Crypt_Token_Plugin_CreateToken(pl, cname);
380 if (ct==0) {
381 DBG_ERROR(AQBANKING_LOGDOMAIN, "Could not create crypt token");
382 return GWEN_ERROR_IO;
383 }
384
385 if (GWEN_Gui_GetFlags(GWEN_Gui_GetGui()) & GWEN_GUI_FLAGS_NONINTERACTIVE)
386 /* in non-interactive mode, so don't use the secure pin input of card readers because
387 * that wouldn't give us a chance to inject the pin via a pinfile
388 */
389 GWEN_Crypt_Token_AddModes(ct, GWEN_CRYPT_TOKEN_MODE_FORCE_PIN_ENTRY);
390
391 /* add to internal list */
392 GWEN_Crypt_Token_List2_PushBack(ab->cryptTokenList, ct);
393 }
394
395 *pCt=ct;
396 return 0;
397 }
398
399
400
AB_Banking_ClearCryptTokenList(AB_BANKING * ab)401 void AB_Banking_ClearCryptTokenList(AB_BANKING *ab)
402 {
403 GWEN_CRYPT_TOKEN_LIST2_ITERATOR *it;
404
405 assert(ab);
406 assert(ab->cryptTokenList);
407
408 it=GWEN_Crypt_Token_List2_First(ab->cryptTokenList);
409 if (it) {
410 GWEN_CRYPT_TOKEN *ct;
411
412 ct=GWEN_Crypt_Token_List2Iterator_Data(it);
413 assert(ct);
414 while (ct) {
415 while (GWEN_Crypt_Token_IsOpen(ct)) {
416 int rv;
417
418 rv=GWEN_Crypt_Token_Close(ct, 0, 0);
419 if (rv) {
420 DBG_WARN(AQBANKING_LOGDOMAIN,
421 "Could not close crypt token [%s:%s], abandoning (%d)",
422 GWEN_Crypt_Token_GetTypeName(ct),
423 GWEN_Crypt_Token_GetTokenName(ct),
424 rv);
425 GWEN_Crypt_Token_Close(ct, 1, 0);
426 }
427 }
428 GWEN_Crypt_Token_free(ct);
429 ct=GWEN_Crypt_Token_List2Iterator_Next(it);
430 }
431 GWEN_Crypt_Token_List2Iterator_free(it);
432 }
433 GWEN_Crypt_Token_List2_Clear(ab->cryptTokenList);
434 }
435
436
437
AB_Banking_CheckCryptToken(AB_BANKING * ab,GWEN_CRYPT_TOKEN_DEVICE devt,GWEN_BUFFER * typeName,GWEN_BUFFER * tokenName)438 int AB_Banking_CheckCryptToken(AB_BANKING *ab,
439 GWEN_CRYPT_TOKEN_DEVICE devt,
440 GWEN_BUFFER *typeName,
441 GWEN_BUFFER *tokenName)
442 {
443 GWEN_PLUGIN_MANAGER *pm;
444 int rv;
445
446 /* get crypt token */
447 pm=GWEN_PluginManager_FindPluginManager(GWEN_CRYPT_TOKEN_PLUGIN_TYPENAME);
448 if (pm==0) {
449 DBG_ERROR(AQBANKING_LOGDOMAIN, "CryptToken plugin manager not found");
450 return GWEN_ERROR_NOT_FOUND;
451 }
452
453 /* try to determine the type and name */
454 rv=GWEN_Crypt_Token_PluginManager_CheckToken(pm,
455 devt,
456 typeName,
457 tokenName,
458 0);
459 if (rv) {
460 DBG_ERROR(AQBANKING_LOGDOMAIN, "here (%d)", rv);
461 return rv;
462 }
463
464 return 0;
465 }
466
467
468
AB_Banking_GetCert(AB_BANKING * ab,const char * url,const char * defaultProto,int defaultPort,uint32_t * httpFlags,uint32_t pid)469 int AB_Banking_GetCert(AB_BANKING *ab,
470 const char *url,
471 const char *defaultProto,
472 int defaultPort,
473 uint32_t *httpFlags,
474 uint32_t pid)
475 {
476 int rv;
477 GWEN_HTTP_SESSION *sess;
478
479 sess=GWEN_HttpSession_new(url, defaultProto, defaultPort);
480 GWEN_HttpSession_SetFlags(sess, *httpFlags);
481
482 rv=GWEN_HttpSession_Init(sess);
483 if (rv<0) {
484 DBG_INFO(AQBANKING_LOGDOMAIN, "here (%d)", rv);
485 GWEN_Gui_ProgressLog2(pid,
486 GWEN_LoggerLevel_Error,
487 I18N("Could not init HTTP session (%d)"), rv);
488 GWEN_HttpSession_free(sess);
489 return rv;
490 }
491
492 rv=GWEN_HttpSession_ConnectionTest(sess);
493 if (rv<0) {
494 DBG_ERROR(AQBANKING_LOGDOMAIN, "Could not connect to server (%d)", rv);
495 GWEN_Gui_ProgressLog2(pid,
496 GWEN_LoggerLevel_Error,
497 I18N("Could not connect to server, giving up (%d)"), rv);
498 return rv;
499 }
500
501 *httpFlags=GWEN_HttpSession_GetFlags(sess);
502
503 GWEN_HttpSession_Fini(sess);
504 GWEN_HttpSession_free(sess);
505
506 GWEN_Gui_ProgressLog(pid,
507 GWEN_LoggerLevel_Notice,
508 I18N("Connection ok, certificate probably received"));
509
510 return 0;
511 }
512
513
514
515
AB_Banking_SendCommands(AB_BANKING * ab,AB_TRANSACTION_LIST2 * commandList,AB_IMEXPORTER_CONTEXT * ctx)516 int AB_Banking_SendCommands(AB_BANKING *ab, AB_TRANSACTION_LIST2 *commandList, AB_IMEXPORTER_CONTEXT *ctx)
517 {
518 uint32_t pid;
519 int rv;
520
521 pid=GWEN_Gui_ProgressStart(GWEN_GUI_PROGRESS_ALLOW_SUBLEVELS |
522 GWEN_GUI_PROGRESS_SHOW_PROGRESS |
523 GWEN_GUI_PROGRESS_SHOW_LOG |
524 GWEN_GUI_PROGRESS_ALWAYS_SHOW_LOG |
525 GWEN_GUI_PROGRESS_KEEP_OPEN |
526 GWEN_GUI_PROGRESS_SHOW_ABORT,
527 I18N("Executing Jobs"),
528 I18N("Now the jobs are send via their "
529 "backends to the credit institutes."),
530 0, /* no progress count */
531 0);
532 GWEN_Gui_ProgressLog(pid, GWEN_LoggerLevel_Notice, "AqBanking v"AQBANKING_VERSION_FULL_STRING);
533 GWEN_Gui_ProgressLog(pid, GWEN_LoggerLevel_Notice, I18N("Sending jobs to the bank(s)"));
534
535 rv=_sendCommandsInsideProgress(ab, commandList, ctx, pid);
536 AB_Banking_ClearCryptTokenList(ab);
537 if (rv) {
538 DBG_INFO(AQBANKING_LOGDOMAIN, "here (%d)", rv);
539 }
540
541 GWEN_Gui_ProgressEnd(pid);
542 return rv;
543 }
544
545
546
_sendCommandsInsideProgress(AB_BANKING * ab,AB_TRANSACTION_LIST2 * commandList,AB_IMEXPORTER_CONTEXT * ctx,uint32_t pid)547 int _sendCommandsInsideProgress(AB_BANKING *ab, AB_TRANSACTION_LIST2 *commandList, AB_IMEXPORTER_CONTEXT *ctx,
548 uint32_t pid)
549 {
550 AB_ACCOUNTQUEUE_LIST *aql;
551 AB_PROVIDERQUEUE_LIST *pql;
552 int rv;
553
554 /* sort commands by account */
555 GWEN_Gui_ProgressLog(pid, GWEN_LoggerLevel_Info, I18N("Sorting commands by account"));
556 aql=AB_AccountQueue_List_new();
557 rv=_sortCommandsByAccounts(ab, commandList, aql, pid);
558 if (rv<0) {
559 DBG_INFO(AQBANKING_LOGDOMAIN, "here (%d)", rv);
560 AB_AccountQueue_List_free(aql);
561 return rv;
562 }
563
564 /* sort account queues by provider */
565 GWEN_Gui_ProgressLog(pid, GWEN_LoggerLevel_Info, I18N("Sorting account queues by provider"));
566 pql=AB_ProviderQueue_List_new();
567 rv=_sortAccountQueuesByProvider(ab, aql, pql, pid);
568 if (rv<0) {
569 DBG_INFO(AQBANKING_LOGDOMAIN, "here (%d)", rv);
570 AB_ProviderQueue_List_free(pql);
571 AB_AccountQueue_List_free(aql);
572 return rv;
573 }
574 AB_AccountQueue_List_free(aql); /* no longer needed */
575
576 /* send to each backend */
577 GWEN_Gui_ProgressLog(pid, GWEN_LoggerLevel_Info, I18N("Send commands to providers"));
578 rv=_sendProviderQueues(ab, pql, ctx, pid);
579 if (rv<0) {
580 DBG_INFO(AQBANKING_LOGDOMAIN, "here (%d)", rv);
581 return rv;
582 }
583 AB_ProviderQueue_List_free(pql);
584
585 /* done */
586 return 0;
587 }
588
589
590
_sortCommandsByAccounts(AB_BANKING * ab,AB_TRANSACTION_LIST2 * commandList,AB_ACCOUNTQUEUE_LIST * aql,uint32_t pid)591 int _sortCommandsByAccounts(AB_BANKING *ab,
592 AB_TRANSACTION_LIST2 *commandList,
593 AB_ACCOUNTQUEUE_LIST *aql,
594 uint32_t pid)
595 {
596 AB_TRANSACTION_LIST2_ITERATOR *jit;
597 AB_ACCOUNTQUEUE *aq;
598
599 /* sort commands by account */
600 jit=AB_Transaction_List2_First(commandList);
601 if (jit) {
602 AB_TRANSACTION *t;
603
604 t=AB_Transaction_List2Iterator_Data(jit);
605 while (t) {
606 AB_TRANSACTION_STATUS tStatus;
607
608 tStatus=AB_Transaction_GetStatus(t);
609 if (tStatus==AB_Transaction_StatusUnknown || tStatus==AB_Transaction_StatusNone ||
610 tStatus==AB_Transaction_StatusEnqueued) {
611 uint32_t uid;
612
613 uid=AB_Transaction_GetUniqueAccountId(t);
614 if (uid==0) {
615 DBG_ERROR(AQBANKING_LOGDOMAIN, "No unique account id given in transaction, aborting");
616 return GWEN_ERROR_BAD_DATA;
617 }
618
619 /* get or create account queue */
620 aq=AB_AccountQueue_List_GetByAccountId(aql, uid);
621 if (aq==NULL) {
622 aq=AB_AccountQueue_new();
623 AB_AccountQueue_SetAccountId(aq, uid);
624 AB_AccountQueue_List_Add(aq, aql);
625 }
626
627 /* assign unique id to job (if none) */
628 if (AB_Transaction_GetUniqueId(t)==0)
629 AB_Transaction_SetUniqueId(t, AB_Banking_GetNamedUniqueId(ab, "jobid", 1));
630 AB_Transaction_SetRefUniqueId(t, 0);
631 /* set status */
632 AB_Transaction_SetStatus(t, AB_Transaction_StatusEnqueued);
633 /* add to queue */
634 AB_AccountQueue_AddTransaction(aq, t);
635 } /* if status matches */
636 else {
637 DBG_ERROR(AQBANKING_LOGDOMAIN, "Transaction with bad status, not enqueuing (%d: %s)",
638 tStatus, AB_Transaction_Status_toString(tStatus));
639 /* TODO: change status, add to im-/export context */
640 }
641
642 t=AB_Transaction_List2Iterator_Next(jit);
643 }
644 AB_Transaction_List2Iterator_free(jit);
645 } /* if (jit) */
646
647 return 0;
648 }
649
650
651
_sortAccountQueuesByProvider(AB_BANKING * ab,AB_ACCOUNTQUEUE_LIST * aql,AB_PROVIDERQUEUE_LIST * pql,uint32_t pid)652 int _sortAccountQueuesByProvider(AB_BANKING *ab,
653 AB_ACCOUNTQUEUE_LIST *aql,
654 AB_PROVIDERQUEUE_LIST *pql,
655 uint32_t pid)
656 {
657 AB_ACCOUNTQUEUE *aq;
658 AB_PROVIDERQUEUE *pq;
659 int rv;
660
661 /* sort account queues by provider */
662 while ((aq=AB_AccountQueue_List_First(aql))) {
663 uint32_t uid;
664 AB_ACCOUNT_SPEC *as=NULL;
665 const char *s;
666
667 uid=AB_AccountQueue_GetAccountId(aq);
668 rv=AB_Banking_GetAccountSpecByUniqueId(ab, uid, &as);
669 if (rv<0) {
670 DBG_ERROR(AQBANKING_LOGDOMAIN, "Unable to load account spec for account %lu (%d)", (unsigned long int)uid, rv);
671 return GWEN_ERROR_BAD_DATA;
672 }
673 AB_AccountQueue_SetAccountSpec(aq, as);
674
675 s=AB_AccountSpec_GetBackendName(as);
676 if (!(s && *s)) {
677 DBG_ERROR(AQBANKING_LOGDOMAIN, "Account spec for account %lu has no backend setting", (unsigned long int)uid);
678 return GWEN_ERROR_BAD_DATA;
679 }
680
681 pq=AB_ProviderQueue_List_GetByProviderName(pql, s);
682 if (pq==NULL) {
683 pq=AB_ProviderQueue_new();
684 AB_ProviderQueue_SetProviderName(pq, s);
685
686 AB_ProviderQueue_List_Add(pq, pql);
687 }
688
689 AB_AccountQueue_List_Del(aq);
690 AB_ProviderQueue_AddAccountQueue(pq, aq);
691 }
692
693 return 0;
694 }
695
696
697
_sendProviderQueues(AB_BANKING * ab,AB_PROVIDERQUEUE_LIST * pql,AB_IMEXPORTER_CONTEXT * ctx,uint32_t pid)698 int _sendProviderQueues(AB_BANKING *ab,
699 AB_PROVIDERQUEUE_LIST *pql,
700 AB_IMEXPORTER_CONTEXT *ctx,
701 uint32_t pid)
702 {
703 AB_PROVIDERQUEUE *pq;
704 int rv;
705
706 pq=AB_ProviderQueue_List_First(pql);
707 while (pq) {
708 AB_PROVIDERQUEUE *pqNext;
709 const char *providerName;
710
711 pqNext=AB_ProviderQueue_List_Next(pq);
712 AB_ProviderQueue_List_Del(pq);
713
714 providerName=AB_ProviderQueue_GetProviderName(pq);
715 if (providerName && *providerName) {
716 AB_PROVIDER *pro;
717
718 pro=AB_Banking_BeginUseProvider(ab, providerName);
719 if (pro) {
720 AB_IMEXPORTER_CONTEXT *localCtx;
721
722 GWEN_Gui_ProgressLog2(pid, GWEN_LoggerLevel_Info, I18N("Send commands to provider \"%s\""), providerName);
723 localCtx=AB_ImExporterContext_new();
724 rv=AB_Provider_SendCommands(pro, pq, localCtx);
725 if (rv<0) {
726 GWEN_Gui_ProgressLog2(pid, GWEN_LoggerLevel_Error, I18N("Error sending commands to provider \"%s\":%d"), providerName,
727 rv);
728 DBG_INFO(AQBANKING_LOGDOMAIN, "Error sending commands to provider \"%s\" (%d)", AB_Provider_GetName(pro), rv);
729 }
730 AB_ImExporterContext_AddContext(ctx, localCtx);
731 AB_Banking_EndUseProvider(ab, pro);
732 }
733 else {
734 GWEN_Gui_ProgressLog2(pid, GWEN_LoggerLevel_Info, I18N("Provider \"%s\" is not available."), providerName);
735 DBG_ERROR(AQBANKING_LOGDOMAIN, "Could not start using provider \"%s\"", providerName);
736 }
737 }
738 AB_ProviderQueue_free(pq);
739
740 pq=pqNext;
741 }
742 return 0;
743 }
744
745
746
747
AB_Banking_ReserveJobId(AB_BANKING * ab)748 uint32_t AB_Banking_ReserveJobId(AB_BANKING *ab)
749 {
750 return AB_Banking_GetNamedUniqueId(ab, "jobid", 1);
751 }
752
753
754