Project

General

Profile

Download (20.7 KB) Statistics
| Branch: | Tag: | Revision:

aqbanking / src / libs / aqbanking / banking_online.c @ fe0aee9d

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

    
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

    
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

    
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

    
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

    
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

    
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

    
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

    
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

    
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

    
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

    
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

    
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

    
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

    
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

    
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

    
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

    
748
uint32_t AB_Banking_ReserveJobId(AB_BANKING *ab)
749
{
750
  return AB_Banking_GetNamedUniqueId(ab, "jobid", 1);
751
}
752

    
753