📄 gtk-server.c
字号:
}/* Wait 0.1 second before removing the pipe - :-) */usleep(100);/* Delete file silently */if (!(gtkserver.behave & 2)) unlink(gtkserver.fifo);}void remove_queue(void){int msgid;msgid = msgget(gtkserver.ipc, 0666);if(msgid < 0) fprintf(stderr, "%s%s\n", "Could not find message queue: ", strerror(errno));if(msgctl(msgid, IPC_RMID, NULL) < 0) { fprintf(stderr, "%s%s\n", "Could not delete message queue. ERROR: ", strerror(errno));}}#endif/*************************************************************************************************/void Print_Error(char * fmt, int no, ...){va_list args;char data[MAX_LEN];#ifdef GTK_SERVER_UNIX #ifdef GTK_SERVER_GTK2x GtkWidget *dialog; /* Read arguments incoming in functionheader */ va_start(args, no); vsnprintf(data, MAX_LEN, fmt, args); gtk_init(NULL, NULL); dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, 2, "%s", data); gtk_window_set_title(GTK_WINDOW(dialog), "GTK-server Error!"); gtk_window_set_keep_above(GTK_WINDOW(dialog), TRUE); gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_CENTER); gtk_dialog_run(GTK_DIALOG (dialog)); gtk_widget_destroy(dialog); #elif GTK_SERVER_GTK1x GtkWidget *dialog, *label, *close_button; /* Read arguments incoming in functionheader */ va_start(args, no); vsnprintf(data, MAX_LEN, fmt, args); gtk_init(NULL, NULL); dialog = gtk_dialog_new(); gtk_window_set_title(GTK_WINDOW(dialog), "GTK-server Error!"); gtk_widget_set_usize(dialog, 350, 100); gtk_window_set_policy(GTK_WINDOW(dialog), FALSE, FALSE, TRUE); label = gtk_label_new(data); close_button = gtk_button_new_with_label("Close"); /* Ensure that the dialog box is destroyed when the user clicks ok. */ gtk_signal_connect_object(GTK_OBJECT(close_button), "clicked", GTK_SIGNAL_FUNC(gtk_main_quit), GTK_OBJECT(dialog)); gtk_signal_connect_object(GTK_OBJECT(dialog), "delete-event", GTK_SIGNAL_FUNC(gtk_main_quit), GTK_OBJECT(dialog)); gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area), close_button); /* Add the label, and show everything we've added to the dialog. */ gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox), label); gtk_widget_show_all(dialog); gtk_main(); #elif GTK_SERVER_XF FL_FORM *dialog; /* Read arguments incoming in functionheader */ va_start(args, no); vsnprintf(data, MAX_LEN, fmt, args); dialog = fl_bgn_form(FL_UP_BOX, 340, 180); fl_add_text(FL_NORMAL_TEXT, 10, 10, 320, 100, data); fl_add_button(FL_NORMAL_BUTTON, 135, 120, 70, 40, "Close"); fl_end_form(); fl_show_form(dialog, FL_PLACE_CENTER, FL_FULLBORDER, "GTK-server Error!"); fl_do_forms(); #else /* Read arguments incoming in functionheader */ va_start(args, no); vsnprintf(data, MAX_LEN, fmt, args); fprintf(stderr, "%s\n\n", data); #endif /* Send signal to parent process */ if (gtkserver.behave & 8) kill(gtkserver.ppid, gtkserver.exit_sig);#elif GTK_SERVER_WIN32 va_start(args, no); vsnprintf(data, MAX_LEN-1, fmt, args); /* Windows messages with messagebox */ MessageBox(NULL, data, "GTK-server Error", MB_OK | MB_ICONSTOP);#endifva_end(args);/* Since this is an error, exit GTK-server */exit(EXIT_FAILURE);}/*************************************************************************************************/char *Print_Result(char *fmt, int no, ...){static char *retstr = NULL;static long memsize = MAX_LEN;va_list args;va_list backup;/* These are used for the C string escaping */unsigned int i = 0, j = 0, l = 0, q, found;char hex_buf[3];char *result;/* Here we go */va_start(args, no);/* Portable va_copy */memcpy (&backup, &args, sizeof (va_list));/* Only executed at first-time use, the 2 extra blocks for are needed for \n\0 */if (retstr == NULL) { retstr = (char*)malloc(memsize*sizeof(char) + 2*sizeof(char)); if (retstr == NULL) Print_Error("%s%s", 2, "\nNo sufficient memory to allocate returnvalue: ", strerror(errno));}/* vsnprintf returns amount of chars that should be written regardless given size */i = vsnprintf(retstr, memsize, fmt, args);if (i > memsize) { retstr = (char*)realloc(retstr, i*sizeof(char) + 2*sizeof(char)); if (retstr == NULL) Print_Error("%s%s", 2, "\nNo sufficient memory to allocate returnvalue: ", strerror(errno)); memsize = i; /* Put back the va_list as it has been used already, using a portable va_copy */ memcpy (&args, &backup, sizeof (va_list)); vsnprintf(retstr, memsize, fmt, args);}va_end(args);va_end(backup);/* Now check if we need to apply C string escaping, only when a string is returned to client */if (gtkserver.c_escaped & 2) { /* This code is contributed by Jeremy Shute, adjusted to solve bugs found by Leonardo Cecchi */ /* Adjusted more so user can provide chars to escape - PvE */ /* Even more so it is generic - Danie Brink */ /* Walk through the escape symbols and check how many there are */ for(i = 0; retstr[i]; ++i){ for(q = 0; gtkserver.escapes[q]; q++){ if(gtkserver.escapes[q] == retstr[i]) l += 2; else{ if((unsigned char)retstr[i] < 32 || (unsigned char)retstr[i] > 254) l += 4; /* Special characters must be returned also */ else ++l; } } } /* Allocate 1 byte more for newline */ result = (char*)malloc(strlen((char*)retstr)*sizeof(char)+(l + 3 + 2)*sizeof(char)); if(!result) Print_Error ("%s", 1, "\nERROR: Cannot allocate memory for escaped string!"); result[0] = '"'; for(i = 0; retstr[i]; ++i) { found = 0; for(q = 0; gtkserver.escapes[q]; q++){ if(gtkserver.escapes[q] == retstr[i]){ result[ ++j ] = '\\'; switch( retstr[i]) { case '\a': result[ ++j ] = 'a'; break; case '\t': result[ ++j ] = 't'; break; case '\n': result[ ++j ] = 'n'; break; case '\r': result[ ++j ] = 'r'; break; default: result[ ++j ] = retstr[i]; } found = 1; } } if(!found){ if((unsigned char)retstr[i] < 32 || (unsigned char)retstr[i] > 254) { /* Special characters must be returned also */ snprintf(hex_buf, sizeof(hex_buf), "%02X", retstr[i]); result[++j] = '\\'; result[++j] = 'x'; result[++j] = hex_buf[0]; result[++j] = hex_buf[1]; } else result[++j] = retstr[i]; } } result[++j] = '"'; result[++j] = '\0'; /* Static return buffer big enough?*/ if (strlen(result) > memsize){ retstr = (char*)realloc(retstr, strlen(result)*sizeof(char) + 2*sizeof(char)); if (retstr == NULL) Print_Error("%s%s", 2, "\nNo sufficient memory to allocate returnvalue: ", strerror(errno)); memsize = strlen(result); } /* Clearup static return buffer */ memset(retstr, 0, memsize); /* Copy result in static buffer */ memcpy(retstr, result, strlen(result)); /* Free temporary buffer */ free(result); /* Make sure to 0 flag */ gtkserver.c_escaped &= 253;}return retstr;}/*************************************************************************************************//* * Shamelessly ripped from the SSL tutorial at http://www.rtfm.com/openssl-examples. * Heavily modified to fit GTK-server purposes. PvE. */#ifdef GTK_SERVER_USE_SSL/* Check that the common name matches the host name*/void check_cert(SSL *ssl, char *host, FILE *logfile){X509 *peer;char peer_CN[256]; if(SSL_get_verify_result(ssl) != X509_V_OK) Print_Error("%s", 1, "\nSSL: Certificate of remote server doesn't verify!");/* Check the common name */peer = SSL_get_peer_certificate(ssl);X509_NAME_get_text_by_NID(X509_get_subject_name(peer), NID_commonName, peer_CN, 256);/* If logging is enabled, write text to log */if (logfile != NULL){ fprintf(logfile, "SSL: remote identification is \"%s\" - GTK-server connects to \"%s\"\n", peer_CN, host); fflush(logfile);}if(strcasecmp(peer_CN, host)) Print_Error("%s", 1, "\nSSL: Common name doesn't match host name!");}/* Password callback */static int password_cb(char *buf, int size, int rwflag, void *userdata){if(gtkserver.password != NULL && size < strlen(gtkserver.password) + 1) return(0);strncpy(buf, gtkserver.password, size);buf[size - 1] = '\0';return(strlen(buf));}SSL_CTX *initialize_ctx(char *keyfile, char *password, FILE *logfile){SSL_METHOD *meth;SSL_CTX *ctx;/* Global system initialization*/SSL_library_init();SSL_load_error_strings();/* Create our context*/meth = SSLv23_method();ctx = SSL_CTX_new(meth);/* Load our keys and certificates*/if((gtkserver.behave & 64) && keyfile != NULL) { /* If logging is enabled, write text to log */ if (logfile != NULL){ fprintf(logfile, "SSL: trying to load keyfile \"%s\"\n", keyfile); fflush(logfile); } if(!(SSL_CTX_use_certificate_chain_file(ctx, keyfile))) Print_Error("%s", 1, "\nSSL: Cannot load certificate chain from file!"); /* Load a private key which optionally is encrypted with a password */ SSL_CTX_set_default_passwd_cb(ctx, password_cb); if(!(SSL_CTX_use_PrivateKey_file(ctx, keyfile, SSL_FILETYPE_PEM))) Print_Error("%s", 1, "\nSSL: Cannot add private key from file!");}/* To verify the remote host, load the CAs we trust*/if(gtkserver.behave & 128) { /* If logging is enabled, write text to log */ if (logfile != NULL){ fprintf(logfile, "SSL: trying to load CA \"%s\"\n", gtkserver.ca); fflush(logfile); } if(!(SSL_CTX_load_verify_locations(ctx, gtkserver.ca, 0))) Print_Error("%s", 1, "\nSSL: Cannot find file to verify CA!");}#if (OPENSSL_VERSION_NUMBER < 0x0090600fL)SSL_CTX_set_verify_depth(ctx, 1);#endifreturn ctx;}#endif/*************************************************************************************************/#ifdef GTK_SERVER_UNIXvoid sig_handler(int signal){int status;/* A child process was killed, decrease fork counter */gtkserver.count_fork--;/* Wait for child without blocking */if (waitpid(-1, &status, WNOHANG) < 0) return;}#endif/*************************************************************************************************//* Piece of code from http://www.koders.com/c/fid1867004532ABB00D9750ACC47A1366D52E8C616C.aspx *//* Modified a little bit to get it working with Win32 */char *mystrndup (const char *s, size_t n){char *new = malloc (n + 1);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -