gwenhywfar 4.0.3
|
00001 /*************************************************************************** 00002 begin : Fri Feb 07 2003 00003 copyright : (C) 2003-2010 by Martin Preuss 00004 email : martin@libchipcard.de 00005 00006 *************************************************************************** 00007 * * 00008 * This library is free software; you can redistribute it and/or * 00009 * modify it under the terms of the GNU Lesser General Public * 00010 * License as published by the Free Software Foundation; either * 00011 * version 2.1 of the License, or (at your option) any later version. * 00012 * * 00013 * This library is distributed in the hope that it will be useful, * 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 00016 * Lesser General Public License for more details. * 00017 * * 00018 * You should have received a copy of the GNU Lesser General Public * 00019 * License along with this library; if not, write to the Free Software * 00020 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * 00021 * MA 02111-1307 USA * 00022 * * 00023 ***************************************************************************/ 00024 00025 00026 #ifdef HAVE_CONFIG_H 00027 # include <config.h> 00028 #endif 00029 00030 #define DISABLE_DEBUGLOG 00031 00032 00033 #ifndef ICONV_CONST 00034 # define ICONV_CONST 00035 #endif 00036 00037 00038 #include "gui_p.h" 00039 #include "dlg_input_l.h" 00040 #include "dlg_message_l.h" 00041 #include "dlg_progress_l.h" 00042 #include "dlg_showbox_l.h" 00043 #include "i18n_l.h" 00044 00045 #include <gwenhywfar/debug.h> 00046 #include <gwenhywfar/dialog_be.h> 00047 #include <gwenhywfar/url.h> 00048 #include <gwenhywfar/syncio_socket.h> 00049 #include <gwenhywfar/syncio_buffered.h> 00050 #include <gwenhywfar/syncio_tls.h> 00051 #include <gwenhywfar/syncio_http.h> 00052 00053 #include <stdarg.h> 00054 #include <string.h> 00055 #include <errno.h> 00056 #include <ctype.h> 00057 00058 #ifdef HAVE_ICONV_H 00059 # include <iconv.h> 00060 #endif 00061 00062 00063 00064 static GWEN_GUI *gwenhywfar_gui=NULL; 00065 00066 00067 GWEN_INHERIT_FUNCTIONS(GWEN_GUI) 00068 00069 00070 00071 GWEN_GUI *GWEN_Gui_new() { 00072 GWEN_GUI *gui; 00073 00074 GWEN_NEW_OBJECT(GWEN_GUI, gui); 00075 GWEN_INHERIT_INIT(GWEN_GUI, gui); 00076 gui->refCount=1; 00077 00078 gui->checkCertFn=GWEN_Gui_CheckCertBuiltIn; 00079 gui->getSyncIoFn=GWEN_Gui_Internal_GetSyncIo; 00080 00081 gui->progressDataTree=GWEN_ProgressData_Tree_new(); 00082 gui->activeDialogs=GWEN_Dialog_List_new(); 00083 00084 return gui; 00085 } 00086 00087 00088 00089 void GWEN_Gui_free(GWEN_GUI *gui) { 00090 if (gui) { 00091 assert(gui->refCount); 00092 if ((--gui->refCount)==0) { 00093 GWEN_INHERIT_FINI(GWEN_GUI, gui); 00094 00095 GWEN_Dialog_List_free(gui->activeDialogs); 00096 GWEN_ProgressData_Tree_free(gui->progressDataTree); 00097 free(gui->name); 00098 free(gui->charSet); 00099 00100 GWEN_FREE_OBJECT(gui); 00101 } 00102 } 00103 } 00104 00105 00106 00107 void GWEN_Gui_UseDialogs(GWEN_GUI *gui) { 00108 assert(gui); 00109 DBG_INFO(GWEN_LOGDOMAIN, "Using own callbacks in gui %p", gui); 00110 gui->progressStartFn=GWEN_Gui_Internal_ProgressStart; 00111 gui->progressAdvanceFn=GWEN_Gui_Internal_ProgressAdvance; 00112 gui->progressLogFn=GWEN_Gui_Internal_ProgressLog; 00113 gui->progressEndFn=GWEN_Gui_Internal_ProgressEnd; 00114 gui->inputBoxFn=GWEN_Gui_Internal_InputBox; 00115 gui->messageBoxFn=GWEN_Gui_Internal_MessageBox; 00116 gui->showBoxFn=GWEN_Gui_Internal_ShowBox; 00117 gui->hideBoxFn=GWEN_Gui_Internal_HideBox; 00118 } 00119 00120 00121 00122 void GWEN_Gui_Attach(GWEN_GUI *gui) { 00123 assert(gui); 00124 assert(gui->refCount); 00125 gui->refCount++; 00126 } 00127 00128 00129 00130 void GWEN_Gui_SetGui(GWEN_GUI *gui) { 00131 if (gui) 00132 GWEN_Gui_Attach(gui); 00133 if (gwenhywfar_gui) 00134 GWEN_Gui_free(gwenhywfar_gui); 00135 gwenhywfar_gui=gui; 00136 } 00137 00138 00139 00140 GWEN_GUI *GWEN_Gui_GetGui() { 00141 return gwenhywfar_gui; 00142 } 00143 00144 00145 00146 int GWEN_Gui_ConvertFromUtf8(const GWEN_GUI *gui, const char *text, int len, GWEN_BUFFER *tbuf) { 00147 assert(gui); 00148 assert(len); 00149 00150 if (gui->charSet) { 00151 if (strcasecmp(gui->charSet, "utf-8")!=0) { 00152 #ifndef HAVE_ICONV 00153 DBG_INFO(GWEN_LOGDOMAIN, 00154 "iconv not available, can not convert to \"%s\"", 00155 gui->charSet); 00156 #else 00157 iconv_t ic; 00158 00159 ic=iconv_open(gui->charSet, "UTF-8"); 00160 if (ic==((iconv_t)-1)) { 00161 DBG_ERROR(GWEN_LOGDOMAIN, "Charset \"%s\" not available", 00162 gui->charSet); 00163 } 00164 else { 00165 char *outbuf; 00166 char *pOutbuf; 00167 /* Some systems have iconv in libc, some have it in libiconv 00168 (OSF/1 and those with the standalone portable GNU libiconv 00169 installed). Check which one is available. The define 00170 ICONV_CONST will be "" or "const" accordingly. */ 00171 ICONV_CONST char *pInbuf; 00172 size_t inLeft; 00173 size_t outLeft; 00174 size_t done; 00175 size_t space; 00176 00177 /* convert */ 00178 pInbuf=(char*)text; 00179 00180 outLeft=len*2; 00181 space=outLeft; 00182 outbuf=(char*)malloc(outLeft); 00183 assert(outbuf); 00184 00185 inLeft=len; 00186 pInbuf=(char*)text; 00187 pOutbuf=outbuf; 00188 done=iconv(ic, &pInbuf, &inLeft, &pOutbuf, &outLeft); 00189 if (done==(size_t)-1) { 00190 DBG_ERROR(GWEN_LOGDOMAIN, "Error in conversion: %s (%d)", 00191 strerror(errno), errno); 00192 free(outbuf); 00193 iconv_close(ic); 00194 return GWEN_ERROR_GENERIC; 00195 } 00196 00197 GWEN_Buffer_AppendBytes(tbuf, outbuf, space-outLeft); 00198 free(outbuf); 00199 DBG_DEBUG(GWEN_LOGDOMAIN, "Conversion done."); 00200 iconv_close(ic); 00201 return 0; 00202 } 00203 #endif 00204 } 00205 } 00206 00207 GWEN_Buffer_AppendBytes(tbuf, text, len); 00208 return 0; 00209 } 00210 00211 00212 00213 void GWEN_Gui_GetRawText(const GWEN_GUI *gui, const char *text, GWEN_BUFFER *tbuf) { 00214 const char *p; 00215 int rv; 00216 00217 assert(text); 00218 p=text; 00219 while ((p=strchr(p, '<'))) { 00220 const char *t; 00221 00222 t=p; 00223 t++; 00224 if (toupper(*t)=='H') { 00225 t++; 00226 if (toupper(*t)=='T') { 00227 t++; 00228 if (toupper(*t)=='M') { 00229 t++; 00230 if (toupper(*t)=='L') { 00231 break; 00232 } 00233 } 00234 } 00235 } 00236 p++; 00237 } /* while */ 00238 00239 if (p) 00240 rv=GWEN_Gui_ConvertFromUtf8(gui, text, (p-text), tbuf); 00241 else 00242 rv=GWEN_Gui_ConvertFromUtf8(gui, text, strlen(text), tbuf); 00243 if (rv) { 00244 DBG_ERROR(GWEN_LOGDOMAIN, "Error converting text"); 00245 GWEN_Buffer_Reset(tbuf); 00246 if (p) 00247 GWEN_Buffer_AppendBytes(tbuf, text, (p-text)); 00248 else 00249 GWEN_Buffer_AppendString(tbuf, text); 00250 } 00251 } 00252 00253 00254 00255 GWEN_GUI_MESSAGEBOX_FN GWEN_Gui_SetMessageBoxFn(GWEN_GUI *gui, 00256 GWEN_GUI_MESSAGEBOX_FN f){ 00257 GWEN_GUI_MESSAGEBOX_FN of; 00258 00259 assert(gui); 00260 of=gui->messageBoxFn; 00261 gui->messageBoxFn=f; 00262 return of; 00263 } 00264 00265 00266 00267 GWEN_GUI_INPUTBOX_FN GWEN_Gui_SetInputBoxFn(GWEN_GUI *gui, 00268 GWEN_GUI_INPUTBOX_FN f){ 00269 GWEN_GUI_INPUTBOX_FN of; 00270 00271 assert(gui); 00272 of=gui->inputBoxFn; 00273 gui->inputBoxFn=f; 00274 return of; 00275 } 00276 00277 00278 00279 GWEN_GUI_SHOWBOX_FN GWEN_Gui_SetShowBoxFn(GWEN_GUI *gui, 00280 GWEN_GUI_SHOWBOX_FN f){ 00281 GWEN_GUI_SHOWBOX_FN of; 00282 00283 assert(gui); 00284 of=gui->showBoxFn; 00285 gui->showBoxFn=f; 00286 return of; 00287 } 00288 00289 00290 00291 GWEN_GUI_HIDEBOX_FN GWEN_Gui_SetHideBoxFn(GWEN_GUI *gui, 00292 GWEN_GUI_HIDEBOX_FN f){ 00293 GWEN_GUI_HIDEBOX_FN of; 00294 00295 assert(gui); 00296 of=gui->hideBoxFn; 00297 gui->hideBoxFn=f; 00298 return of; 00299 } 00300 00301 00302 00303 GWEN_GUI_PROGRESS_START_FN 00304 GWEN_Gui_SetProgressStartFn(GWEN_GUI *gui, GWEN_GUI_PROGRESS_START_FN f){ 00305 GWEN_GUI_PROGRESS_START_FN of; 00306 00307 assert(gui); 00308 of=gui->progressStartFn; 00309 gui->progressStartFn=f; 00310 return of; 00311 } 00312 00313 00314 00315 GWEN_GUI_PROGRESS_ADVANCE_FN 00316 GWEN_Gui_SetProgressAdvanceFn(GWEN_GUI *gui, GWEN_GUI_PROGRESS_ADVANCE_FN f){ 00317 GWEN_GUI_PROGRESS_ADVANCE_FN of; 00318 00319 assert(gui); 00320 of=gui->progressAdvanceFn; 00321 gui->progressAdvanceFn=f; 00322 return of; 00323 } 00324 00325 00326 00327 GWEN_GUI_PROGRESS_LOG_FN 00328 GWEN_Gui_SetProgressLogFn(GWEN_GUI *gui, GWEN_GUI_PROGRESS_LOG_FN f){ 00329 GWEN_GUI_PROGRESS_LOG_FN of; 00330 00331 assert(gui); 00332 of=gui->progressLogFn; 00333 gui->progressLogFn=f; 00334 return of; 00335 } 00336 00337 00338 00339 GWEN_GUI_PROGRESS_END_FN 00340 GWEN_Gui_SetProgressEndFn(GWEN_GUI *gui, GWEN_GUI_PROGRESS_END_FN f){ 00341 GWEN_GUI_PROGRESS_END_FN of; 00342 00343 assert(gui); 00344 of=gui->progressEndFn; 00345 gui->progressEndFn=f; 00346 return of; 00347 } 00348 00349 00350 00351 GWEN_GUI_PRINT_FN GWEN_Gui_SetPrintFn(GWEN_GUI *gui, 00352 GWEN_GUI_PRINT_FN f){ 00353 GWEN_GUI_PRINT_FN of; 00354 00355 assert(gui); 00356 of=gui->printFn; 00357 gui->printFn=f; 00358 return of; 00359 } 00360 00361 00362 00363 GWEN_GUI_GETPASSWORD_FN GWEN_Gui_SetGetPasswordFn(GWEN_GUI *gui, 00364 GWEN_GUI_GETPASSWORD_FN f) { 00365 GWEN_GUI_GETPASSWORD_FN of; 00366 00367 assert(gui); 00368 of=gui->getPasswordFn; 00369 gui->getPasswordFn=f; 00370 return of; 00371 } 00372 00373 00374 00375 GWEN_GUI_SETPASSWORDSTATUS_FN 00376 GWEN_Gui_SetSetPasswordStatusFn(GWEN_GUI *gui, 00377 GWEN_GUI_SETPASSWORDSTATUS_FN f) { 00378 GWEN_GUI_SETPASSWORDSTATUS_FN of; 00379 00380 assert(gui); 00381 of=gui->setPasswordStatusFn; 00382 gui->setPasswordStatusFn=f; 00383 return of; 00384 } 00385 00386 00387 00388 GWEN_GUI_LOG_HOOK_FN GWEN_Gui_SetLogHookFn(GWEN_GUI *gui, 00389 GWEN_GUI_LOG_HOOK_FN f) { 00390 GWEN_GUI_LOG_HOOK_FN of; 00391 00392 assert(gui); 00393 of=gui->logHookFn; 00394 gui->logHookFn=f; 00395 00396 return of; 00397 } 00398 00399 00400 00401 GWEN_GUI_WAITFORSOCKETS_FN GWEN_Gui_SetWaitForSocketsFn(GWEN_GUI *gui, 00402 GWEN_GUI_WAITFORSOCKETS_FN f) { 00403 GWEN_GUI_WAITFORSOCKETS_FN of; 00404 00405 assert(gui); 00406 of=gui->waitForSocketsFn; 00407 gui->waitForSocketsFn=f; 00408 00409 return of; 00410 } 00411 00412 00413 00414 GWEN_GUI_CHECKCERT_FN GWEN_Gui_SetCheckCertFn(GWEN_GUI *gui, GWEN_GUI_CHECKCERT_FN f) { 00415 GWEN_GUI_CHECKCERT_FN of; 00416 00417 assert(gui); 00418 of=gui->checkCertFn; 00419 gui->checkCertFn=f; 00420 00421 return of; 00422 } 00423 00424 00425 00426 GWEN_GUI_EXEC_DIALOG_FN GWEN_Gui_SetExecDialogFn(GWEN_GUI *gui, GWEN_GUI_EXEC_DIALOG_FN f) { 00427 GWEN_GUI_EXEC_DIALOG_FN of; 00428 00429 assert(gui); 00430 of=gui->execDialogFn; 00431 gui->execDialogFn=f; 00432 00433 return of; 00434 } 00435 00436 00437 00438 GWEN_GUI_OPEN_DIALOG_FN GWEN_Gui_SetOpenDialogFn(GWEN_GUI *gui, GWEN_GUI_OPEN_DIALOG_FN f) { 00439 GWEN_GUI_OPEN_DIALOG_FN of; 00440 00441 assert(gui); 00442 of=gui->openDialogFn; 00443 gui->openDialogFn=f; 00444 00445 return of; 00446 } 00447 00448 00449 00450 GWEN_GUI_CLOSE_DIALOG_FN GWEN_Gui_SetCloseDialogFn(GWEN_GUI *gui, GWEN_GUI_CLOSE_DIALOG_FN f) { 00451 GWEN_GUI_CLOSE_DIALOG_FN of; 00452 00453 assert(gui); 00454 of=gui->closeDialogFn; 00455 gui->closeDialogFn=f; 00456 00457 return of; 00458 } 00459 00460 00461 00462 GWEN_GUI_RUN_DIALOG_FN GWEN_Gui_SetRunDialogFn(GWEN_GUI *gui, GWEN_GUI_RUN_DIALOG_FN f) { 00463 GWEN_GUI_RUN_DIALOG_FN of; 00464 00465 assert(gui); 00466 of=gui->runDialogFn; 00467 gui->runDialogFn=f; 00468 00469 return of; 00470 } 00471 00472 00473 00474 GWEN_GUI_READ_DIALOG_PREFS_FN 00475 GWEN_Gui_SetReadDialogPrefsFn(GWEN_GUI *gui, GWEN_GUI_READ_DIALOG_PREFS_FN f) { 00476 GWEN_GUI_READ_DIALOG_PREFS_FN of; 00477 00478 assert(gui); 00479 of=gui->readDialogPrefsFn; 00480 gui->readDialogPrefsFn=f; 00481 00482 return of; 00483 } 00484 00485 00486 00487 GWEN_GUI_WRITE_DIALOG_PREFS_FN 00488 GWEN_Gui_SetWriteDialogPrefsFn(GWEN_GUI *gui, GWEN_GUI_WRITE_DIALOG_PREFS_FN f) { 00489 GWEN_GUI_WRITE_DIALOG_PREFS_FN of; 00490 00491 assert(gui); 00492 of=gui->writeDialogPrefsFn; 00493 gui->writeDialogPrefsFn=f; 00494 00495 return of; 00496 } 00497 00498 00499 00500 GWEN_GUI_GET_FILENAME_FN GWEN_Gui_SetGetFileNameFn(GWEN_GUI *gui, GWEN_GUI_GET_FILENAME_FN f) { 00501 GWEN_GUI_GET_FILENAME_FN of; 00502 00503 assert(gui); 00504 of=gui->getFileNameFn; 00505 gui->getFileNameFn=f; 00506 00507 return of; 00508 } 00509 00510 00511 00512 GWEN_GUI_GETSYNCIO_FN GWEN_Gui_SetGetSyncIoFn(GWEN_GUI *gui, GWEN_GUI_GETSYNCIO_FN f) { 00513 GWEN_GUI_GETSYNCIO_FN of; 00514 00515 assert(gui); 00516 of=gui->getSyncIoFn; 00517 gui->getSyncIoFn=f; 00518 00519 return of; 00520 } 00521 00522 00523 00524 GWEN_GUI_KEYDATAFROMTEXT_OPENSSL_FN 00525 GWEN_Gui_SetKeyDataFromTextOpenSslFn(GWEN_GUI *gui, 00526 GWEN_GUI_KEYDATAFROMTEXT_OPENSSL_FN f) { 00527 GWEN_GUI_KEYDATAFROMTEXT_OPENSSL_FN of; 00528 00529 assert(gui); 00530 of=gui->keyDataFromTextOpenSslFn; 00531 gui->keyDataFromTextOpenSslFn=f; 00532 00533 return of; 00534 00535 } 00536 00537 00538 00539 uint32_t GWEN_Gui_GetFlags(const GWEN_GUI *gui) { 00540 assert(gui); 00541 return gui->flags; 00542 } 00543 00544 00545 00546 void GWEN_Gui_SetFlags(GWEN_GUI *gui, uint32_t fl) { 00547 assert(gui); 00548 gui->flags=fl; 00549 } 00550 00551 00552 00553 void GWEN_Gui_AddFlags(GWEN_GUI *gui, uint32_t fl) { 00554 assert(gui); 00555 gui->flags|=fl; 00556 } 00557 00558 00559 00560 void GWEN_Gui_SubFlags(GWEN_GUI *gui, uint32_t fl) { 00561 assert(gui); 00562 gui->flags&=~fl; 00563 } 00564 00565 00566 00567 void GWEN_Gui_SetName(GWEN_GUI *gui, const char *name) { 00568 free(gui->name); 00569 if (name) gui->name=strdup(name); 00570 else gui->name=NULL; 00571 } 00572 00573 00574 00575 const char *GWEN_Gui_GetName() { 00576 if (gwenhywfar_gui) 00577 return gwenhywfar_gui->name; 00578 return NULL; 00579 } 00580 00581 00582 00583 const char *GWEN_Gui_GetCharSet(const GWEN_GUI *gui) { 00584 if (gui) 00585 return gui->charSet; 00586 return NULL; 00587 } 00588 00589 00590 00591 void GWEN_Gui_SetCharSet(GWEN_GUI *gui, const char *s) { 00592 if (gui) { 00593 free(gui->charSet); 00594 if (s) 00595 gui->charSet=strdup(s); 00596 else 00597 gui->charSet=NULL; 00598 } 00599 } 00600 00601 00602 00603 00604 00605 00606 00607 00608 00609 00610 int GWEN_Gui_MessageBox(uint32_t flags, 00611 const char *title, 00612 const char *text, 00613 const char *b1, 00614 const char *b2, 00615 const char *b3, 00616 uint32_t guiid) { 00617 if (gwenhywfar_gui && gwenhywfar_gui->messageBoxFn) 00618 return gwenhywfar_gui->messageBoxFn(gwenhywfar_gui, 00619 flags, 00620 title, 00621 text, 00622 b1, b2, b3, guiid); 00623 return GWEN_ERROR_NOT_IMPLEMENTED; 00624 } 00625 00626 00627 00628 void GWEN_Gui_ShowError(const char *title, const char *fmt, ...) { 00629 va_list list; 00630 char msgbuffer[2048]; 00631 int rv; 00632 00633 /* prepare list for va_arg */ 00634 va_start(list, fmt); 00635 rv=vsnprintf(msgbuffer, sizeof(msgbuffer), fmt, list); 00636 if (rv<0 || rv>=(int)(sizeof(msgbuffer))) { 00637 DBG_WARN(GWEN_LOGDOMAIN, "Internal buffer too small for message, truncating (%d>%d)", 00638 rv, (int)(sizeof(msgbuffer))); 00639 } 00640 00641 GWEN_Gui_MessageBox(GWEN_GUI_MSG_FLAGS_SEVERITY_NORMAL | 00642 GWEN_GUI_MSG_FLAGS_TYPE_ERROR | 00643 GWEN_GUI_MSG_FLAGS_CONFIRM_B1, 00644 title, 00645 msgbuffer, 00646 I18N("Dismiss"), NULL, NULL, 0); 00647 } 00648 00649 00650 00651 int GWEN_Gui_InputBox(uint32_t flags, 00652 const char *title, 00653 const char *text, 00654 char *buffer, 00655 int minLen, 00656 int maxLen, 00657 uint32_t guiid) { 00658 if (gwenhywfar_gui && gwenhywfar_gui->inputBoxFn) 00659 return gwenhywfar_gui->inputBoxFn(gwenhywfar_gui, 00660 flags, 00661 title, 00662 text, 00663 buffer, 00664 minLen, maxLen, guiid); 00665 return GWEN_ERROR_NOT_IMPLEMENTED; 00666 } 00667 00668 00669 00670 uint32_t GWEN_Gui_ShowBox(uint32_t flags, 00671 const char *title, 00672 const char *text, 00673 uint32_t guiid) { 00674 if (gwenhywfar_gui && gwenhywfar_gui->showBoxFn) 00675 return gwenhywfar_gui->showBoxFn(gwenhywfar_gui, 00676 flags, 00677 title, 00678 text, 00679 guiid); 00680 return 0; 00681 } 00682 00683 00684 00685 void GWEN_Gui_HideBox(uint32_t id) { 00686 if (gwenhywfar_gui && gwenhywfar_gui->hideBoxFn) 00687 return gwenhywfar_gui->hideBoxFn(gwenhywfar_gui, id); 00688 } 00689 00690 00691 00692 uint32_t GWEN_Gui_ProgressStart(uint32_t progressFlags, 00693 const char *title, 00694 const char *text, 00695 uint64_t total, 00696 uint32_t guiid) { 00697 if (gwenhywfar_gui && gwenhywfar_gui->progressStartFn) 00698 return gwenhywfar_gui->progressStartFn(gwenhywfar_gui, 00699 progressFlags, 00700 title, 00701 text, 00702 total, 00703 guiid); 00704 return 0; 00705 } 00706 00707 00708 00709 int GWEN_Gui_ProgressAdvance(uint32_t id, uint32_t progress) { 00710 if (gwenhywfar_gui && gwenhywfar_gui->progressAdvanceFn) 00711 return gwenhywfar_gui->progressAdvanceFn(gwenhywfar_gui, 00712 id, 00713 progress); 00714 return 0; 00715 } 00716 00717 00718 00719 int GWEN_Gui_ProgressLog(uint32_t id, 00720 GWEN_LOGGER_LEVEL level, 00721 const char *text) { 00722 if (gwenhywfar_gui && gwenhywfar_gui->progressLogFn) 00723 return gwenhywfar_gui->progressLogFn(gwenhywfar_gui, 00724 id, level, text); 00725 return 0; 00726 } 00727 00728 00729 00730 int GWEN_Gui_ProgressLog2(uint32_t id, 00731 GWEN_LOGGER_LEVEL level, 00732 const char *fmt, ...) { 00733 va_list list; 00734 char msgbuffer[2048]; 00735 int rv; 00736 00737 /* prepare list for va_arg */ 00738 va_start(list, fmt); 00739 rv=vsnprintf(msgbuffer, sizeof(msgbuffer), fmt, list); 00740 if (rv<0 || rv>=(int)(sizeof(msgbuffer))) { 00741 DBG_WARN(GWEN_LOGDOMAIN, "Internal buffer too small for message, truncating (%d>%d)", 00742 rv, (int)(sizeof(msgbuffer))); 00743 } 00744 00745 return GWEN_Gui_ProgressLog(id, level, msgbuffer); 00746 } 00747 00748 00749 00750 int GWEN_Gui_ProgressEnd(uint32_t id) { 00751 if (gwenhywfar_gui && gwenhywfar_gui->progressEndFn) 00752 return gwenhywfar_gui->progressEndFn(gwenhywfar_gui, id); 00753 return GWEN_ERROR_NOT_IMPLEMENTED; 00754 } 00755 00756 00757 00758 int GWEN_Gui_Print(const char *docTitle, 00759 const char *docType, 00760 const char *descr, 00761 const char *text, 00762 uint32_t guiid) { 00763 if (gwenhywfar_gui && gwenhywfar_gui->printFn) 00764 return gwenhywfar_gui->printFn(gwenhywfar_gui, 00765 docTitle, 00766 docType, 00767 descr, 00768 text, 00769 guiid); 00770 return GWEN_ERROR_NOT_IMPLEMENTED; 00771 } 00772 00773 00774 00775 int GWEN_Gui_GetPassword(uint32_t flags, 00776 const char *token, 00777 const char *title, 00778 const char *text, 00779 char *buffer, 00780 int minLen, 00781 int maxLen, 00782 uint32_t guiid) { 00783 if (gwenhywfar_gui) { 00784 if (gwenhywfar_gui->getPasswordFn) 00785 return gwenhywfar_gui->getPasswordFn(gwenhywfar_gui, 00786 flags, 00787 token, 00788 title, 00789 text, 00790 buffer, 00791 minLen, 00792 maxLen, 00793 guiid); 00794 else 00795 if (gwenhywfar_gui->inputBoxFn) 00796 return gwenhywfar_gui->inputBoxFn(gwenhywfar_gui, 00797 flags, 00798 title, 00799 text, 00800 buffer, 00801 minLen, 00802 maxLen, 00803 guiid); 00804 } 00805 return GWEN_ERROR_NOT_IMPLEMENTED; 00806 } 00807 00808 00809 00810 int GWEN_Gui_SetPasswordStatus(const char *token, 00811 const char *pin, 00812 GWEN_GUI_PASSWORD_STATUS status, 00813 uint32_t guiid) { 00814 if (gwenhywfar_gui && gwenhywfar_gui->setPasswordStatusFn) 00815 return gwenhywfar_gui->setPasswordStatusFn(gwenhywfar_gui, 00816 token, pin, status, guiid); 00817 return GWEN_ERROR_NOT_IMPLEMENTED; 00818 } 00819 00820 00821 00822 int GWEN_Gui_LogHook(const char *logDomain, 00823 GWEN_LOGGER_LEVEL priority, const char *s) { 00824 if (gwenhywfar_gui && gwenhywfar_gui->logHookFn) { 00825 if (priority>=GWEN_LoggerLevel_Debug && 00826 logDomain && 00827 strcasecmp(logDomain, "gwenhywfar")==0) 00828 /* don't send possibly sensitive data to the log function because 00829 * some application tend to store the messages indiscriminately. 00830 * In some cases sensitive information can be send to this function 00831 * which we don't want the application to store */ 00832 return 0; 00833 else { 00834 int rv; 00835 00836 if (gwenhywfar_gui->inLogHook==0) { 00837 /* otherwise the log message seems to be uncritical, convey it */ 00838 gwenhywfar_gui->inLogHook++; 00839 rv=gwenhywfar_gui->logHookFn(gwenhywfar_gui, logDomain, priority, s); 00840 gwenhywfar_gui->inLogHook--; 00841 return rv; 00842 } 00843 else 00844 /* loghook recursion, don't convey */ 00845 return 0; 00846 } 00847 } 00848 else 00849 /* handle as usual */ 00850 return 0; 00851 } 00852 00853 00854 00855 int GWEN_Gui_WaitForSockets(GWEN_SOCKET_LIST2 *readSockets, 00856 GWEN_SOCKET_LIST2 *writeSockets, 00857 uint32_t guiid, 00858 int msecs) { 00859 if (gwenhywfar_gui && gwenhywfar_gui->waitForSocketsFn) 00860 return gwenhywfar_gui->waitForSocketsFn(gwenhywfar_gui, readSockets, writeSockets, guiid, msecs); 00861 else { 00862 uint32_t pid; 00863 time_t t0; 00864 int wt; 00865 int dist; 00866 00867 t0=time(0); 00868 if (msecs==GWEN_TIMEOUT_NONE) { 00869 wt=0; 00870 dist=0; 00871 } 00872 else if (msecs==GWEN_TIMEOUT_FOREVER) { 00873 wt=0; 00874 dist=500; 00875 } 00876 else { 00877 wt=msecs/1000; 00878 dist=500; 00879 } 00880 00881 pid=GWEN_Gui_ProgressStart(((wt!=0)?GWEN_GUI_PROGRESS_SHOW_PROGRESS:0) | 00882 GWEN_GUI_PROGRESS_SHOW_ABORT | 00883 GWEN_GUI_PROGRESS_DELAY | 00884 GWEN_GUI_PROGRESS_ALLOW_EMBED, 00885 I18N("Waiting for Data"), 00886 "Waiting for data to become available", 00887 wt, 00888 0); 00889 while(1) { 00890 GWEN_SOCKETSET *rset; 00891 GWEN_SOCKETSET *wset; 00892 GWEN_SOCKET_LIST2_ITERATOR *sit; 00893 00894 rset=GWEN_SocketSet_new(); 00895 wset=GWEN_SocketSet_new(); 00896 00897 /* fill read socket set */ 00898 if (readSockets) { 00899 sit=GWEN_Socket_List2_First(readSockets); 00900 if (sit) { 00901 GWEN_SOCKET *s; 00902 00903 s=GWEN_Socket_List2Iterator_Data(sit); 00904 assert(s); 00905 00906 while(s) { 00907 GWEN_SocketSet_AddSocket(rset, s); 00908 s=GWEN_Socket_List2Iterator_Next(sit); 00909 } 00910 GWEN_Socket_List2Iterator_free(sit); 00911 } 00912 } 00913 00914 /* fill write socket set */ 00915 if (writeSockets) { 00916 sit=GWEN_Socket_List2_First(writeSockets); 00917 if (sit) { 00918 GWEN_SOCKET *s; 00919 00920 s=GWEN_Socket_List2Iterator_Data(sit); 00921 assert(s); 00922 00923 while(s) { 00924 GWEN_SocketSet_AddSocket(wset, s); 00925 s=GWEN_Socket_List2Iterator_Next(sit); 00926 } 00927 GWEN_Socket_List2Iterator_free(sit); 00928 } 00929 } 00930 00931 if (GWEN_SocketSet_GetSocketCount(rset)==0 && 00932 GWEN_SocketSet_GetSocketCount(wset)==0) { 00933 /* no sockets to wait for, sleep for a few ms to keep cpu load down */ 00934 GWEN_SocketSet_free(wset); 00935 GWEN_SocketSet_free(rset); 00936 00937 if (msecs) { 00938 /* only sleep if a timeout was given */ 00939 DBG_DEBUG(GWEN_LOGDOMAIN, "Sleeping (no socket)"); 00940 GWEN_Socket_Select(NULL, NULL, NULL, GWEN_GUI_CPU_TIMEOUT); 00941 } 00942 GWEN_Gui_ProgressEnd(pid); 00943 return GWEN_ERROR_TIMEOUT; 00944 } 00945 else { 00946 int rv; 00947 int v=0; 00948 00949 rv=GWEN_Socket_Select(rset, wset, NULL, dist); 00950 GWEN_SocketSet_free(wset); 00951 GWEN_SocketSet_free(rset); 00952 00953 if (rv!=GWEN_ERROR_TIMEOUT) { 00954 GWEN_Gui_ProgressEnd(pid); 00955 return rv; 00956 } 00957 00958 if (wt) { 00959 time_t t1; 00960 00961 t1=time(0); 00962 v=(int) difftime(t1, t0); 00963 if (v>wt) { 00964 GWEN_Gui_ProgressEnd(pid); 00965 return GWEN_ERROR_TIMEOUT; 00966 } 00967 } 00968 rv=GWEN_Gui_ProgressAdvance(pid, v); 00969 if (rv==GWEN_ERROR_USER_ABORTED) { 00970 GWEN_Gui_ProgressEnd(pid); 00971 return rv; 00972 } 00973 } 00974 } /* loop */ 00975 } 00976 } 00977 00978 00979 00980 int GWEN_Gui_CheckCert(const GWEN_SSLCERTDESCR *cd, GWEN_SYNCIO *sio, uint32_t guiid) { 00981 if (gwenhywfar_gui && gwenhywfar_gui->checkCertFn) 00982 return gwenhywfar_gui->checkCertFn(gwenhywfar_gui, cd, sio, guiid); 00983 else 00984 return GWEN_ERROR_NOT_IMPLEMENTED; 00985 } 00986 00987 00988 00989 int GWEN_Gui_CheckCertBuiltIn(GWEN_UNUSED GWEN_GUI *gui, 00990 const GWEN_SSLCERTDESCR *cd, 00991 GWEN_UNUSED GWEN_SYNCIO *sio, uint32_t guiid) { 00992 int rv; 00993 int isError; 00994 const char *hash; 00995 const char *status; 00996 const char *ipAddr; 00997 const char *statusOn; 00998 const char *statusOff; 00999 char varName[128]; 01000 char dbuffer1[32]; 01001 char dbuffer2[32]; 01002 char buffer[8192]; 01003 const GWEN_TIME *ti; 01004 const char *unknown; 01005 const char *commonName; 01006 const char *organizationName; 01007 const char *organizationalUnitName; 01008 const char *countryName; 01009 const char *localityName; 01010 const char *stateOrProvinceName; 01011 01012 char *msg=I18S( 01013 "The following certificate has been received:\n" 01014 "Name : %s\n" 01015 "Organisation: %s\n" 01016 "Department : %s\n" 01017 "Country : %s\n" 01018 "City : %s\n" 01019 "State : %s\n" 01020 "Valid after : %s\n" 01021 "Valid until : %s\n" 01022 "Hash : %s\n" 01023 "Status : %s\n" 01024 "Do you wish to accept this certificate?" 01025 01026 "<html>" 01027 " <p>" 01028 " The following certificate has been received:" 01029 " </p>" 01030 " <table>" 01031 " <tr><td>Name</td><td>%s</td></tr>" 01032 " <tr><td>Organisation</td><td>%s</td></tr>" 01033 " <tr><td>Department</td><td>%s</td></tr>" 01034 " <tr><td>Country</td><td>%s</td></tr>" 01035 " <tr><td>City</td><td>%s</td></tr>" 01036 " <tr><td>State</td><td>%s</td></tr>" 01037 " <tr><td>Valid after</td><td>%s</td></tr>" 01038 " <tr><td>Valid until</td><td>%s</td></tr>" 01039 " <tr><td>Hash</td><td>%s</td></tr>" 01040 " <tr><td>Status</td><td>%s%s%s</td></tr>" 01041 " </table>" 01042 " <p>" 01043 " Do you wish to accept this certificate?" 01044 " </p>" 01045 "</html>" 01046 ); 01047 01048 memset(dbuffer1, 0, sizeof(dbuffer1)); 01049 memset(dbuffer2, 0, sizeof(dbuffer2)); 01050 memset(varName, 0, sizeof(varName)); 01051 01052 isError=GWEN_SslCertDescr_GetIsError(cd); 01053 01054 hash=GWEN_SslCertDescr_GetFingerPrint(cd); 01055 status=GWEN_SslCertDescr_GetStatusText(cd); 01056 ipAddr=GWEN_SslCertDescr_GetIpAddress(cd); 01057 01058 ti=GWEN_SslCertDescr_GetNotBefore(cd); 01059 if (ti) { 01060 GWEN_BUFFER *tbuf; 01061 01062 tbuf=GWEN_Buffer_new(0, 32, 0, 1); 01063 /* TRANSLATORS: This string is used as a template string to 01064 convert a given time into your local translated timeformat. The 01065 following characters are accepted in the template string: Y - 01066 digit of the year, M - digit of the month, D - digit of the day 01067 of month, h - digit of the hour, m - digit of the minute, s- 01068 digit of the second. All other characters are left unchanged. */ 01069 if (GWEN_Time_toString(ti, I18N("YYYY/MM/DD hh:mm:ss"), tbuf)) { 01070 DBG_ERROR(GWEN_LOGDOMAIN, 01071 "Could not convert beforeDate to string"); 01072 abort(); 01073 } 01074 strncpy(dbuffer1, GWEN_Buffer_GetStart(tbuf), sizeof(dbuffer1)-1); 01075 GWEN_Buffer_free(tbuf); 01076 } 01077 01078 ti=GWEN_SslCertDescr_GetNotAfter(cd); 01079 if (ti) { 01080 GWEN_BUFFER *tbuf; 01081 01082 tbuf=GWEN_Buffer_new(0, 32, 0, 1); 01083 if (GWEN_Time_toString(ti, I18N("YYYY/MM/DD hh:mm:ss"), tbuf)) { 01084 DBG_ERROR(GWEN_LOGDOMAIN, 01085 "Could not convert untilDate to string"); 01086 abort(); 01087 } 01088 strncpy(dbuffer2, GWEN_Buffer_GetStart(tbuf), sizeof(dbuffer2)-1); 01089 GWEN_Buffer_free(tbuf); 01090 } 01091 01092 if (isError) { 01093 statusOn="<font color=red>"; 01094 statusOff="</font>"; 01095 } 01096 else { 01097 statusOn="<font color=green>"; 01098 statusOff="</font>"; 01099 } 01100 01101 unknown=I18N("unknown"); 01102 commonName=GWEN_SslCertDescr_GetCommonName(cd); 01103 if (!commonName) 01104 commonName=unknown; 01105 organizationName=GWEN_SslCertDescr_GetOrganizationName(cd); 01106 if (!organizationName) 01107 organizationName=unknown; 01108 organizationalUnitName=GWEN_SslCertDescr_GetOrganizationalUnitName(cd); 01109 if (!organizationalUnitName) 01110 organizationalUnitName=unknown; 01111 countryName=GWEN_SslCertDescr_GetCountryName(cd); 01112 if (!countryName) 01113 countryName=unknown; 01114 localityName=GWEN_SslCertDescr_GetLocalityName(cd); 01115 if (!localityName) 01116 localityName=unknown; 01117 stateOrProvinceName=GWEN_SslCertDescr_GetStateOrProvinceName(cd); 01118 if (!stateOrProvinceName) 01119 stateOrProvinceName=unknown; 01120 if (!status) 01121 status=unknown; 01122 01123 snprintf(buffer, sizeof(buffer)-1, 01124 I18N(msg), 01125 commonName, 01126 organizationName, 01127 organizationalUnitName, 01128 countryName, 01129 localityName, 01130 stateOrProvinceName, 01131 dbuffer1, dbuffer2, 01132 hash, 01133 status, 01134 /* the same again for HTML */ 01135 commonName, 01136 organizationName, 01137 organizationalUnitName, 01138 countryName, 01139 localityName, 01140 stateOrProvinceName, 01141 dbuffer1, dbuffer2, 01142 hash, 01143 statusOn, 01144 status, 01145 statusOff 01146 ); 01147 01148 rv=GWEN_Gui_MessageBox(GWEN_GUI_MSG_FLAGS_TYPE_WARN | 01149 GWEN_GUI_MSG_FLAGS_CONFIRM_B1 | 01150 GWEN_GUI_MSG_FLAGS_SEVERITY_DANGEROUS, 01151 I18N("Certificate Received"), 01152 buffer, 01153 I18N("Yes"), I18N("No"), 0, guiid); 01154 if (rv==1) { 01155 return 0; 01156 } 01157 else { 01158 DBG_NOTICE(GWEN_LOGDOMAIN, "User rejected certificate"); 01159 01160 return GWEN_ERROR_SSL_SECURITY; 01161 } 01162 } 01163 01164 01165 01166 int GWEN_Gui_KeyDataFromText_OpenSSL(const char *text, 01167 unsigned char *buffer, 01168 unsigned int bufLength) { 01169 if (gwenhywfar_gui && gwenhywfar_gui->keyDataFromTextOpenSslFn) 01170 return gwenhywfar_gui->keyDataFromTextOpenSslFn(gwenhywfar_gui, 01171 text, 01172 buffer, 01173 bufLength); 01174 return GWEN_ERROR_NOT_IMPLEMENTED; 01175 } 01176 01177 01178 01179 int GWEN_Gui_ExecDialog(GWEN_DIALOG *dlg, uint32_t guiid) { 01180 if (gwenhywfar_gui && gwenhywfar_gui->execDialogFn) 01181 return gwenhywfar_gui->execDialogFn(gwenhywfar_gui, dlg, guiid); 01182 return GWEN_ERROR_NOT_IMPLEMENTED; 01183 } 01184 01185 01186 01187 int GWEN_Gui_OpenDialog(GWEN_DIALOG *dlg, uint32_t guiid) { 01188 if (gwenhywfar_gui && gwenhywfar_gui->openDialogFn) 01189 return gwenhywfar_gui->openDialogFn(gwenhywfar_gui, dlg, guiid); 01190 return GWEN_ERROR_NOT_IMPLEMENTED; 01191 } 01192 01193 01194 01195 int GWEN_Gui_CloseDialog(GWEN_DIALOG *dlg) { 01196 if (gwenhywfar_gui && gwenhywfar_gui->closeDialogFn) 01197 return gwenhywfar_gui->closeDialogFn(gwenhywfar_gui, dlg); 01198 return GWEN_ERROR_NOT_IMPLEMENTED; 01199 } 01200 01201 01202 01203 int GWEN_Gui_RunDialog(GWEN_DIALOG *dlg, int untilEnd) { 01204 if (gwenhywfar_gui && gwenhywfar_gui->runDialogFn) 01205 return gwenhywfar_gui->runDialogFn(gwenhywfar_gui, dlg, untilEnd); 01206 return GWEN_ERROR_NOT_IMPLEMENTED; 01207 } 01208 01209 01210 01211 01212 int GWEN_Gui_GetFileName(const char *caption, 01213 GWEN_GUI_FILENAME_TYPE fnt, 01214 uint32_t flags, 01215 const char *patterns, 01216 GWEN_BUFFER *pathBuffer, 01217 uint32_t guiid) { 01218 if (gwenhywfar_gui && gwenhywfar_gui->getFileNameFn) 01219 return gwenhywfar_gui->getFileNameFn(gwenhywfar_gui, 01220 caption, 01221 fnt, 01222 flags, 01223 patterns, 01224 pathBuffer, 01225 guiid); 01226 return GWEN_ERROR_NOT_IMPLEMENTED; 01227 } 01228 01229 01230 01231 int GWEN_Gui_ReadDialogPrefs(const char *groupName, 01232 const char *altName, 01233 GWEN_DB_NODE **pDb) { 01234 if (gwenhywfar_gui && gwenhywfar_gui->readDialogPrefsFn) 01235 return gwenhywfar_gui->readDialogPrefsFn(gwenhywfar_gui, groupName, altName, pDb); 01236 return GWEN_ERROR_NOT_IMPLEMENTED; 01237 } 01238 01239 01240 01241 int GWEN_Gui_WriteDialogPrefs(const char *groupName, 01242 GWEN_DB_NODE *db) { 01243 if (gwenhywfar_gui && gwenhywfar_gui->writeDialogPrefsFn) 01244 return gwenhywfar_gui->writeDialogPrefsFn(gwenhywfar_gui, groupName, db); 01245 return GWEN_ERROR_NOT_IMPLEMENTED; 01246 } 01247 01248 01249 01250 int GWEN_Gui_GetSyncIo(const char *url, 01251 const char *defaultProto, 01252 int defaultPort, 01253 GWEN_SYNCIO **pSio) { 01254 if (gwenhywfar_gui && gwenhywfar_gui->getSyncIoFn) 01255 return gwenhywfar_gui->getSyncIoFn(gwenhywfar_gui, url, defaultProto, defaultPort, pSio); 01256 return GWEN_ERROR_NOT_IMPLEMENTED; 01257 } 01258 01259 01260 01261 01262 01263 01264 01265 01266 01267 01268 int GWEN_Gui_ShowProgress(GWEN_PROGRESS_DATA *pd) { 01269 GWEN_PROGRESS_DATA *highest=NULL; 01270 GWEN_PROGRESS_DATA *t; 01271 GWEN_DIALOG *dlg=NULL; 01272 01273 assert(gwenhywfar_gui); 01274 01275 t=pd; 01276 while(t) { 01277 highest=t; 01278 t=GWEN_ProgressData_Tree_GetParent(t); 01279 } 01280 01281 /* highest must always be visible */ 01282 if (GWEN_ProgressData_GetShown(highest)==0) 01283 GWEN_ProgressData_SetShown(highest, 1); 01284 01285 dlg=GWEN_ProgressData_GetDialog(highest); 01286 if (dlg==NULL) { 01287 int rv; 01288 01289 /* need to create dialog for it */ 01290 dlg=GWEN_DlgProgress_new(); 01291 if (GWEN_ProgressData_GetFlags(pd) & GWEN_GUI_PROGRESS_KEEP_OPEN) 01292 GWEN_DlgProgress_SetStayOpen(dlg, 1); 01293 01294 if (GWEN_ProgressData_GetFlags(pd) & GWEN_GUI_PROGRESS_SHOW_LOG) 01295 GWEN_DlgProgress_SetShowLog(dlg, 1); 01296 01297 rv=GWEN_Gui_OpenDialog(dlg, 0); 01298 if (rv<0) { 01299 DBG_ERROR(GWEN_LOGDOMAIN, "Unable to openDialog: %d", rv); 01300 GWEN_Dialog_free(dlg); 01301 return rv; 01302 } 01303 01304 DBG_INFO(GWEN_LOGDOMAIN, "Setting new firstprogress: %08x", 01305 GWEN_ProgressData_GetId(pd)); 01306 GWEN_DlgProgress_SetFirstProgress(dlg, highest); 01307 GWEN_ProgressData_SetDialog(highest, dlg); 01308 } 01309 01310 if (pd!=highest) { 01311 DBG_INFO(GWEN_LOGDOMAIN, "Setting new second progress: %08x", 01312 GWEN_ProgressData_GetId(pd)); 01313 GWEN_DlgProgress_SetSecondProgress(dlg, pd); 01314 GWEN_ProgressData_SetDialog(pd, dlg); 01315 GWEN_ProgressData_SetShown(pd, 1); 01316 } 01317 01318 GWEN_Gui_RunDialog(dlg, 0); 01319 01320 return 0; 01321 } 01322 01323 01324 01325 void GWEN_Gui_Internal_CheckShow(GWEN_GUI *gui, GWEN_PROGRESS_DATA *pd) { 01326 if (GWEN_ProgressData_GetShown(pd)==0) { 01327 if (GWEN_ProgressData_GetFlags(pd) & GWEN_GUI_PROGRESS_DELAY) { 01328 double dt; 01329 time_t t1; 01330 01331 t1=time(0); 01332 dt=difftime(t1, GWEN_ProgressData_GetStartTime(pd)); 01333 if ((int)dt>=GWEN_GUI_DELAY_SECS) { 01334 DBG_INFO(GWEN_LOGDOMAIN, "Progress %08x open for %d secs, showing", 01335 GWEN_ProgressData_GetId(pd), (int) dt); 01336 GWEN_ProgressData_SetShown(pd, 1); 01337 } 01338 } 01339 else 01340 GWEN_ProgressData_SetShown(pd, 1); 01341 } 01342 01343 if (GWEN_ProgressData_GetShown(pd)==1) { 01344 if (GWEN_ProgressData_GetDialog(pd)==NULL) { 01345 GWEN_Gui_ShowProgress(pd); 01346 } 01347 } 01348 } 01349 01350 01351 01352 uint32_t GWEN_Gui_Internal_ProgressStart(GWEN_GUI *gui, 01353 uint32_t progressFlags, 01354 const char *title, 01355 const char *text, 01356 uint64_t total, 01357 uint32_t guiid) { 01358 GWEN_PROGRESS_DATA *pdParent=NULL; 01359 GWEN_PROGRESS_DATA *pd; 01360 uint32_t id; 01361 01362 id=++(gui->nextProgressId); 01363 01364 DBG_DEBUG(GWEN_LOGDOMAIN, "ProgressStart: flags=%08x, title=[%s], total=%08x, guiid=%08x", 01365 progressFlags, title?title:"(none)", (uint32_t) total, guiid); 01366 01367 if (guiid==0) { 01368 guiid=gui->lastProgressId; 01369 } 01370 01371 if (guiid) { 01372 pdParent=GWEN_ProgressData_Tree_FindProgressById(gui->progressDataTree, guiid); 01373 if (pdParent==NULL) { 01374 DBG_WARN(GWEN_LOGDOMAIN, "Parent progress by id %08x not found", guiid); 01375 DBG_DEBUG(GWEN_LOGDOMAIN, "Title: [%s], Text: [%s]", 01376 title?title:"no title", 01377 text?text:"no text"); 01378 } 01379 } 01380 01381 pd=GWEN_ProgressData_new(gui, id, progressFlags, title, text, total); 01382 assert(pd); 01383 GWEN_ProgressData_SetPreviousId(pd, gui->lastProgressId); 01384 if (pdParent) 01385 GWEN_ProgressData_Tree_AddChild(pdParent, pd); 01386 else 01387 GWEN_ProgressData_Tree_Add(gui->progressDataTree, pd); 01388 01389 GWEN_Gui_Internal_CheckShow(gui, pd); 01390 01391 gui->lastProgressId=id; 01392 01393 return id; 01394 } 01395 01396 01397 01398 int GWEN_Gui_Internal_ProgressEnd(GWEN_GUI *gui, uint32_t pid) { 01399 GWEN_PROGRESS_DATA *pd; 01400 uint32_t parentPid=0; 01401 01402 DBG_DEBUG(GWEN_LOGDOMAIN, "ProgressEnd: guiid=%08x", pid); 01403 01404 if (pid==0) { 01405 pid=gui->lastProgressId; 01406 if (pid==0) { 01407 DBG_INFO(GWEN_LOGDOMAIN, "Last active progress not available"); 01408 return GWEN_ERROR_INVALID; 01409 } 01410 } 01411 01412 pd=GWEN_ProgressData_Tree_FindProgressById(gui->progressDataTree, pid); 01413 if (pd==NULL) { 01414 DBG_ERROR(GWEN_LOGDOMAIN, "Progress by id %08x not found", pid); 01415 return GWEN_ERROR_INVALID; 01416 } 01417 else { 01418 GWEN_DIALOG *dlg; 01419 GWEN_PROGRESS_DATA *previousPd; 01420 01421 /* set previous progress id */ 01422 gui->lastProgressId=GWEN_ProgressData_GetPreviousId(pd); 01423 01424 /* find next highest active progress */ 01425 previousPd=GWEN_ProgressData_Tree_GetParent(pd); 01426 if (previousPd) 01427 parentPid=GWEN_ProgressData_GetId(previousPd); 01428 while(previousPd) { 01429 if (GWEN_ProgressData_GetShown(previousPd)) 01430 break; 01431 previousPd=GWEN_ProgressData_Tree_GetParent(previousPd); 01432 } 01433 01434 dlg=GWEN_ProgressData_GetDialog(pd); 01435 if (dlg) { 01436 GWEN_PROGRESS_DATA *primary; 01437 GWEN_PROGRESS_DATA *secondary; 01438 01439 primary=GWEN_DlgProgress_GetFirstProgress(dlg); 01440 secondary=GWEN_DlgProgress_GetSecondProgress(dlg); 01441 01442 /* force update of progress bar */ 01443 GWEN_DlgProgress_Advanced(dlg, pd); 01444 GWEN_Gui_RunDialog(dlg, 0); 01445 01446 if (primary==pd) { 01447 int rv; 01448 01449 DBG_DEBUG(GWEN_LOGDOMAIN, "Progress %08x is primary, closing dialog", 01450 GWEN_ProgressData_GetId(pd)); 01451 01452 if (secondary) { 01453 DBG_WARN(GWEN_LOGDOMAIN, "There is still a secondary progress!"); 01454 GWEN_DlgProgress_SetSecondProgress(dlg, NULL); 01455 GWEN_ProgressData_SetDialog(secondary, NULL); 01456 } 01457 01458 /* this is the primary progress, with this closed we can also 01459 * close the dialog */ 01460 DBG_INFO(GWEN_LOGDOMAIN, "Closing progress dialog"); 01461 GWEN_DlgProgress_AddLogText(dlg, GWEN_LoggerLevel_Info, I18N("Operation finished, you can now close this window.")); 01462 01463 // run dialog until end, close then 01464 GWEN_DlgProgress_SetAllowClose(dlg, 1); 01465 if (GWEN_DlgProgress_GetStayOpen(dlg)) { 01466 rv=GWEN_Gui_RunDialog(dlg, 1); 01467 if (rv<0) { 01468 DBG_ERROR(GWEN_LOGDOMAIN, "Unable to runDialog: %d", rv); 01469 /*GWEN_Dialog_free(dlg); 01470 return rv;*/ 01471 } 01472 } 01473 01474 rv=GWEN_Gui_CloseDialog(dlg); 01475 if (rv<0) { 01476 DBG_ERROR(GWEN_LOGDOMAIN, "Unable to closeDialog: %d", rv); 01477 GWEN_Dialog_free(dlg); 01478 return rv; 01479 } 01480 GWEN_Dialog_free(dlg); 01481 } 01482 else if (secondary==pd) { 01483 /* t is maybe the next higher progress, it will become the second progress */ 01484 if (previousPd && previousPd!=GWEN_DlgProgress_GetFirstProgress(dlg)) { 01485 DBG_DEBUG(GWEN_LOGDOMAIN, "Progress %08x becomes new second progress", 01486 GWEN_ProgressData_GetId(previousPd)); 01487 GWEN_DlgProgress_SetSecondProgress(dlg, pd); 01488 GWEN_ProgressData_SetDialog(pd, dlg); 01489 } 01490 else { 01491 DBG_INFO(GWEN_LOGDOMAIN, "No next secondary progress"); 01492 GWEN_DlgProgress_SetSecondProgress(dlg, NULL); 01493 } 01494 } 01495 else { 01496 DBG_ERROR(GWEN_LOGDOMAIN, "Progress %08x is neither primary nor secondary, SNH", 01497 GWEN_ProgressData_GetId(pd)); 01498 } 01499 } 01500 else { 01501 DBG_DEBUG(GWEN_LOGDOMAIN, "Progress %08x has no dialog", GWEN_ProgressData_GetId(pd)); 01502 } 01503 01504 GWEN_ProgressData_SetDialog(pd, NULL); 01505 GWEN_ProgressData_Tree_Del(pd); 01506 GWEN_ProgressData_free(pd); 01507 } 01508 01509 return 0; 01510 } 01511 01512 01513 01514 int GWEN_Gui_Internal_ProgressAdvance(GWEN_GUI *gui, uint32_t pid, uint64_t progress) { 01515 GWEN_PROGRESS_DATA *pd; 01516 int aborted=0; 01517 01518 if (pid==0) { 01519 pid=gui->lastProgressId; 01520 if (pid==0) { 01521 DBG_INFO(GWEN_LOGDOMAIN, "Last active progress not available"); 01522 return GWEN_ERROR_INVALID; 01523 } 01524 } 01525 01526 pd=GWEN_ProgressData_Tree_FindProgressById(gui->progressDataTree, pid); 01527 if (pd==NULL) { 01528 DBG_ERROR(GWEN_LOGDOMAIN, "Progress by id %08x not found", pid); 01529 return GWEN_ERROR_INVALID; 01530 } 01531 else { 01532 GWEN_DIALOG *dlg; 01533 01534 if (progress==GWEN_GUI_PROGRESS_ONE) 01535 progress=GWEN_ProgressData_GetCurrent(pd)+1; 01536 else if (progress==GWEN_GUI_PROGRESS_NONE) 01537 progress=GWEN_ProgressData_GetCurrent(pd); 01538 GWEN_ProgressData_SetCurrent(pd, progress); 01539 GWEN_Gui_Internal_CheckShow(gui, pd); 01540 01541 dlg=GWEN_ProgressData_GetDialog(pd); 01542 if (dlg) { 01543 time_t t0; 01544 time_t t1; 01545 01546 t0=GWEN_ProgressData_GetCheckTime(pd); 01547 t1=time(0); 01548 if (t0!=t1) { 01549 GWEN_DlgProgress_Advanced(dlg, pd); 01550 GWEN_Gui_RunDialog(dlg, 0); 01551 GWEN_ProgressData_SetCheckTime(pd, t1); 01552 } 01553 } 01554 aborted=GWEN_ProgressData_GetAborted(pd); 01555 } 01556 01557 if (aborted) 01558 return GWEN_ERROR_USER_ABORTED; 01559 return 0; 01560 } 01561 01562 01563 01564 int GWEN_Gui_Internal_ProgressLog(GWEN_GUI *gui, 01565 uint32_t pid, 01566 GWEN_LOGGER_LEVEL level, 01567 const char *text) { 01568 GWEN_PROGRESS_DATA *pd; 01569 int aborted=0; 01570 01571 if (pid==0) { 01572 pid=gui->lastProgressId; 01573 if (pid==0) { 01574 DBG_INFO(GWEN_LOGDOMAIN, "Last active progress not available"); 01575 return GWEN_ERROR_INVALID; 01576 } 01577 } 01578 01579 pd=GWEN_ProgressData_Tree_FindProgressById(gui->progressDataTree, pid); 01580 if (pd==NULL) { 01581 DBG_ERROR(GWEN_LOGDOMAIN, "Progress by id %08x not found", pid); 01582 return GWEN_ERROR_INVALID; 01583 } 01584 else { 01585 GWEN_DIALOG *dlg; 01586 01587 if (level<=GWEN_LoggerLevel_Notice) 01588 GWEN_ProgressData_SetShown(pd, 1); 01589 if (level<=GWEN_LoggerLevel_Warning) 01590 GWEN_ProgressData_AddFlags(pd, GWEN_GUI_PROGRESS_KEEP_OPEN); 01591 GWEN_Gui_Internal_CheckShow(gui, pd); 01592 01593 dlg=GWEN_ProgressData_GetDialog(pd); 01594 if (dlg) { 01595 if (level<=GWEN_LoggerLevel_Warning) { 01596 GWEN_DlgProgress_SetStayOpen(dlg, 1); 01597 GWEN_DlgProgress_SetShowLog(dlg, 1); 01598 } 01599 01600 GWEN_DlgProgress_AddLogText(dlg, level, text); 01601 GWEN_Gui_RunDialog(dlg, 0); 01602 } 01603 else 01604 GWEN_ProgressData_AddLogText(pd, level, text); 01605 01606 aborted=GWEN_ProgressData_GetAborted(pd); 01607 } 01608 01609 if (aborted) 01610 return GWEN_ERROR_USER_ABORTED; 01611 return 0; 01612 } 01613 01614 01615 01616 int GWEN_Gui_Internal_InputBox(GWEN_GUI *gui, 01617 uint32_t flags, 01618 const char *title, 01619 const char *text, 01620 char *buffer, 01621 int minLen, 01622 int maxLen, 01623 uint32_t guiid) { 01624 GWEN_DIALOG *dlg; 01625 int rv; 01626 01627 dlg=GWEN_DlgInput_new(flags, title, text, minLen, maxLen); 01628 if (dlg==NULL) { 01629 DBG_ERROR(GWEN_LOGDOMAIN, "Could not create dialog"); 01630 return GWEN_ERROR_INTERNAL; 01631 } 01632 01633 rv=GWEN_Gui_ExecDialog(dlg, 0); 01634 if (rv==1) { 01635 rv=GWEN_DlgInput_CopyInput(dlg, buffer, maxLen); 01636 if (rv<0) { 01637 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 01638 GWEN_Dialog_free(dlg); 01639 return rv; 01640 } 01641 GWEN_Dialog_free(dlg); 01642 return 0; 01643 } 01644 else { 01645 DBG_ERROR(GWEN_LOGDOMAIN, "User aborted"); 01646 GWEN_Dialog_free(dlg); 01647 return GWEN_ERROR_USER_ABORTED; 01648 } 01649 } 01650 01651 01652 01653 int GWEN_Gui_Internal_MessageBox(GWEN_GUI *gui, 01654 uint32_t flags, 01655 const char *title, 01656 const char *text, 01657 const char *b1, 01658 const char *b2, 01659 const char *b3, 01660 uint32_t guiid) { 01661 GWEN_DIALOG *dlg; 01662 int rv; 01663 01664 dlg=GWEN_DlgMessage_new(flags, title, text, b1, b2, b3); 01665 if (dlg==NULL) { 01666 DBG_ERROR(GWEN_LOGDOMAIN, "Could not create dialog"); 01667 return GWEN_ERROR_INTERNAL; 01668 } 01669 01670 GWEN_Gui_ExecDialog(dlg, 0); 01671 rv=GWEN_DlgMessage_GetResponse(dlg); 01672 GWEN_Dialog_free(dlg); 01673 return rv; 01674 } 01675 01676 01677 01678 uint32_t GWEN_Gui_Internal_ShowBox(GWEN_GUI *gui, 01679 uint32_t flags, 01680 const char *title, 01681 const char *text, 01682 uint32_t guiid) { 01683 GWEN_DIALOG *dlg; 01684 int rv; 01685 uint32_t id; 01686 01687 id=++(gui->nextDialogId); 01688 01689 dlg=GWEN_DlgShowBox_new(flags, title, text); 01690 if (dlg==NULL) { 01691 DBG_ERROR(GWEN_LOGDOMAIN, "Could not create dialog"); 01692 return 0; 01693 } 01694 01695 GWEN_Dialog_SetGuiId(dlg, id); 01696 01697 rv=GWEN_Gui_OpenDialog(dlg, guiid); 01698 if (rv<0) { 01699 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 01700 GWEN_Dialog_free(dlg); 01701 return 0; 01702 } 01703 01704 GWEN_Dialog_List_Add(dlg, gui->activeDialogs); 01705 01706 return id; 01707 } 01708 01709 01710 01711 void GWEN_Gui_Internal_HideBox(GWEN_GUI *gui, uint32_t id) { 01712 GWEN_DIALOG *dlg; 01713 01714 if (id) { 01715 dlg=GWEN_Dialog_List_First(gui->activeDialogs); 01716 while(dlg) { 01717 if (GWEN_Dialog_GetGuiId(dlg)==id) 01718 break; 01719 dlg=GWEN_Dialog_List_Next(dlg); 01720 } 01721 } 01722 else 01723 dlg=GWEN_Dialog_List_Last(gui->activeDialogs); 01724 01725 if (dlg) { 01726 int rv; 01727 01728 rv=GWEN_Gui_CloseDialog(dlg); 01729 if (rv<0) { 01730 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 01731 } 01732 GWEN_Dialog_List_Del(dlg); 01733 GWEN_Dialog_free(dlg); 01734 } 01735 } 01736 01737 01738 01739 int GWEN_Gui_Internal_GetSyncIo(GWEN_GUI *gui, 01740 const char *url, 01741 const char *defaultProto, 01742 int defaultPort, 01743 GWEN_SYNCIO **pSio) { 01744 GWEN_URL *u; 01745 const char *s; 01746 int port; 01747 const char *addr; 01748 01749 if (!(url && *url)) { 01750 DBG_ERROR(GWEN_LOGDOMAIN, "Empty URL"); 01751 return GWEN_ERROR_INVALID; 01752 } 01753 01754 u=GWEN_Url_fromString(url); 01755 if (u==NULL) { 01756 DBG_ERROR(GWEN_LOGDOMAIN, "Invalid URL [%s]", url); 01757 return GWEN_ERROR_INVALID; 01758 } 01759 01760 /* determine protocol and port */ 01761 s=GWEN_Url_GetProtocol(u); 01762 if (!(s && *s)) 01763 s=defaultProto; 01764 if (!(s && *s)) 01765 s="http"; 01766 port=GWEN_Url_GetPort(u); 01767 if (port<1) 01768 port=defaultPort; 01769 if (port<1) 01770 port=80; 01771 addr=GWEN_Url_GetServer(u); 01772 if (!(addr && *addr)) { 01773 DBG_ERROR(GWEN_LOGDOMAIN, "Missing server in URL [%s]", url); 01774 GWEN_Url_free(u); 01775 return GWEN_ERROR_INVALID; 01776 } 01777 01778 if (strcasecmp(s, "http")==0 || 01779 strcasecmp(s, "https")==0) { 01780 GWEN_SYNCIO *sio; 01781 GWEN_SYNCIO *baseLayer; 01782 GWEN_DB_NODE *db; 01783 GWEN_BUFFER *tbuf; 01784 int rv; 01785 01786 /* create base io */ 01787 sio=GWEN_SyncIo_Socket_new(GWEN_SocketTypeTCP, GWEN_AddressFamilyIP); 01788 if (sio==NULL) { 01789 DBG_INFO(GWEN_LOGDOMAIN, "here"); 01790 GWEN_Url_free(u); 01791 return GWEN_ERROR_GENERIC; 01792 } 01793 01794 GWEN_SyncIo_Socket_SetAddress(sio, addr); 01795 GWEN_SyncIo_Socket_SetPort(sio, port); 01796 baseLayer=sio; 01797 01798 if (strcasecmp(s, "https")==0) { 01799 /* create TLS layer */ 01800 sio=GWEN_SyncIo_Tls_new(baseLayer); 01801 if (sio==NULL) { 01802 DBG_INFO(GWEN_LOGDOMAIN, "here"); 01803 GWEN_SyncIo_free(baseLayer); 01804 GWEN_Url_free(u); 01805 return GWEN_ERROR_GENERIC; 01806 } 01807 GWEN_SyncIo_Tls_SetRemoteHostName(sio, addr); 01808 baseLayer=sio; 01809 } 01810 01811 /* create buffered layer as needed for HTTP */ 01812 sio=GWEN_SyncIo_Buffered_new(baseLayer); 01813 if (sio==NULL) { 01814 DBG_INFO(GWEN_LOGDOMAIN, "here"); 01815 GWEN_SyncIo_free(baseLayer); 01816 GWEN_Url_free(u); 01817 return GWEN_ERROR_GENERIC; 01818 } 01819 baseLayer=sio; 01820 01821 /* create HTTP layer */ 01822 sio=GWEN_SyncIo_Http_new(baseLayer); 01823 if (sio==NULL) { 01824 DBG_INFO(GWEN_LOGDOMAIN, "here"); 01825 GWEN_SyncIo_free(baseLayer); 01826 GWEN_Url_free(u); 01827 return GWEN_ERROR_GENERIC; 01828 } 01829 01830 /* setup default command and header */ 01831 tbuf=GWEN_Buffer_new(0, 256, 0, 1); 01832 db=GWEN_SyncIo_Http_GetDbCommandOut(sio); 01833 01834 /* get command string (e.g. server-relative path plus variables) */ 01835 rv=GWEN_Url_toCommandString(u, tbuf); 01836 if (rv<0) { 01837 DBG_ERROR(GWEN_LOGDOMAIN, "Invalid path in URL, ignoring (%d)", rv); 01838 } 01839 else 01840 GWEN_DB_SetCharValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS, "url", GWEN_Buffer_GetStart(tbuf)); 01841 GWEN_DB_SetCharValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS, "command", "GET"); 01842 GWEN_DB_SetCharValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS, "protocol", "HTTP/1.0"); 01843 01844 /* preset some headers */ 01845 db=GWEN_SyncIo_Http_GetDbHeaderOut(sio); 01846 GWEN_DB_SetCharValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS, "Host", addr); 01847 GWEN_DB_SetCharValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS, "Connection", "close"); 01848 01849 /* done */ 01850 GWEN_Url_free(u); 01851 *pSio=sio; 01852 return 0; 01853 } 01854 else { 01855 GWEN_SYNCIO *sio; 01856 01857 /* create base io */ 01858 sio=GWEN_SyncIo_Socket_new(GWEN_SocketTypeTCP, GWEN_AddressFamilyIP); 01859 if (sio==NULL) { 01860 DBG_INFO(GWEN_LOGDOMAIN, "here"); 01861 GWEN_Url_free(u); 01862 return GWEN_ERROR_GENERIC; 01863 } 01864 GWEN_SyncIo_Socket_SetAddress(sio, addr); 01865 GWEN_SyncIo_Socket_SetPort(sio, port); 01866 01867 /* done */ 01868 GWEN_Url_free(u); 01869 *pSio=sio; 01870 return 0; 01871 } 01872 01873 } 01874 01875 01876 01877 01878