gitkserver.c

Go to the documentation of this file.
00001 
00018 #define GITK_LIB_C
00019 #define GITK_SERVER_C
00020 
00021 #include "gitkincludes.h"
00022 
00023 #ifdef USE_LIBHTTPD
00024 
00025 //-- locale workaround helper
00026 
00030 static gchar *extend_locale_name(gchar *locale_name) {
00031   if(locale_name[2]=='\0') {
00032     static char ext_name[6];
00033     g_snprintf(ext_name,6,"%s_%s",locale_name,g_ascii_strup(locale_name,2));
00034     return(ext_name);
00035   }
00036   return(locale_name);
00037 }
00038 
00039 //-- output tools
00040 
00041 static void output_header(httpd *server,char *title_str) {
00042   // mozillas xslt engine does not like <!DOCTYPE ...> statements 
00043   httpdPrintf(server, "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"
00044                       "<?xml-stylesheet href=\"index.xsl\" type=\"text/xsl\"?>\n"
00045                       "<book>\n"
00046   );
00047   httpdPrintf(server, "  <bookinfo>"
00048                       "    <title>%s | %s::%s</title>"
00049                       "  </bookinfo>\n",title_str,client_package_name,client_name);
00050   httpdPrintf(server, "  <body>\n");
00051 }
00052 
00053 
00054 static void output_error(httpd *server,char *error_str) {
00055   output_header(server,"gitk http server error");
00056   httpdPrintf(server,"<p>%s</p>",error_str);
00057   httpdPrintf(server,"</body></book>");
00058 }
00059 
00060 static void output_section_heading(httpd  *server, char *heading) {
00061   httpdPrintf(server,"<tr><td colspan=\"3\" bgcolor=\"#F0F0F0\"><b>%s</b></td></tr>\n",heading);
00062 }
00063 
00064 static void output_section_spacer(httpd *server) {
00065   httpdPrintf(server,"<tr><td colspan=\"3\">&#160;</td></tr>\n");
00066 }
00067 
00068 
00069 //-- request handler
00070 
00071 void index_html(httpd *server) {
00072   httpVar *varPtr;
00073   static char env_lang[20],env_lcall[20];
00074   gboolean has_doc_changed=FALSE;
00075 
00076   varPtr=httpdGetVariableByName(server,"setrenderer");
00077   if(varPtr!=NULL) {
00078 
00079     gitk_log("### setrenderer ###\n");
00080 
00081     free(gitk_renderer_name);
00082     gitk_renderer_name=strdup(varPtr->value);
00083 
00084     exchange_event_loop=TRUE;
00085     gitk_renderer->gitkr_event_loop_end();
00086     //has_doc_changed=TRUE;
00087   }
00088   varPtr=httpdGetVariableByName(server,"setstyle");
00089   if(varPtr!=NULL) {
00090     gitk_log("setstyle");
00091     free(gitk_style_name);
00092     gitk_style_name=strdup(varPtr->value);
00093     gitk_init_xsl_style();
00094     has_doc_changed=TRUE;
00095   }
00096   varPtr=httpdGetVariableByName(server,"setlang");
00097   if(varPtr!=NULL) {
00098     gchar *_locale;
00099     gitk_log("setlang");
00100     if(varPtr->value && strncmp(varPtr->value,"default",7)) {
00101       snprintf(env_lang ,19,"LANG=%s"  ,varPtr->value);putenv(env_lang);
00102       snprintf(env_lcall,19,"LC_ALL=%s",varPtr->value);putenv(env_lcall);
00103       //_locale=setlocale(LC_ALL, varPtr->value);
00104     }
00105     else {
00108       snprintf(env_lang ,19,"LC_ALL=");putenv(env_lang);
00109       snprintf(env_lcall,19,"LANG=");putenv(env_lcall);
00110     }
00111     _locale=setlocale(LC_ALL, "");
00112     gitk_log("  rebinding text domains");
00113     if(!_locale) gitk_log2("error changing locale to \"%s\" : %d",varPtr->value,errno);
00114     //-- the catalog paths
00115     (void)bindtextdomain(PACKAGE, LOCALEDIR);
00116     (void)bindtextdomain(client_package_name, client_locale_dir);
00117     (void)bindtextdomain(gitk_renderer->gitkr_info(GITKR_INFO_PACKAGE), gitk_renderer->gitkr_info(GITKR_INFO_LOCALEDIR));
00118     (void)textdomain(PACKAGE);  // this finally seems to reload the locales
00119     gitk_log3("\"%s\" NLS enabled for \"%s\" in \"%s\"",(_locale?_locale:"-"),PACKAGE,LOCALEDIR);
00120     gitk_log3("\"%s\" NLS enabled for \"%s\" in \"%s\"",(_locale?_locale:"-"),client_package_name,client_locale_dir);
00121     has_doc_changed=TRUE;
00122   }
00123   if(has_doc_changed) {
00125     gitk_log("about to change all dialogs");
00126     //sigsend(P_PID,P_MYID,SIGHUP);
00127     gitk_renderer->gitkr_event_loop_restart();
00128     gitk_log("after changing all dialogs");
00129   }
00130 
00131   output_header(server,"gitk http server");
00132 
00133   //httpdPrintf(server,"<table border=\"0\" width=\"100%%\" cellpadding=\"1\" cellspacing=\"0\">\n");
00134   httpdPrintf(server,"<table border=\"0\" cellpadding=\"1\" cellspacing=\"0\">\n");
00135 
00136   //-- general info
00137   output_section_heading(server,"General Info");
00138   httpdPrintf(server,"<tr><td align=\"right\">application:</td><td>&#160;</td><td>%s::%s</td></tr>\n",client_package_name,client_name);
00139   httpdPrintf(server,"<tr><td align=\"right\">process id:</td><td>&#160;</td><td>%d</td></tr>\n",getpid());
00141   output_section_spacer(server);
00142 
00143   //-- renderer info
00144   output_section_heading(server,"Renderer Info");
00145   httpdPrintf(server,"<tr><td align=\"right\">current:</td><td>&#160;</td><td>%s</td></tr>\n",gitk_renderer_name);
00146   httpdPrintf(server,"<tr><td align=\"right\">media domain:</td><td>&#160;</td><td>%s</td></tr>\n",gitk_renderer->gitkr_info(GITKR_INFO_MEDIA_DOMAIN));
00147   httpdPrintf(server,"<tr><td align=\"right\">interface location:</td><td>&#160;</td><td>%s</td></tr>\n",gitk_renderer->gitkr_info(GITKR_INFO_INTERFACE_LOCATION));
00148   httpdPrintf(server,"<tr><td align=\"right\">switch to:</td><td>&#160;</td><td>\n");
00149   {
00150     DIR *dirp=opendir(LIBDIR);
00151     struct dirent *dire;
00152     gchar *fn;
00153     guint sl;
00154     
00155     if(dirp) {
00156       while((dire=readdir(dirp))!=NULL) {
00157         fn=dire->d_name;
00158         sl=strlen(fn);
00159         //-- if it starts and ends with defined strings
00160         if((sl>20) && !strncmp(fn,"libgitk-renderer-",17) && !strncmp(&fn[sl-3],".so",3)) {
00161           //-- renderer_name=fn[18...sl-3];
00162           fn[sl-3]='\0';
00163           if(strcmp(&fn[17],gitk_renderer_name)) httpdPrintf(server,"<a href=\"index.html?setrenderer=%s\">%s</a>\n",&fn[17],&fn[17]);
00164           fn[sl-3]='.';
00165         }
00166       }
00167       closedir(dirp);
00168     }
00169   }
00170   httpdPrintf(server," <b>(be careful yet!)</b></td></tr>\n");
00171   output_section_spacer(server);
00172 
00173   //-- style info
00174   output_section_heading(server,"Style Info");
00175   httpdPrintf(server,"<tr><td align=\"right\">current style:</td><td>&#160;</td><td>%s</td></tr>\n",gitk_style_name);
00176   httpdPrintf(server,"<tr><td align=\"right\">switch to:</td><td>&#160;</td><td>\n");
00177   {
00178     gchar *fn,dn[FILENAME_MAX];
00179     DIR *dirp;
00180     struct dirent *dire;
00181     guint sl;
00182     
00183     snprintf(dn,FILENAME_MAX,XSL_ROOT_PATH"gitk-renderer-%s/style",gitk_renderer_name,gitk_style_name);
00184     if((dirp=opendir(dn))) {
00185       while((dire=readdir(dirp))!=NULL) {
00186         fn=dire->d_name;
00187         sl=strlen(fn);
00188         //-- if it starts and ends with defined strings
00189         if((sl>4) && !strncmp(&fn[sl-4],".xsl",4)) {
00190           fn[sl-4]='\0';
00191           if(strcmp(fn,gitk_style_name)) httpdPrintf(server,"<a href=\"index.html?setstyle=%s\">%s</a>\n",fn,fn);
00192           fn[sl-4]='.';
00193         }
00194       }
00195       closedir(dirp);
00196     }
00197   }
00198   httpdPrintf(server,"</td></tr>\n");
00199   output_section_spacer(server);
00200 
00201   //-- locale info
00202   output_section_heading(server,"Locale Info");
00203   {
00204     char *envvar;
00205     
00206     envvar=getenv("LC_ALL");
00207     httpdPrintf(server,"<tr><td align=\"right\">env: LC_ALL:</td><td>&#160;</td><td>%s</td></tr>\n",gitk_save_get_string(envvar));
00208     envvar=getenv("LANG");
00209     httpdPrintf(server,"<tr><td align=\"right\">env: LANG:</td><td>&#160;</td><td>%s</td></tr>\n",gitk_save_get_string(envvar));
00210     httpdPrintf(server,"<tr><td align=\"right\">switch to:</td><td>&#160;</td><td>\n");
00211     httpdPrintf(server,"<a href=\"index.html?setlang=default\">default</a>\n");
00212     {
00213       gchar *fn,*ln;
00214       DIR *dirp=opendir(LOCALEDIR);
00215       struct dirent *dire;
00216 
00217       if(dirp) {
00218         while((dire=readdir(dirp))!=NULL) {
00219           fn=dire->d_name;
00220           if(fn && (*fn) && (strncmp(fn,"..\0",3)) && (strncmp(fn,".\0",2))) {
00221             ln=extend_locale_name(fn);
00222             if((envvar==NULL) || (strcmp(fn,envvar) && strcmp(ln,envvar))) {
00223               httpdPrintf(server,"<a href=\"index.html?setlang=%s\">%s</a>\n",ln,ln);
00224             }
00225           }
00226         }
00227         closedir(dirp);
00228       }
00229     }
00230   }
00231   httpdPrintf(server,"</td></tr>\n");
00232   output_section_spacer(server);
00233 
00234   //-- dialog list
00235   if(gitk_dialog_list) {
00236     GList* node=g_list_first(gitk_dialog_list);
00237     GitkDialogPtr dialog;
00238     guint number_of_contexts=0;
00239 
00240     output_section_heading(server,"Active Dialogs");
00241     while(node) {
00242       dialog=(GitkDialogPtr)node->data;
00244       httpdPrintf(server,"<tr><td>%d : %s:</td><td>&#160;</td><td>"
00245         "[<a href=\"showdialogdoc.html?dialog=%lu&amp;doc=src\">src</a>]&#160;"
00246         "[<a href=\"showdialogdoc.html?dialog=%lu&amp;doc=dst\">dst</a>]"
00247         "</td></tr>\n",
00248         dialog->priority, gitk_cxpath_get_string(dialog,xpath_get_dialog_name,NULL),
00249         (gulong)dialog,(gulong)dialog
00250       );
00251       number_of_contexts++;
00252       node=g_list_next(node);
00253     }
00254     httpdPrintf(server,"<tr><td colspan=\"3\">= %d dialog(s)</td></tr>\n",number_of_contexts);
00255     output_section_spacer(server);
00256   }
00257 
00258   if(has_doc_changed) {
00259     httpdPrintf(server,"<tr><td colspan=\"3\">option has been changed, back to <a href=\"index.html\">home</a>.</td></tr>\n");
00260     output_section_spacer(server);
00261   }
00262   
00263   //-- footer 
00264   httpdPrintf(server,"</table>");
00265   httpdPrintf(server,"</body>");
00266   //httpdPrintf(server,"</html>");
00267   httpdPrintf(server,"</book>");
00268 }
00269 
00270 
00271 void showdialogdoc_html(httpd *server) {
00272   httpVar *param=httpdGetVariableByName(server,"dialog");
00273   if(param) {
00274     GitkDialogPtr dialog=(GitkDialogPtr)atol(param->value);
00275     if(dialog) {
00276       param=httpdGetVariableByName(server,"doc");
00277       if(param) {
00278         xmlDocPtr const doc=(!strncmp(param->value,"src",3))?gitk_dialog_get_src(dialog):gitk_dialog_get_dst(dialog);
00279         if(doc) {
00280           xmlChar *buffer;
00281           guint size;
00282           
00283           xmlDocDumpMemory(doc,&buffer,&size);
00284           httpdOutput(server,buffer);
00285           xmlFree(buffer);
00286         }
00287         else output_error(server,"null doc specified");
00288       }
00289       else output_error(server,"no doc specified");
00290     }
00291     else output_error(server,"null dialog specified");
00292   }
00293   else output_error(server,"no dialog specified");
00294 }
00295 
00296 
00297 //-- server thread
00298 
00304 gpointer gitk_server_thread(gpointer data) {
00305   httpd *server;
00306   int result;
00307 
00308   gitk_log1("starting http server on port %d",gitk_server_port);
00309 
00310   //-- create a server and setup our logging
00311   if(!(server=httpdCreate(NULL,gitk_server_port))) {
00312     gitk_log("can't create http server");
00313     return(NULL);
00314   }
00315   //httpdSetAccessLog(server,stderr);
00316   //httpdSetErrorLog(server,stderr);
00317   httpdSetFileBase(server,DATADIR""G_DIR_SEPARATOR_S"httpd");
00318 
00319   //-- set some dummy content
00320   //httpdAddStaticContent(server,"/","index.html",HTTP_FALSE, NULL,"<HTML><BODY>This is just a test</BODY></HTML>");
00321   httpdAddCContent(server,"/","index.html",HTTP_TRUE,NULL,index_html);
00322   httpdAddFileContent(server,"/","index.xsl",HTTP_FALSE,NULL,"index.xsl");
00323   httpdAddCContent(server,"/","showdialogdoc.html",HTTP_FALSE,NULL,showdialogdoc_html);
00324     
00325   //-- serve requests
00326   while(TRUE) {
00327     result=httpdGetConnection(server,NULL);
00328     if(result==0) {
00329       gitk_log("Timeout ... \n");
00330       continue;
00331     }
00332     if(result<0) {
00333       gitk_log("Error ... \n");
00334       continue;
00335     }
00336     if(httpdReadRequest(server)<0) {
00337       httpdEndRequest(server);
00338       continue;
00339     }
00340     httpdSetContentType(server,"text/xml");
00341     httpdProcessRequest(server);
00342     httpdEndRequest(server);
00343   }
00344   return(NULL);
00345 }
00346 
00347 #endif

Generated on Thu Oct 28 10:59:14 2004 for gitk by doxygen 1.3.6