void do_housekeeping(void) { int do_housekeeping_now = 0; int do_perminute_housekeeping_now = 0; time_t now; /* * We do it this way instead of wrapping the whole loop in an * S_HOUSEKEEPING critical section because it eliminates the need to * potentially have multiple concurrent mutexes in progress. */ begin_critical_section(S_HOUSEKEEPING); if (housekeeping_in_progress == 0) { do_housekeeping_now = 1; housekeeping_in_progress = 1; } end_critical_section(S_HOUSEKEEPING); if (do_housekeeping_now == 0) { return; } /* * Ok, at this point we've made the decision to run the housekeeping * loop. Everything below this point is real work. */ now = time(NULL); if ( (now - last_timer) > (time_t)60 ) { do_perminute_housekeeping_now = 1; last_timer = time(NULL); } /* First, do the "as often as needed" stuff... */ JournalRunQueue(); PerformSessionHooks(EVT_HOUSE); /* Then, do the "once per minute" stuff... */ if (do_perminute_housekeeping_now) { cdb_check_handles(); /* suggested by Justin Case */ PerformSessionHooks(EVT_TIMER); /* Run any timer hooks */ } /* * All done. */ begin_critical_section(S_HOUSEKEEPING); housekeeping_in_progress = 0; end_critical_section(S_HOUSEKEEPING); }
int look_for_open_group_data(char *to) { int i,found; char temp1[MAX_CALLSIGN+1]; char *temp_ptr; begin_critical_section(&send_message_dialog_lock, "messages.c:look_for_open_group_data" ); found = FALSE; for(i = 0; i < MAX_MESSAGE_WINDOWS; i++) { /* find station */ if(mw[i].send_message_dialog != NULL) { temp_ptr = XmTextFieldGetString(mw[i].send_message_call_data); xastir_snprintf(temp1, sizeof(temp1), "%s", temp_ptr); XtFree(temp_ptr); (void)to_upper(temp1); /*fprintf(stderr,"Looking at call <%s> for <%s>\n",temp1,to);*/ if(strcmp(temp1,to)==0) { found=(int)TRUE; break; } } } end_critical_section(&send_message_dialog_lock, "messages.c:look_for_open_group_data" ); return(found); }
/* * This function is called by the XMPP service's async loop. * If the client session has instant messages waiting, it outputs * unsolicited XML stanzas containing them. */ void xmpp_output_incoming_messages(void) { struct ExpressMessage *ptr; char xmlbuf1[4096]; char xmlbuf2[4096]; while (CC->FirstExpressMessage != NULL) { begin_critical_section(S_SESSION_TABLE); ptr = CC->FirstExpressMessage; CC->FirstExpressMessage = CC->FirstExpressMessage->next; end_critical_section(S_SESSION_TABLE); cprintf("<message to=\"%s\" from=\"%s\" type=\"chat\">", xmlesc(xmlbuf1, XMPP->client_jid, sizeof xmlbuf1), xmlesc(xmlbuf2, ptr->sender_email, sizeof xmlbuf2) ); if (ptr->text != NULL) { striplt(ptr->text); cprintf("<body>%s</body>", xmlesc(xmlbuf1, ptr->text, sizeof xmlbuf1)); free(ptr->text); } cprintf("</message>"); free(ptr); } }
void clear_message_windows(void) { int i; begin_critical_section(&send_message_dialog_lock, "messages.c:clear_message_windows" ); for (i = 0; i < MAX_MESSAGE_WINDOWS; i++) { if (mw[i].send_message_dialog) XtDestroyWidget(mw[i].send_message_dialog); mw[i].send_message_dialog = (Widget)NULL; mw[i].to_call_sign[0] = '\0'; mw[i].send_message_call_data = (Widget)NULL; mw[i].D700_mode = (Widget)NULL; mw[i].D7_mode = (Widget)NULL; mw[i].HamHUD_mode = (Widget)NULL; mw[i].message_data_line1 = (Widget)NULL; mw[i].message_data_line2 = (Widget)NULL; mw[i].message_data_line3 = (Widget)NULL; mw[i].message_data_line4 = (Widget)NULL; mw[i].send_message_text = (Widget)NULL; } end_critical_section(&send_message_dialog_lock, "messages.c:clear_message_windows" ); }
/* * Hand off a copy of a message to be journalized. */ void JournalBackgroundSubmit(struct CtdlMessage *msg, StrBuf *saved_rfc822_version, recptypes *recps) { struct jnlq *jptr = NULL; /* Avoid double journaling! */ if (!CM_IsEmpty(msg, eJournal)) { FreeStrBuf(&saved_rfc822_version); return; } jptr = (struct jnlq *)malloc(sizeof(struct jnlq)); if (jptr == NULL) { FreeStrBuf(&saved_rfc822_version); return; } memset(jptr, 0, sizeof(struct jnlq)); if (recps != NULL) memcpy(&jptr->recps, recps, sizeof(recptypes)); if (!CM_IsEmpty(msg, eAuthor)) jptr->from = strdup(msg->cm_fields[eAuthor]); if (!CM_IsEmpty(msg, eNodeName)) jptr->node = strdup(msg->cm_fields[eNodeName]); if (!CM_IsEmpty(msg, erFc822Addr)) jptr->rfca = strdup(msg->cm_fields[erFc822Addr]); if (!CM_IsEmpty(msg, eMsgSubject)) jptr->subj = strdup(msg->cm_fields[eMsgSubject]); if (!CM_IsEmpty(msg, emessageId)) jptr->msgn = strdup(msg->cm_fields[emessageId]); jptr->rfc822 = SmashStrBuf(&saved_rfc822_version); /* Add to the queue */ begin_critical_section(S_JOURNAL_QUEUE); jptr->next = jnlq; jnlq = jptr; end_critical_section(S_JOURNAL_QUEUE); }
/* * Poll room for incoming chat messages */ void roomchat_poll(char *argbuf) { int newer_than = 0; struct chatmsg *found = NULL; struct chatmsg *ptr = NULL; newer_than = extract_int(argbuf, 1); if ((CC->cs_flags & CS_CHAT) == 0) { cprintf("%d Session is not in chat mode.\n", ERROR); return; } begin_critical_section(S_CHATQUEUE); for (ptr = first_chat_msg; ((ptr != NULL) && (found == NULL)); ptr = ptr->next) { if ((ptr->seq > newer_than) && (ptr->roomnum == CC->room.QRnumber)) { found = ptr; } } end_critical_section(S_CHATQUEUE); if (found == NULL) { cprintf("%d no messages\n", ERROR + MESSAGE_NOT_FOUND); return; } cprintf("%d %d|%ld|%s\n", LISTING_FOLLOWS, found->seq, found->timestamp, found->sender); cprintf("%s\n", found->msgtext); cprintf("000\n"); }
void popup_time_out_check(int curr_sec) { int i; // Check only every two minutes or so if (popup_time_out_check_last + 120 < curr_sec) { popup_time_out_check_last = curr_sec; for (i=0;i<MAX_POPUPS;i++) { if (pw[i].popup_message_dialog!=NULL) { if ((sec_now()-pw[i].sec_opened)>MAX_POPUPS_TIME) { XtPopdown(pw[i].popup_message_dialog); begin_critical_section(&popup_message_dialog_lock, "popup_gui.c:popup_time_out_check" ); XtDestroyWidget(pw[i].popup_message_dialog); pw[i].popup_message_dialog = (Widget)NULL; pw[i].popup_message_data = (Widget)NULL; end_critical_section(&popup_message_dialog_lock, "popup_gui.c:popup_time_out_check" ); } } } } }
/* * Request client termination */ void cmd_reqt(char *argbuf) { struct CitContext *ccptr; int sessions = 0; int which_session; struct ExpressMessage *newmsg; if (CtdlAccessCheck(ac_aide)) return; which_session = extract_int(argbuf, 0); begin_critical_section(S_SESSION_TABLE); for (ccptr = ContextList; ccptr != NULL; ccptr = ccptr->next) { if ((ccptr->cs_pid == which_session) || (which_session == 0)) { newmsg = (struct ExpressMessage *) malloc(sizeof (struct ExpressMessage)); memset(newmsg, 0, sizeof (struct ExpressMessage)); time(&(newmsg->timestamp)); safestrncpy(newmsg->sender, CC->user.fullname, sizeof newmsg->sender); newmsg->flags |= EM_GO_AWAY; newmsg->text = strdup("Automatic logoff requested."); add_xmsg_to_context(ccptr, newmsg); ++sessions; } } end_critical_section(S_SESSION_TABLE); cprintf("%d Sent termination request to %d sessions.\n", CIT_OK, sessions); }
/* * Retrieve instant messages */ void cmd_gexp(char *argbuf) { struct ExpressMessage *ptr; if (CC->FirstExpressMessage == NULL) { cprintf("%d No instant messages waiting.\n", ERROR + MESSAGE_NOT_FOUND); return; } begin_critical_section(S_SESSION_TABLE); ptr = CC->FirstExpressMessage; CC->FirstExpressMessage = CC->FirstExpressMessage->next; end_critical_section(S_SESSION_TABLE); cprintf("%d %d|%ld|%d|%s|%s|%s\n", LISTING_FOLLOWS, ((ptr->next != NULL) ? 1 : 0), /* more msgs? */ (long)ptr->timestamp, /* time sent */ ptr->flags, /* flags */ ptr->sender, /* sender of msg */ config.c_nodename, /* static for now (and possibly deprecated) */ ptr->sender_email /* email or jid of sender */ ); if (ptr->text != NULL) { memfmout(ptr->text, "\n"); free(ptr->text); } cprintf("000\n"); free(ptr); }
/* * CtdlGetCurrentMessageNumber() - Obtain the current highest message number in the system * This provides a quick way to initialise a variable that might be used to indicate * messages that should not be processed. EG. a new Sieve script will use this * to record determine that messages older than this should not be processed. */ long CtdlGetCurrentMessageNumber(void) { long retval = 0L; begin_critical_section(S_CONTROL); get_control(); retval = CitControl.MMhighest; end_critical_section(S_CONTROL); return(retval); }
/* * get_new_message_number() - Obtain a new, unique ID to be used for a message. */ long get_new_message_number(void) { long retval = 0L; begin_critical_section(S_CONTROL); get_control(); retval = ++CitControl.MMhighest; put_control(); end_critical_section(S_CONTROL); return(retval); }
/* * get_new_room_number() - Obtain a new, unique ID to be used for a room. */ long get_new_room_number(void) { long retval = 0L; begin_critical_section(S_CONTROL); get_control(); retval = ++CitControl.MMnextroom; put_control(); end_critical_section(S_CONTROL); return(retval); }
void Download_trail_destroy_shell( /*@unused@*/ Widget widget, XtPointer clientData, /*@unused@*/ XtPointer callData) { Widget shell = (Widget) clientData; XtPopdown(shell); begin_critical_section(&download_findu_dialog_lock, "track_gui.c:Download_trail_destroy_shell" ); XtDestroyWidget(shell); download_findu_dialog = (Widget)NULL; end_critical_section(&download_findu_dialog_lock, "track_gui.c:Download_trail_destroy_shell" ); }
/* * This is the back end to the instant message sending function. * Returns the number of users to which the message was sent. * Sending a zero-length message tests for recipients without sending messages. */ int send_instant_message(char *lun, char *lem, char *x_user, char *x_msg) { int message_sent = 0; /* number of successful sends */ struct CitContext *ccptr; struct ExpressMessage *newmsg = NULL; char *un; int do_send = 0; /* 1 = send message; 0 = only check for valid recipient */ static int serial_number = 0; /* this keeps messages from getting logged twice */ if (strlen(x_msg) > 0) { do_send = 1; } /* find the target user's context and append the message */ begin_critical_section(S_SESSION_TABLE); ++serial_number; for (ccptr = ContextList; ccptr != NULL; ccptr = ccptr->next) { if (ccptr->fake_username[0]) { un = ccptr->fake_username; } else { un = ccptr->user.fullname; } if ( ((!strcasecmp(un, x_user)) || (!strcasecmp(x_user, "broadcast"))) && (ccptr->can_receive_im) && ((ccptr->disable_exp == 0) || (CC->user.axlevel >= AxAideU)) ) { if (do_send) { newmsg = (struct ExpressMessage *) malloc(sizeof (struct ExpressMessage)); memset(newmsg, 0, sizeof (struct ExpressMessage)); time(&(newmsg->timestamp)); safestrncpy(newmsg->sender, lun, sizeof newmsg->sender); safestrncpy(newmsg->sender_email, lem, sizeof newmsg->sender_email); if (!strcasecmp(x_user, "broadcast")) { newmsg->flags |= EM_BROADCAST; } newmsg->text = strdup(x_msg); add_xmsg_to_context(ccptr, newmsg); /* and log it ... */ if (ccptr != CC) { log_instant_message(CC, ccptr, newmsg->text, serial_number); } } ++message_sent; } } end_critical_section(S_SESSION_TABLE); return (message_sent); }
void track_station_destroy_shell( /*@unused@*/ Widget widget, XtPointer clientData, /*@unused@*/ XtPointer callData) { Widget shell = (Widget) clientData; XtPopdown(shell); begin_critical_section(&track_station_dialog_lock, "track_gui.c:track_station_destroy_shell" ); XtDestroyWidget(shell); track_station_dialog = (Widget)NULL; end_critical_section(&track_station_dialog_lock, "track_gui.c:track_station_destroy_shell" ); }
/* * Delete any remaining instant messages */ void delete_instant_messages(void) { struct ExpressMessage *ptr; begin_critical_section(S_SESSION_TABLE); while (CC->FirstExpressMessage != NULL) { ptr = CC->FirstExpressMessage->next; if (CC->FirstExpressMessage->text != NULL) free(CC->FirstExpressMessage->text); free(CC->FirstExpressMessage); CC->FirstExpressMessage = ptr; } end_critical_section(S_SESSION_TABLE); }
/* * Run the queue. */ void JournalRunQueue(void) { struct jnlq *jptr = NULL; while (jnlq != NULL) { begin_critical_section(S_JOURNAL_QUEUE); if (jnlq != NULL) { jptr = jnlq; jnlq = jnlq->next; } end_critical_section(S_JOURNAL_QUEUE); JournalRunQueueMsg(jptr); } }
void CtdlDisableHouseKeeping(void) { int ActiveBackgroundJobs; int do_housekeeping_now = 0; struct CitContext *nptr; int nContexts, i; retry_block_housekeeping: syslog(LOG_INFO, "trying to disable housekeeping services"); begin_critical_section(S_HOUSEKEEPING); if (housekeeping_in_progress == 0) { do_housekeeping_now = 1; housekeeping_in_progress = 1; } end_critical_section(S_HOUSEKEEPING); if (do_housekeeping_now == 0) { usleep(1000000); goto retry_block_housekeeping; } syslog(LOG_INFO, "checking for running server Jobs"); retry_wait_for_contexts: /* So that we don't keep the context list locked for a long time * we create a copy of it first */ ActiveBackgroundJobs = 0; nptr = CtdlGetContextArray(&nContexts) ; if (nptr) { for (i=0; i<nContexts; i++) { if ((nptr[i].state != CON_SYS) || (nptr[i].IO == NULL) || (nptr[i].lastcmd == 0)) continue; ActiveBackgroundJobs ++; syslog(LOG_INFO, "Job CC[%d] active; use TERM if you don't want to wait for it",nptr[i].cs_pid); } free(nptr); } if (ActiveBackgroundJobs != 0) { syslog(LOG_INFO, "found %d running jobs, need to wait", ActiveBackgroundJobs); usleep(5000000); goto retry_wait_for_contexts; } syslog(LOG_INFO, "Housekeeping disabled now."); }
void clear_popup_message_windows(void) { int i; begin_critical_section(&popup_message_dialog_lock, "popup_gui.c:clear_popup_message_windows" ); for (i=0;i<MAX_POPUPS;i++) { pw[i].popup_message_dialog=(Widget)NULL; pw[i].popup_message_data=(Widget)NULL; } end_critical_section(&popup_message_dialog_lock, "popup_gui.c:clear_popup_message_windows" ); pwb.popup_message_dialog=(Widget)NULL; pwb.popup_message_data=(Widget)NULL; }
static void popup_message_destroy_shell(/*@unused@*/ Widget w, XtPointer clientData, /*@unused@*/ XtPointer callData) { int i; i=atoi((char *)clientData); XtPopdown(pw[i].popup_message_dialog); begin_critical_section(&popup_message_dialog_lock, "popup_gui.c:popup_message_destroy_shell" ); XtDestroyWidget(pw[i].popup_message_dialog); pw[i].popup_message_dialog = (Widget)NULL; pw[i].popup_message_data = (Widget)NULL; end_critical_section(&popup_message_dialog_lock, "popup_gui.c:popup_message_destroy_shell" ); }
/* * Check the size of our thread pool. If all threads are executing, spawn another. */ void check_thread_pool_size(void) { if (time_to_die) return; /* don't expand the thread pool during shutdown */ begin_critical_section(S_SPAWNER); /* only one of these should run at a time */ if ( (num_threads_executing >= num_threads_existing) && (num_threads_existing < MAX_WORKER_THREADS) ) { syslog(LOG_DEBUG, "%d of %d threads are executing. Adding another worker thread.", num_threads_executing, num_threads_existing ); spawn_another_worker_thread(); } end_critical_section(S_SPAWNER); }
/* * Periodically called for housekeeping. Expire old chat messages so they don't take up memory forever. */ void roomchat_timer(void) { struct chatmsg *ptr; begin_critical_section(S_CHATQUEUE); while ((first_chat_msg != NULL) && ((time(NULL) - first_chat_msg->timestamp) > 300)) { ptr = first_chat_msg->next; free(first_chat_msg->sender); free(first_chat_msg->msgtext); free(first_chat_msg); first_chat_msg = ptr; if (first_chat_msg == NULL) { last_chat_msg = NULL; } } end_critical_section(S_CHATQUEUE); }
void clear_outgoing_messages(void) { int i; for (i=0;i<MAX_OUTGOING_MESSAGES;i++) clear_outgoing_message(i); begin_critical_section(&send_message_dialog_lock, "messages.c:clear_outgoing_messages" ); /* clear message send buttons */ for (i=0;i<MAX_MESSAGE_WINDOWS;i++) { /* find station */ // if (mw[i].send_message_dialog!=NULL) /* clear submit */ // XtSetSensitive(mw[i].button_ok,TRUE); } end_critical_section(&send_message_dialog_lock, "messages.c:clear_outgoing_messages" ); }
/* * Get Next Unregistered User */ void cmd_gnur(char *argbuf) { struct cdbdata *cdbus; struct ctdluser usbuf; if (CtdlAccessCheck(ac_aide)) { return; } if ((CtdlGetConfigInt("MMflags") & MM_VALID) == 0) { cprintf("%d There are no unvalidated users.\n", CIT_OK); return; } /* There are unvalidated users. Traverse the user database, * and return the first user we find that needs validation. */ cdb_rewind(CDB_USERS); while (cdbus = cdb_next_item(CDB_USERS), cdbus != NULL) { memset(&usbuf, 0, sizeof(struct ctdluser)); memcpy(&usbuf, cdbus->ptr, ((cdbus->len > sizeof(struct ctdluser)) ? sizeof(struct ctdluser) : cdbus->len)); cdb_free(cdbus); if ((usbuf.flags & US_NEEDVALID) && (usbuf.axlevel > AxDeleted)) { cprintf("%d %s\n", MORE_DATA, usbuf.fullname); cdb_close_cursor(CDB_USERS); return; } } /* If we get to this point, there are no more unvalidated users. * Therefore we clear the "users need validation" flag. */ begin_critical_section(S_CONTROL); int flags; flags = CtdlGetConfigInt("MMflags"); flags = flags & (~MM_VALID); CtdlSetConfigInt("MMflags", flags); end_critical_section(S_CONTROL); cprintf("%d *** End of registration.\n", CIT_OK); }
void All_messages_destroy_shell( /*@unused@*/ Widget widget, XtPointer clientData, /*@unused@*/ XtPointer callData) { Widget shell = (Widget) clientData; char *temp_ptr; temp_ptr = XmTextFieldGetString(vm_dist_data); vm_range = atoi(temp_ptr); XtFree(temp_ptr); XtPopdown(shell); begin_critical_section(&All_messages_dialog_lock, "view_message_gui.c:All_messages_destroy_shell" ); XtDestroyWidget(shell); All_messages_dialog = (Widget)NULL; end_critical_section(&All_messages_dialog_lock, "view_message_gui.c:All_messages_destroy_shell" ); }
/* * Add a message into the chat queue */ void add_to_chat_queue(char *msg) { static int seq = 0; struct chatmsg *m = malloc(sizeof(struct chatmsg)); if (!m) return; m->next = NULL; m->timestamp = time(NULL); m->roomnum = CC->room.QRnumber; m->sender = strdup(CC->user.fullname); m->msgtext = strdup(msg); if ((m->sender == NULL) || (m->msgtext == NULL)) { free(m->sender); free(m->msgtext); free(m); return; } begin_critical_section(S_CHATQUEUE); m->seq = ++seq; if (first_chat_msg == NULL) { assert(last_chat_msg == NULL); first_chat_msg = m; last_chat_msg = m; } else { assert(last_chat_msg != NULL); assert(last_chat_msg->next == NULL); last_chat_msg->next = m; last_chat_msg = m; } end_critical_section(S_CHATQUEUE); }
void Download_findu_trail( /*@unused@*/ Widget w, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer callData) { static Widget pane, my_form, button_ok, button_cancel, call, sep; Atom delw; XmString x_str; if (!download_findu_dialog) { begin_critical_section(&download_findu_dialog_lock, "track_gui.c:Download_findu_trail" ); download_findu_dialog = XtVaCreatePopupShell(langcode("WPUPTSP007"), xmDialogShellWidgetClass, appshell, XmNdeleteResponse,XmDESTROY, XmNdefaultPosition, FALSE, XmNfontList, fontlist1, NULL); pane = XtVaCreateWidget("Download_findu_trail pane", xmPanedWindowWidgetClass, download_findu_dialog, MY_FOREGROUND_COLOR, MY_BACKGROUND_COLOR, NULL); my_form = XtVaCreateWidget("Download_findu_trail my_form", xmFormWidgetClass, pane, XmNfractionBase, 2, XmNautoUnmanage, FALSE, XmNshadowThickness, 1, MY_FOREGROUND_COLOR, MY_BACKGROUND_COLOR, NULL); call = XtVaCreateManagedWidget(langcode("WPUPTSP008"), xmLabelWidgetClass, my_form, XmNtopAttachment, XmATTACH_FORM, XmNtopOffset, 10, XmNbottomAttachment, XmATTACH_NONE, XmNleftAttachment, XmATTACH_FORM, XmNleftOffset, 10, XmNrightAttachment, XmATTACH_NONE, MY_FOREGROUND_COLOR, MY_BACKGROUND_COLOR, XmNfontList, fontlist1, NULL); download_trail_station_data = XtVaCreateManagedWidget("download_trail_station_data", xmTextFieldWidgetClass, my_form, XmNeditable, TRUE, XmNcursorPositionVisible, TRUE, XmNsensitive, TRUE, XmNshadowThickness, 1, XmNcolumns, 15, XmNwidth, ((15*7)+2), XmNmaxLength, 15, XmNbackground, colors[0x0f], XmNtopAttachment,XmATTACH_FORM, XmNtopOffset, 5, XmNbottomAttachment,XmATTACH_NONE, XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, call, XmNleftOffset, 10, XmNrightAttachment,XmATTACH_NONE, XmNnavigationType, XmTAB_GROUP, XmNtraversalOn, TRUE, XmNfontList, fontlist1, NULL); x_str = XmStringCreateLocalized(langcode("WPUPTSP009")); posit_start_value = XtVaCreateManagedWidget("Start of Trail (hrs ago)", xmScaleWidgetClass, my_form, XmNtopAttachment,XmATTACH_WIDGET, XmNtopWidget, call, XmNtopOffset, 15, XmNbottomAttachment,XmATTACH_NONE, XmNleftAttachment, XmATTACH_FORM, XmNleftOffset, 10, XmNrightAttachment,XmATTACH_NONE, XmNnavigationType, XmTAB_GROUP, XmNtraversalOn, TRUE, //XmNwidth, 190, XmNrightAttachment, XmATTACH_FORM, XmNrightOffset, 10, XmNsensitive, TRUE, XmNorientation, XmHORIZONTAL, XmNborderWidth, 1, XmNminimum, 1, XmNmaximum, MAX_FINDU_START_TIME, XmNshowValue, TRUE, XmNvalue, posit_start, // Note: Some versions of OpenMotif (distributed with Fedora, // perhaps others) don't work properly with XtVaTypedArg() as used // here, instead showing blank labels for the Scale widgets. // XtVaTypedArg, XmNtitleString, XmRString, langcode("WPUPTSP009"), 22, XmNtitleString, x_str, MY_FOREGROUND_COLOR, MY_BACKGROUND_COLOR, XmNfontList, fontlist1, NULL); XmStringFree(x_str); x_str = XmStringCreateLocalized(langcode("WPUPTSP010")); posit_length_value = XtVaCreateManagedWidget("Length of trail (hrs)", xmScaleWidgetClass, my_form, XmNtopAttachment,XmATTACH_WIDGET, XmNtopWidget, posit_start_value, XmNtopOffset, 15, XmNbottomAttachment,XmATTACH_NONE, XmNleftAttachment, XmATTACH_FORM, XmNleftOffset, 10, XmNrightAttachment,XmATTACH_NONE, XmNnavigationType, XmTAB_GROUP, XmNtraversalOn, TRUE, //XmNwidth, 190, XmNrightAttachment, XmATTACH_FORM, XmNrightOffset, 10, XmNsensitive, TRUE, XmNorientation, XmHORIZONTAL, XmNborderWidth, 1, XmNminimum, 1, XmNmaximum, MAX_FINDU_DURATION, XmNshowValue, TRUE, XmNvalue, posit_length, // Note: Some versions of OpenMotif (distributed with Fedora, // perhaps others) don't work properly with XtVaTypedArg() as used // here, instead showing blank labels for the Scale widgets. // XtVaTypedArg, XmNtitleString, XmRString, langcode("WPUPTSP010"), 19, XmNtitleString, x_str, MY_FOREGROUND_COLOR, MY_BACKGROUND_COLOR, XmNfontList, fontlist1, NULL); XmStringFree(x_str); sep = XtVaCreateManagedWidget("Download_findu_trail sep", xmSeparatorGadgetClass, my_form, XmNorientation, XmHORIZONTAL, XmNtopAttachment,XmATTACH_WIDGET, XmNtopWidget,posit_length_value, XmNtopOffset, 10, XmNbottomAttachment,XmATTACH_NONE, XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment,XmATTACH_FORM, MY_FOREGROUND_COLOR, MY_BACKGROUND_COLOR, XmNfontList, fontlist1, NULL); button_ok = XtVaCreateManagedWidget(langcode("WPUPTSP007"), xmPushButtonGadgetClass, my_form, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, sep, XmNtopOffset, 5, XmNbottomAttachment, XmATTACH_FORM, XmNbottomOffset, 5, XmNleftAttachment, XmATTACH_POSITION, XmNleftPosition, 0, XmNleftOffset, 5, XmNrightAttachment, XmATTACH_POSITION, XmNrightPosition, 1, XmNnavigationType, XmTAB_GROUP, XmNtraversalOn, TRUE, MY_FOREGROUND_COLOR, MY_BACKGROUND_COLOR, XmNfontList, fontlist1, NULL); if (fetching_findu_trail_now) XtSetSensitive(button_ok, FALSE); button_cancel = XtVaCreateManagedWidget(langcode("UNIOP00002"), xmPushButtonGadgetClass, my_form, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, sep, XmNtopOffset, 5, XmNbottomAttachment, XmATTACH_FORM, XmNbottomOffset, 5, XmNleftAttachment, XmATTACH_POSITION, XmNleftPosition, 1, XmNrightAttachment, XmATTACH_POSITION, XmNrightPosition, 2, XmNrightOffset, 5, XmNnavigationType, XmTAB_GROUP, XmNtraversalOn, TRUE, MY_FOREGROUND_COLOR, MY_BACKGROUND_COLOR, XmNfontList, fontlist1, NULL); XtAddCallback(button_ok, XmNactivateCallback, Download_trail_now, download_findu_dialog); XtAddCallback(button_cancel, XmNactivateCallback, Download_trail_destroy_shell, download_findu_dialog); XtAddCallback(posit_start_value, XmNvalueChangedCallback, Reset_posit_length_max, download_findu_dialog); pos_dialog(download_findu_dialog); delw = XmInternAtom(XtDisplay(download_findu_dialog),"WM_DELETE_WINDOW", FALSE); XmAddWMProtocolCallback(download_findu_dialog, delw, Download_trail_destroy_shell, (XtPointer)download_findu_dialog); XmTextFieldSetString(download_trail_station_data,download_trail_station_call); XtManageChild(my_form); XtManageChild(pane); end_critical_section(&download_findu_dialog_lock, "track_gui.c:Download_trail" ); XtPopup(download_findu_dialog,XtGrabNone); fix_dialog_size(download_findu_dialog); // Move focus to the Cancel button. This appears to highlight the // button fine, but we're not able to hit the <Enter> key to // have that default function happen. Note: We _can_ hit the // <SPACE> key, and that activates the option. // XmUpdateDisplay(download_findu_dialog); XmProcessTraversal(button_cancel, XmTRAVERSE_CURRENT); } else (void)XRaiseWindow(XtDisplay(download_findu_dialog), XtWindow(download_findu_dialog)); }
void Track_station( /*@unused@*/ Widget w, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer callData) { static Widget pane, my_form, button_ok, button_close, button_clear, call, sep; Atom delw; if (!track_station_dialog) { begin_critical_section(&track_station_dialog_lock, "track_gui.c:Track_station" ); track_station_dialog = XtVaCreatePopupShell(langcode("WPUPTSP001"), xmDialogShellWidgetClass, appshell, XmNdeleteResponse, XmDESTROY, XmNdefaultPosition, FALSE, XmNfontList, fontlist1, NULL); pane = XtVaCreateWidget("Track_station pane", xmPanedWindowWidgetClass, track_station_dialog, MY_FOREGROUND_COLOR, MY_BACKGROUND_COLOR, NULL); my_form = XtVaCreateWidget("Track_station my_form", xmFormWidgetClass, pane, XmNfractionBase, 3, XmNautoUnmanage, FALSE, XmNshadowThickness, 1, MY_FOREGROUND_COLOR, MY_BACKGROUND_COLOR, NULL); call = XtVaCreateManagedWidget(langcode("WPUPTSP002"), xmLabelWidgetClass, my_form, XmNtopAttachment, XmATTACH_FORM, XmNtopOffset, 10, XmNbottomAttachment, XmATTACH_NONE, XmNleftAttachment, XmATTACH_FORM, XmNleftOffset, 10, XmNrightAttachment, XmATTACH_NONE, MY_FOREGROUND_COLOR, MY_BACKGROUND_COLOR, XmNfontList, fontlist1, NULL); track_station_data = XtVaCreateManagedWidget("Track_station track locate data", xmTextFieldWidgetClass, my_form, XmNeditable, TRUE, XmNcursorPositionVisible, TRUE, XmNsensitive, TRUE, XmNshadowThickness, 1, XmNcolumns, 15, XmNwidth, ((15*7)+2), XmNmaxLength, 15, XmNbackground, colors[0x0f], XmNtopAttachment,XmATTACH_FORM, XmNtopOffset, 5, XmNbottomAttachment,XmATTACH_NONE, XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, call, XmNleftOffset, 10, XmNrightAttachment,XmATTACH_NONE, XmNnavigationType, XmTAB_GROUP, XmNtraversalOn, TRUE, XmNfontList, fontlist1, NULL); track_case_data = XtVaCreateManagedWidget(langcode("WPUPTSP003"), xmToggleButtonWidgetClass, my_form, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, call, XmNtopOffset, 20, XmNbottomAttachment, XmATTACH_NONE, XmNleftAttachment, XmATTACH_FORM, XmNleftOffset ,10, XmNrightAttachment, XmATTACH_NONE, XmNnavigationType, XmTAB_GROUP, XmNtraversalOn, TRUE, MY_FOREGROUND_COLOR, MY_BACKGROUND_COLOR, XmNfontList, fontlist1, NULL); track_match_data = XtVaCreateManagedWidget(langcode("WPUPTSP004"), xmToggleButtonWidgetClass, my_form, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, call, XmNtopOffset, 20, XmNbottomAttachment, XmATTACH_NONE, XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget,track_case_data, XmNrightOffset ,20, XmNrightAttachment, XmATTACH_NONE, XmNnavigationType, XmTAB_GROUP, XmNtraversalOn, TRUE, MY_FOREGROUND_COLOR, MY_BACKGROUND_COLOR, XmNfontList, fontlist1, NULL); sep = XtVaCreateManagedWidget("Track_station sep", xmSeparatorGadgetClass, my_form, XmNorientation, XmHORIZONTAL, XmNtopAttachment,XmATTACH_WIDGET, XmNtopWidget,track_case_data, XmNtopOffset, 10, XmNbottomAttachment,XmATTACH_NONE, XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment,XmATTACH_FORM, MY_FOREGROUND_COLOR, MY_BACKGROUND_COLOR, XmNfontList, fontlist1, NULL); button_ok = XtVaCreateManagedWidget(langcode("WPUPTSP005"), xmPushButtonGadgetClass, my_form, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, sep, XmNtopOffset, 5, XmNbottomAttachment, XmATTACH_FORM, XmNbottomOffset, 5, XmNleftAttachment, XmATTACH_POSITION, XmNleftPosition, 0, XmNleftOffset, 5, XmNrightAttachment, XmATTACH_POSITION, XmNrightPosition, 1, XmNnavigationType, XmTAB_GROUP, XmNtraversalOn, TRUE, MY_FOREGROUND_COLOR, MY_BACKGROUND_COLOR, XmNfontList, fontlist1, NULL); button_clear = XtVaCreateManagedWidget(langcode("WPUPTSP006"), xmPushButtonGadgetClass, my_form, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, sep, XmNtopOffset, 5, XmNbottomAttachment, XmATTACH_FORM, XmNbottomOffset, 5, XmNleftAttachment, XmATTACH_POSITION, XmNleftPosition, 1, XmNrightAttachment, XmATTACH_POSITION, XmNrightPosition, 2, XmNnavigationType, XmTAB_GROUP, XmNtraversalOn, TRUE, MY_FOREGROUND_COLOR, MY_BACKGROUND_COLOR, XmNfontList, fontlist1, NULL); button_close = XtVaCreateManagedWidget(langcode("UNIOP00003"), xmPushButtonGadgetClass, my_form, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, sep, XmNtopOffset, 5, XmNbottomAttachment, XmATTACH_FORM, XmNbottomOffset, 5, XmNleftAttachment, XmATTACH_POSITION, XmNleftPosition, 2, XmNrightAttachment, XmATTACH_POSITION, XmNrightPosition, 3, XmNrightOffset, 5, XmNnavigationType, XmTAB_GROUP, XmNtraversalOn, TRUE, MY_FOREGROUND_COLOR, MY_BACKGROUND_COLOR, XmNfontList, fontlist1, NULL); XtAddCallback(button_ok, XmNactivateCallback, Track_station_now, track_station_dialog); XtAddCallback(button_close, XmNactivateCallback, track_station_destroy_shell, track_station_dialog); XtAddCallback(button_clear, XmNactivateCallback, Track_station_clear, track_station_dialog); XmToggleButtonSetState(track_case_data,FALSE,FALSE); XmToggleButtonSetState(track_match_data,TRUE,FALSE); pos_dialog(track_station_dialog); delw = XmInternAtom(XtDisplay(track_station_dialog),"WM_DELETE_WINDOW", FALSE); XmAddWMProtocolCallback(track_station_dialog, delw, track_station_destroy_shell, (XtPointer)track_station_dialog); // if (track_station_on==1) XmTextFieldSetString(track_station_data,tracking_station_call); XtManageChild(my_form); XtManageChild(pane); end_critical_section(&track_station_dialog_lock, "track_gui.c:Track_station" ); XtPopup(track_station_dialog,XtGrabNone); fix_dialog_size(track_station_dialog); // Move focus to the Cancel button. This appears to highlight the // button fine, but we're not able to hit the <Enter> key to // have that default function happen. Note: We _can_ hit the // <SPACE> key, and that activates the option. // XmUpdateDisplay(track_station_dialog); XmProcessTraversal(button_close, XmTRAVERSE_CURRENT); } else (void)XRaiseWindow(XtDisplay(track_station_dialog), XtWindow(track_station_dialog)); }
// Adds a message to the outgoing message queue. Doesn't actually // cause a transmit. "check_and_transmit_messages()" is the // function which actually gets things moving. // // We also stuff the message into the main message queue so that the // queued messages will appear in the Send Message box. // void output_message(char *from, char *to, char *message, char *path) { int ok,i,j; char message_out[MAX_MESSAGE_OUTPUT_LENGTH+1+5+1]; // +'{' +msg_id +terminator int last_space, message_ptr, space_loc; int wait_on_first_ack; int error; long record; //fprintf(stderr,"output_message:%s\n", message); message_ptr=0; last_space=0; ok=0; error=0; if (debug_level & 2) fprintf(stderr,"Output Message from <%s> to <%s>\n",from,to); // Repeat until we process the entire message. We'll process it // a chunk at a time, size of chunk to correspond to max APRS // message line length. // while (!error && (message_ptr < (int)strlen(message))) { ok=0; space_loc=0; // Break a long message into smaller chunks that can be // processed into APRS messages. Break at a space character // if possible. // for (j=0; j<MAX_MESSAGE_OUTPUT_LENGTH; j++) { if(message[j+message_ptr] != '\0') { if(message[j+message_ptr]==' ') { last_space=j+message_ptr+1; space_loc=j; } if (j!=MAX_MESSAGE_OUTPUT_LENGTH) { message_out[j]=message[j+message_ptr]; message_out[j+1] = '\0'; } else { if(space_loc!=0) message_out[space_loc] = '\0'; else last_space=j+message_ptr; } } else { j=MAX_MESSAGE_OUTPUT_LENGTH+1; last_space=strlen(message)+1; } } //fprintf(stderr,"message_out: %s\n", message_out); if (debug_level & 2) fprintf(stderr,"MESSAGE <%s> %d %d\n",message_out,message_ptr,last_space); if (j >= MAX_MESSAGE_OUTPUT_LENGTH) { message_ptr = MAX_MESSAGE_OUTPUT_LENGTH; } else { message_ptr=last_space; } /* check for others in the queue */ wait_on_first_ack=0; for (i=0; i<MAX_OUTGOING_MESSAGES; i++) { if (message_pool[i].active == MESSAGE_ACTIVE && strcmp(to, message_pool[i].to_call_sign) == 0 && strcmp(from, "***") != 0) { wait_on_first_ack=1; i=MAX_OUTGOING_MESSAGES+1; // Done with loop } } for (i=0; i<MAX_OUTGOING_MESSAGES && !ok ;i++) { /* Check for clear position*/ if (message_pool[i].active==MESSAGE_CLEAR) { /* found a spot */ ok=1; // Increment the message sequence ID variable if (bump_message_counter(message_counter)) fprintf(stderr, "!WARNING!: Wrap around Message Counter"); // Note that Xastir's messaging can lock up if we do a rollover and // have unacked messages on each side of the rollover. This is due // to the logic in db.c that looks for the lowest numbered unacked // message. We get stuck on both sides of the fence at once. To // avoid this condition we could reduce the compare number (8100) to // a smaller value, and only roll over when there are no unacked // messages? Another way to do it would be to write a "0" to the // config file if we're more than 1000 when we quit Xastir? That // would probably be easier. It's still possible to get to 8100 // messages during one runtime though. Unlikely, but possible. message_pool[i].active = MESSAGE_ACTIVE; message_pool[i].wait_on_first_ack = wait_on_first_ack; xastir_snprintf(message_pool[i].to_call_sign, sizeof(message_pool[i].to_call_sign), "%s", to); xastir_snprintf(message_pool[i].from_call_sign, sizeof(message_pool[i].from_call_sign), "%s", from); xastir_snprintf(message_pool[i].message_line, sizeof(message_pool[i].message_line), "%s", message_out); if (path != NULL) xastir_snprintf(message_pool[i].path, sizeof(message_pool[i].path), "%s", path); else message_pool[i].path[0] = '\0'; // // We compute the base-90 sequence number here // // This allows it to range from "!!" to "zz" // xastir_snprintf(message_pool[i].seq, // sizeof(message_pool[i].seq), // "%c%c", // (char)(((message_counter / 90) % 90) + 33), // (char)((message_counter % 90) + 33)); xastir_snprintf(message_pool[i].seq, sizeof(message_pool[i].seq), "%c%c", message_counter[0], message_counter[1]); message_pool[i].active_time=0; message_pool[i].next_time = (time_t)7l; if (strcmp(from,"***")!= 0) message_pool[i].tries = 0; else message_pool[i].tries = MAX_TRIES-1; // Cause the message to get added to the main // message queue as well, with the proper sequence // number, so queued messages will appear in the // Send Message box as unacked messages. // // We must get rid of the lock we already have for a moment, as // update_messages(), which is called by msg_data_add(), also snags // this lock. end_critical_section(&send_message_dialog_lock, "db.c:update_messages" ); (void)msg_data_add(to, from, message_out, message_pool[i].seq, MESSAGE_MESSAGE, 'L', // From the Local system &record); /* fprintf(stderr,"msg_data_add %s %s %s %s\n", to, from, message_out, message_pool[i].seq); */ // Regain the lock we had before begin_critical_section(&send_message_dialog_lock, "db.c:update_messages" ); } } if(!ok) { fprintf(stderr,"Output message queue is full!\n"); error=1; } } }
// What we wish to do here: Check for an active Send Message dialog // that contains the callsign of interest. If one doesn't exist, // create one and pop it up. We don't want to do this for duplicate // message lines or duplicate acks for any particular QSO. To do so // would cause the Send Message dialog to pop up on every such // received message, which is VERY annoying (that was the default in // Xastir for years, and nobody liked it!). // int check_popup_window(char *from_call_sign, int group) { int i,found,j,ret; char temp1[MAX_CALLSIGN+1]; char *temp_ptr; //fprintf(stderr,"\tcheck_popup_window()\n"); ret = -1; found = -1; begin_critical_section(&send_message_dialog_lock, "messages.c:check_popup_window" ); // Check for an already-created dialog for talking to this // particular call_sign. // for (i = 0; i < MAX_MESSAGE_WINDOWS; i++) { if (mw[i].send_message_dialog != NULL) { // If dialog created temp_ptr = XmTextFieldGetString(mw[i].send_message_call_data); xastir_snprintf(temp1, sizeof(temp1), "%s", temp_ptr); XtFree(temp_ptr); /*fprintf(stderr,"Looking at call <%s> for <%s>\n",temp1,from_call_sign);*/ if (strcasecmp(temp1, from_call_sign) == 0) { // Found a call_sign match in a Send Message dialog! //fprintf(stderr,"\tFound a Send_message dialog match\n"); found = i; break; } } } end_critical_section(&send_message_dialog_lock, "messages.c:check_popup_window" ); // If found == -1 at this point, we haven't found a Send Message // dialog that contains the call_sign of interest. // if (found == -1 && (group == 2 || group_active(from_call_sign))) { /* no window found Open one! */ //fprintf(stderr,"\tNo Send Message dialog found, creating one\n"); begin_critical_section(&send_message_dialog_lock, "messages.c:check_popup_window2" ); i= -1; for (j=0; j<MAX_MESSAGE_WINDOWS; j++) { if (!mw[j].send_message_dialog) { i=j; break; } } end_critical_section(&send_message_dialog_lock, "messages.c:check_popup_window2" ); if (i!= -1) { if (group == 1) { temp1[0] = '*'; temp1[1] = '\0'; } else { temp1[0] = '\0'; } strncat(temp1, from_call_sign, sizeof(temp1) - 1 - strlen(temp1)); if (!disable_all_popups) { Send_message(appshell, temp1, NULL); } update_messages(1); ret=i; } else { fprintf(stderr,"No open windows!\n"); } } else { /* window open! */ // Pop it up ret=found; } if (found != -1) { // Already have a window XtPopup(mw[i].send_message_dialog,XtGrabNone); } return(ret); }