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