void Track_station_now(Widget w, XtPointer clientData, XtPointer callData) { char temp[MAX_CALLSIGN+1]; char temp2[200]; int found = 0; char *temp_ptr; temp_ptr = XmTextFieldGetString(track_station_data); xastir_snprintf(temp, sizeof(temp), "%s", temp_ptr); XtFree(temp_ptr); (void)remove_trailing_spaces(temp); (void)remove_trailing_dash_zero(temp); xastir_snprintf(tracking_station_call, sizeof(tracking_station_call), "%s", temp); track_case = (int)XmToggleButtonGetState(track_case_data); track_match = (int)XmToggleButtonGetState(track_match_data); found = locate_station(da, temp, track_case, track_match, 0); if ( valid_object(tracking_station_call) // Name of object is legal || valid_call(tracking_station_call) || valid_item(tracking_station_call ) ) { track_station_on = 1; // Track it whether we've seen it yet or not if (!found) { xastir_snprintf(temp2, sizeof(temp2), langcode("POPEM00026"), temp); popup_message_always(langcode("POPEM00025"),temp2); } // Check for exact match, includes SSID if ( track_me & !is_my_call( tracking_station_call, 1) ) { XmToggleButtonSetState( trackme_button, FALSE, FALSE ); track_me = 0; } } else { tracking_station_call[0] = '\0'; // Empty it out again track_station_on = 0; xastir_snprintf(temp2, sizeof(temp2), langcode("POPEM00002"), temp); popup_message_always(langcode("POPEM00003"),temp2); } track_station_destroy_shell(w, clientData, callData); display_zoom_status(); }
int group_active(char *from) { static struct stat current_group_stat; struct stat group_stat; static char altgroup[10]; char group_data_path[MAX_VALUE]; get_user_base_dir(group_data_file, group_data_path, sizeof(group_data_path)); (void)remove_trailing_spaces(from); // If we cycle to/from special group or file changes, rebuild group list. if ((!stat( group_data_path, &group_stat ) && (current_group_stat.st_size != group_stat.st_size || current_group_stat.st_mtime != group_stat.st_mtime || current_group_stat.st_ctime != group_stat.st_ctime))) { // altgroup equates to "address of altgroup" which always evaluates // as true. Commenting it out of the conditional. --we7u. // || (altgroup && strcasecmp(altgroup, VERSIONFRM))) { group_build_list( group_data_path ); current_group_stat = group_stat; xastir_snprintf(altgroup,sizeof(altgroup),"%s",VERSIONFRM); } if (group_data_list != NULL) // Causes segfault on Solaris 2.5 without this! return (int)(bsearch(from, group_data_list, (size_t)group_data_count, (size_t)10, group_comp) != NULL); else return(0); }
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); }
void jump_sort(void) { char temp[200]; char name[100]; char *temp_ptr; FILE *f; char location_file_path[MAX_VALUE]; char location_db_file_path[MAX_VALUE]; get_user_base_dir("config/locations.sys", location_file_path, sizeof(location_file_path)); get_user_base_dir("data/locations_db.dat", location_db_file_path, sizeof(location_db_file_path)); f=fopen(location_file_path,"r"); if (f!=NULL) { while (!feof(f)) { (void)get_line(f,temp,200); if (!feof(f) && strlen(temp)>8) { temp_ptr=strtok(temp,"|"); /* get the name */ if (temp_ptr!=NULL) { xastir_snprintf(name, sizeof(name), "%s", temp); (void)sort_input_database(location_db_file_path,name,200); } } } (void)fclose(f); } else fprintf(stderr,"Couldn't open file: %s\n", location_file_path ); }
/* * xastir_curl_init - create curl session with common options */ CURL *xastir_curl_init(char *errBuf) { CURL *mySession; char agent_string[15]; mySession = curl_easy_init(); if (mySession != NULL) { if (debug_level & 8192) { curl_easy_setopt(mySession, CURLOPT_VERBOSE, 1); } else { curl_easy_setopt(mySession, CURLOPT_VERBOSE, 0); } curl_easy_setopt(mySession, CURLOPT_ERRORBUFFER, errBuf); xastir_snprintf(agent_string, sizeof(agent_string),"Xastir"); curl_easy_setopt(mySession, CURLOPT_USERAGENT, agent_string); // write function curl_easy_setopt(mySession, CURLOPT_WRITEFUNCTION, curl_fwrite); curl_easy_setopt(mySession, CURLOPT_TIMEOUT, (long)net_map_timeout); curl_easy_setopt(mySession, CURLOPT_CONNECTTIMEOUT, (long)(net_map_timeout/2)); // Added in libcurl 7.9.8 #if (LIBCURL_VERSION_NUM >= 0x070908) curl_easy_setopt(mySession, CURLOPT_NETRC, CURL_NETRC_OPTIONAL); #endif // LIBCURL_VERSION_NUM // Added in libcurl 7.10.6 #if (LIBCURL_VERSION_NUM >= 0x071006) curl_easy_setopt(mySession, CURLOPT_HTTPAUTH, CURLAUTH_ANY); #endif // LIBCURL_VERSION_NUM // Added in libcurl 7.10.7 #if (LIBCURL_VERSION_NUM >= 0x071007) curl_easy_setopt(mySession, CURLOPT_PROXYAUTH, CURLAUTH_ANY); #endif // LIBCURL_VERSION_NUM // Added in libcurl 7.10 #if (LIBCURL_VERSION_NUM >= 0x070a00) // This prevents a segfault for the case where we get a timeout on // domain name lookup. It has to do with the ALARM signal // and siglongjmp(), which we use in hostname.c already. // This URL talks about it a bit more, plus see the libcurl // docs: // // http://curl.haxx.se/mail/lib-2002-12/0103.html // curl_easy_setopt(mySession, CURLOPT_NOSIGNAL, 1); #endif // LIBCURL_VERSION_NUM } return(mySession); } // xastir_curl_init()
pid_t play_sound(char *sound_cmd, char *soundfile) { pid_t sound_pid; char command[600]; sound_pid=0; if (strlen(sound_cmd)>3 && strlen(soundfile)>1) { if (last_sound_pid==0) { // Create a new process to run in sound_pid = fork(); if (sound_pid!=-1) { if(sound_pid==0) { // This is the child process // Go back to default signal handler instead of // calling restart() on SIGHUP (void) signal(SIGHUP,SIG_DFL); // Change the name of the new child process. So // far this only works for "ps" listings, not // for "top". This code only works on Linux. // For BSD use setproctitle(3), NetBSD can use // setprogname(2). #ifdef __linux__ init_set_proc_title(my_argc, my_argv, my_envp); set_proc_title("%s", "festival process (xastir)"); //fprintf(stderr,"DEBUG: %s\n", Argv[0]); #endif // __linux__ xastir_snprintf(command, sizeof(command), "%s %s/%s", sound_cmd, SOUND_DIR, soundfile); if (system(command) != 0) {} // We don't care whether it succeeded exit(0); // Exits only this process, not Xastir itself } else { // This is the parent process last_sound_pid=sound_pid; } } else fprintf(stderr,"Error! trying to play sound\n"); } else { sound_pid=last_sound_pid; /*fprintf(stderr,"Sound already running\n");*/ } } return(sound_pid); }
// Change path on all pending transmit messages that are from us and // to the callsign listed. // void change_path_outgoing_messages_to(char *callsign, char *new_path) { int ii; char my_callsign[20]; //fprintf(stderr, // "Changing all outgoing msgs to %s to new path: %s\n", // callsign, // new_path); xastir_snprintf(my_callsign, sizeof(my_callsign), "%s", callsign); remove_trailing_spaces(my_callsign); // Run through the entire outgoing message queue for (ii = 0; ii < MAX_OUTGOING_MESSAGES; ii++) { if (message_pool[ii].active == MESSAGE_ACTIVE) { //fprintf(stderr,"\t'%s'\n\t'%s'\n", // message_pool[ii].to_call_sign, // my_callsign); // If it matches the callsign we're talking to if (strcasecmp(message_pool[ii].to_call_sign,my_callsign) == 0) { //fprintf(stderr,"\tFound an outgoing queued msg to change path on.\n"); xastir_snprintf(message_pool[ii].path, sizeof(message_pool[ii].path), "%s", new_path); } } } }
void track_gui_init(void) { init_critical_section( &track_station_dialog_lock ); init_critical_section( &download_findu_dialog_lock ); if (temp_tracking_station_call[0] != '\0') { xastir_snprintf(tracking_station_call, sizeof(tracking_station_call), "%s", temp_tracking_station_call); track_station_on = 1; } else { tracking_station_call[0] = '\0'; } }
// Function to compute checksums for NMEA sentences // // Input: "$............*" // Output: Two character string containing the checksum // // Checksum is computed from the '$' to the '*', but not including // these two characters. It is an 8-bit Xor of the characters // specified, encoded in hexadecimal format. // char *nmea_checksum(char *nmea_sentence) { int i; int sum = 0; int right; int left; char convert[17] = "0123456789ABCDEF"; for (i = 1; i < ((int)strlen(nmea_sentence) - 1); i++) { sum = sum ^ nmea_sentence[i]; } right = sum % 16; left = (sum / 16) % 16; xastir_snprintf(checksum, sizeof(checksum), "%c%c", convert[left], convert[right]); return(checksum); }
// Function which will send an NMEA sentence to a Garmin GPS which // will create a waypoint if the Garmin is set to NMEA-in/NMEA-out // mode. The sentence looks like this: // // $GPWPL,4807.038,N,01131.000,E,WPTNME*31 // // $GPWPL,4849.65,N,06428.53,W,0001*54 // $GPWPL,4849.70,N,06428.50,W,0002*50 // // 4807.038,N Latitude // 01131.000,E Longitude // WPTNME Waypoint Name (stick to 6 chars for compatibility?) // *31 Checksum, always begins with '*' // // // Future implementation ideas: // // Create linked list of waypoints/location. // Use the list to prevent multiple writes of the same waypoint if // nothing has changed. // // Use the list to check distance of previously-written waypoints. // If we're out of range, delete the waypoint and remove it from the // list. // // Perhaps write the list to disk also. As we shut down, delete the // waypoints (self-cleaning). As we come up, load them in again? // We could also just continue cleaning out waypoints that are // out-of-range since the last time we ran the program. That's // probably a better solution. // void create_garmin_waypoint(long latitude,long longitude,char *call_sign) { char short_callsign[10]; char lat_string[15]; char long_string[15]; char lat_char; char long_char; int i,j,len; char out_string[80]; char out_string2[80]; convert_lat_l2s(latitude, lat_string, sizeof(lat_string), CONVERT_HP_NOSP); lat_char = lat_string[strlen(lat_string) - 1]; lat_string[strlen(lat_string) - 1] = '\0'; convert_lon_l2s(longitude, long_string, sizeof(long_string), CONVERT_HP_NOSP); long_char = long_string[strlen(long_string) - 1]; long_string[strlen(long_string) - 1] = '\0'; len = strlen(call_sign); if (len > 9) len = 9; j = 0; for (i = 0; i <= len; i++) { // Copy the '\0' as well if (call_sign[i] != '-') { // We don't want the dash short_callsign[j++] = call_sign[i]; } } short_callsign[6] = '\0'; // Truncate at 6 chars // Convert to upper case. Garmin's don't seem to like lower // case waypoint names to_upper(short_callsign); //fprintf(stderr,"Creating waypoint for %s:%s\n",call_sign,short_callsign); xastir_snprintf(out_string, sizeof(out_string), "$GPWPL,%s,%c,%s,%c,%s*", lat_string, lat_char, long_string, long_char, short_callsign); nmea_checksum(out_string); xastir_snprintf(out_string2, sizeof(out_string2), "%s%s", out_string, checksum); output_waypoint_data(out_string2); //fprintf(stderr,"%s\n",out_string2); }
// 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); }
/* * fetch_remote_file * Returns: 0 If file retrieved * 1 If there was a problem getting the file */ int fetch_remote_file(char *fileimg, char *local_filename) { #ifdef HAVE_LIBCURL CURL *curl; CURLcode res; char curlerr[CURL_ERROR_SIZE]; struct FtpFile ftpfile; //fprintf(stderr, "Fetching remote file: %s\n", fileimg); curl = xastir_curl_init(curlerr); if (curl) { // download from fileimg curl_easy_setopt(curl, CURLOPT_URL, fileimg); ftpfile.filename = local_filename; ftpfile.stream = NULL; curl_easy_setopt(curl, CURLOPT_FILE, &ftpfile); res = curl_easy_perform(curl); curl_easy_cleanup(curl); if (CURLE_OK != res) { fprintf(stderr, "curl told us %d\n", res); fprintf(stderr, "curlerr: %s\n", curlerr); fprintf(stderr, "Perhaps a timeout? Try increasing \"Internet Map Timout\".\n"); } if (ftpfile.stream) fclose(ftpfile.stream); // Return error-code if we had trouble if (CURLE_OK != res) { return(1); } } else { fprintf(stderr,"Couldn't download the file %s\n", fileimg); fprintf(stderr, "Perhaps a timeout? Try increasing \"Internet Map Timout\".\n"); return(1); } return(0); // Success! #else // HAVE_LIBCURL #ifdef HAVE_WGET char tempfile[500]; //"%s --server-response --timestamping --user-agent=Xastir --tries=1 --timeout=%d --output-document=%s \'%s\' 2> /dev/null\n", xastir_snprintf(tempfile, sizeof(tempfile), "%s --server-response --user-agent=Xastir --tries=1 --timeout=%d --output-document=%s \'%s\' 2> /dev/null\n", WGET_PATH, net_map_timeout, local_filename, fileimg); if (debug_level & 2) fprintf(stderr,"%s",tempfile); if ( system(tempfile) ) { // Go get the file fprintf(stderr,"Couldn't download the file\n"); fprintf(stderr, "Perhaps a timeout? Try increasing \"Internet Map Timout\".\n"); return(1); } return(0); // Success! #else // HAVE_WGET fprintf(stderr,"libcurl or 'wget' not installed. Can't download file\n"); return(1); #endif // HAVE_WGET #endif // HAVE_LIBCURL }
void all_messages(char from, char *call_sign, char *from_call, char *message) { char temp_my_course[10]; char *temp; char data1[97]; char data2[97]; int pos; int i; int my_size = 200; XmTextPosition drop_ptr; if (Read_messages_mine_only || (!Read_messages_mine_only && ((vm_range == 0) || ((int)distance_from_my_station(call_sign,temp_my_course) <= vm_range)) ) ) { // Check that it's coming from the correct type of interface // Compare Read_messages_packet_data_type against the port // type associated with data_port to determine whether or // not to display it. // // I = Internet // L = Local // T = TNC // F = File // switch (Read_messages_packet_data_type) { case 2: // Display NET data only // if not network_interface, return if (from != 'I') return; // Don't display it break; case 1: // Display TNC data only // if not local_tnc_interface, return if (from != 'T') return; // Don't display it break; case 0: // Display both TNC and NET data default: break; } // Check for my stations only if set if (Read_messages_mine_only) { char short_call[MAX_CALLSIGN]; char *p; xastir_snprintf(short_call, sizeof(short_call), "%s", my_callsign); if ( (p = index(short_call,'-')) ) { *p = '\0'; // Terminate it } if (!strstr(call_sign, short_call) && !strstr(from_call, short_call)) { return; } } if ((temp = malloc((size_t)my_size)) == NULL) return; if (strlen(message)>95) { xastir_snprintf(data1, sizeof(data1), "%s", message); data1[95]='\0'; xastir_snprintf(data2, sizeof(data2), "\n\t%s", message+95); } else { xastir_snprintf(data1, sizeof(data1), "%s", message); data2[0] = '\0'; } if (strncmp(call_sign, "java",4) == 0) { xastir_snprintf(call_sign, MAX_CALLSIGN+1, "%s", langcode("WPUPMSB015") ); // Broadcast xastir_snprintf(temp, my_size, "%s %s\t%s%s\n", from_call, call_sign, data1, data2); } else if (strncmp(call_sign, "USER", 4) == 0) { xastir_snprintf(call_sign, MAX_CALLSIGN+1, "%s", langcode("WPUPMSB015") ); // Broadcast xastir_snprintf(temp, my_size, "%s %s\t%s%s\n", from_call, call_sign, data1, data2); } else xastir_snprintf(temp, my_size, "%s to %s via:%c\t%s%s\n", from_call, call_sign, from, data1, data2); if ((All_messages_dialog != NULL)) { begin_critical_section(&All_messages_dialog_lock, "view_message_gui.c:all_messages" ); pos = (int)XmTextGetLastPosition(view_messages_text); XmTextInsert(view_messages_text, pos, temp); pos += strlen(temp); while (pos > view_message_limit) { for (drop_ptr = i = 0; i < 3; i++) { (void)XmTextFindString(view_messages_text, drop_ptr, "\n", XmTEXT_FORWARD, &drop_ptr); drop_ptr++; } XmTextReplace(view_messages_text, 0, drop_ptr, ""); pos = (int)XmTextGetLastPosition(view_messages_text); } XtVaSetValues(view_messages_text, XmNcursorPosition, pos, NULL); XmTextShowPosition(view_messages_text, pos); end_critical_section(&All_messages_dialog_lock, "view_message_gui.c:all_messages" ); } free(temp); } }
// Function which marks a message as ack'ed in the transmit queue // and releases the next message to allow it to be transmitted. // Handles REPLY-ACK format or normal ACK format just fine. // void clear_acked_message(char *from, char *to, char *seq) { int i,ii; int found; char lowest[3]; char temp1[MAX_CALLSIGN+1]; char *temp_ptr; char msg_id[5+1]; // Copy seq into local variable xastir_snprintf(msg_id, sizeof(msg_id), "%s", seq); // Check for REPLY-ACK protocol. If found, terminate at the end // of the first ack. temp_ptr = strchr(msg_id, '}'); if (temp_ptr) *temp_ptr = '\0'; (void)remove_trailing_spaces(msg_id); // This is IMPORTANT here!!! //lowest=100000; // Highest Base-90 2-char string xastir_snprintf(lowest,sizeof(lowest),"zz"); found= -1; for (i=0; i<MAX_OUTGOING_MESSAGES;i++) { if (message_pool[i].active==MESSAGE_ACTIVE) { if (debug_level & 1) fprintf(stderr, "TO <%s> <%s> from <%s> <%s> seq <%s> <%s>\n", to, message_pool[i].to_call_sign, from, message_pool[i].from_call_sign, msg_id, message_pool[i].seq); if (strcmp(message_pool[i].to_call_sign,from)==0) { if (debug_level & 1) fprintf(stderr,"Matched message to_call_sign\n"); if (strcmp(message_pool[i].from_call_sign,to)==0) { if (debug_level & 1) fprintf(stderr,"Matched message from_call_sign\n"); if (strcmp(message_pool[i].seq,msg_id)==0) { if (debug_level & 2) fprintf(stderr,"Found and cleared\n"); clear_outgoing_message(i); // now find and release next message, look for the lowest sequence? // What about when the sequence rolls over? for (i=0; i<MAX_OUTGOING_MESSAGES;i++) { if (message_pool[i].active==MESSAGE_ACTIVE) { if (strcmp(message_pool[i].to_call_sign,from)==0) { // Need to change this to a string compare instead of an integer // compare. We are using base-90 encoding now. //if (atoi(message_pool[i].seq)<lowest) { if (strncmp(message_pool[i].seq,lowest,2) < 0) { //lowest=atoi(message_pool[i].seq); xastir_snprintf(lowest, sizeof(lowest), "%s", message_pool[i].seq); found=i; } } } } // Release the next message in the queue for transmission if (found!= -1) { message_pool[found].wait_on_first_ack=0; } else { /* if no more clear the send button */ begin_critical_section(&send_message_dialog_lock, "messages.c:clear_acked_message" ); for (ii=0;ii<MAX_MESSAGE_WINDOWS;ii++) { /* find station */ if (mw[ii].send_message_dialog!=NULL) { temp_ptr = XmTextFieldGetString(mw[ii].send_message_call_data); xastir_snprintf(temp1, sizeof(temp1), "%s", temp_ptr); XtFree(temp_ptr); (void)to_upper(temp1); //fprintf(stderr,"%s\t%s\n",temp1,from); // if (strcmp(temp1,from)==0) { /*clear submit*/ // XtSetSensitive(mw[ii].button_ok,TRUE); // } } } end_critical_section(&send_message_dialog_lock, "messages.c:clear_acked_message" ); } } else { if (debug_level & 1) fprintf(stderr,"Sequences didn't match: %s %s\n",message_pool[i].seq,msg_id); } } } } } }
void view_message_print_record(Message *m_fill) { int pos; char *temp; int i; int my_size = 200; char temp_my_course[10]; XmTextPosition drop_ptr; int distance; // Make sure it's within our distance range we have set distance = (int)distance_from_my_station(m_fill->from_call_sign,temp_my_course); if (Read_messages_mine_only || (!Read_messages_mine_only && ( (vm_range == 0) || (distance <= vm_range) ) ) ) { // Check that it's coming from the correct type of interface // Compare Read_messages_packet_data_type against the port // type associated with data_port to determine whether or // not to display it. // // I = Internet // L = Local // T = TNC // F = File // switch (Read_messages_packet_data_type) { case 2: // Display NET data only // if not network_interface, return if (m_fill->data_via != 'I') return; // Don't display it break; case 1: // Display TNC data only // if not local_tnc_interface, return if (m_fill->data_via != 'T') return; // Don't display it break; case 0: // Display both TNC and NET data default: break; } // Check for my stations only if set if (Read_messages_mine_only) { char short_call[MAX_CALLSIGN]; char *p; xastir_snprintf(short_call, sizeof(short_call), "%s", my_callsign); if ( (p = index(short_call,'-')) ) { *p = '\0'; // Terminate it } if (!strstr(m_fill->call_sign, short_call) && !strstr(m_fill->from_call_sign, short_call)) { return; } } if ((temp = malloc((size_t)my_size)) == NULL) return; sprintf(temp,"%-9s>%-9s %s:%5s %s:%c :%s\n", m_fill->from_call_sign, m_fill->call_sign, langcode("WPUPMSB013"), m_fill->seq, langcode("WPUPMSB014"), m_fill->type, m_fill->message_line); pos = (int)XmTextGetLastPosition(view_messages_text); XmTextInsert(view_messages_text, pos, temp); pos += strlen(temp); while (pos > view_message_limit) { for (drop_ptr = i = 0; i < 3; i++) { (void)XmTextFindString(view_messages_text, drop_ptr, "\n", XmTEXT_FORWARD, &drop_ptr); drop_ptr++; } XmTextReplace(view_messages_text, 0, drop_ptr, ""); pos = (int)XmTextGetLastPosition(view_messages_text); } XtVaSetValues(view_messages_text, XmNcursorPosition, pos, NULL); free(temp); } }
// // Note that the length of "gps_line_data" can be up to // MAX_DEVICE_BUFFER, which is currently set to 4096. // int gps_data_find(char *gps_line_data, int port) { char long_pos[20],lat_pos[20],aunit[2]; time_t t; char temp_str[MAX_GPS_STRING+1]; int have_valid_string = 0; #ifndef __CYGWIN__ struct timeval tv; struct timezone tz; #endif // __CYGWIN__ if (strncmp(gps_line_data,"$GPRMC,",7)==0) { if (debug_level & 128) { char filtered_data[MAX_LINE_SIZE+1]; xastir_snprintf(filtered_data, sizeof(filtered_data), "%s", gps_line_data); makePrintable(filtered_data); fprintf(stderr,"Got RMC %s\n", filtered_data); } if (debug_level & 128) { // Got GPS RMC String statusline(langcode("BBARSTA015"),0); } xastir_snprintf(gps_gprmc, sizeof(gps_gprmc), "%s", gps_line_data); xastir_snprintf(temp_str, sizeof(temp_str), "%s", gps_gprmc); // decode_gps_rmc is destructive to its first parameter if (decode_gps_rmc( temp_str, long_pos, sizeof(long_pos), lat_pos, sizeof(lat_pos), gps_spd, gps_sunit, sizeof(gps_sunit), gps_cse, &t, &gps_valid ) == 1) { // mod station data // got GPS data have_valid_string++; if (debug_level & 128) fprintf(stderr,"RMC <%s> <%s><%s> %c <%s>\n", long_pos,lat_pos,gps_spd,gps_sunit[0],gps_cse); if (debug_level & 128) { fprintf(stderr,"Checking for Time Set on %d (%d)\n", port, devices[port].set_time); } // Don't set the time if it's a Cygwin system. Causes problems with // date, plus time can be an hour off if daylight savings time is // enabled on Windows. // #ifndef __CYGWIN__ if (devices[port].set_time) { tv.tv_sec=t; tv.tv_usec=0; tz.tz_minuteswest=0; tz.tz_dsttime=0; if (debug_level & 128) { fprintf(stderr,"Setting Time %ld EUID: %d, RUID: %d\n", (long)t, (int)getuid(), (int)getuid()); } #ifdef HAVE_SETTIMEOFDAY ENABLE_SETUID_PRIVILEGE; settimeofday(&tv, &tz); DISABLE_SETUID_PRIVILEGE; #endif // HAVE_SETTIMEOFDAY } #endif // __CYGWIN__ } } else { if (debug_level & 128) { int i; fprintf(stderr,"Not $GPRMC: "); for (i = 0; i<7; i++) fprintf(stderr,"%c", gps_line_data[i]); fprintf(stderr,"\n"); } } if (strncmp(gps_line_data,"$GPGGA,",7)==0) { if (debug_level & 128) { char filtered_data[MAX_LINE_SIZE+1]; xastir_snprintf(filtered_data, sizeof(filtered_data), "%s", gps_line_data); makePrintable(filtered_data); fprintf(stderr,"Got GGA %s\n", filtered_data); } if (debug_level & 128) { // Got GPS GGA String statusline(langcode("BBARSTA016"),0); } xastir_snprintf(gps_gpgga, sizeof(gps_gpgga), "%s", gps_line_data); xastir_snprintf(temp_str, sizeof(temp_str), "%s", gps_gpgga); // decode_gps_gga is destructive to its first parameter if ( decode_gps_gga( temp_str, long_pos, sizeof(long_pos), lat_pos, sizeof(lat_pos), gps_sats, gps_alt, aunit, &gps_valid ) == 1) { // mod station data // got GPS data have_valid_string++; if (debug_level & 128) fprintf(stderr,"GGA <%s> <%s> <%s> <%s> %c\n", long_pos,lat_pos,gps_sats,gps_alt,aunit[0]); } } else { if (debug_level & 128) { int i; fprintf(stderr,"Not $GPGGA: "); for (i = 0; i<7; i++) fprintf(stderr,"%c",gps_line_data[i]); fprintf(stderr,"\n"); } } if (have_valid_string) { if (debug_level & 128) { statusline(langcode("BBARSTA037"),0); } // Go update my screen position my_station_gps_change(long_pos,lat_pos,gps_cse,gps_spd, gps_sunit[0],gps_alt,gps_sats); // gps_stop_now is how we tell main.c that we've got a valid GPS string. // Only useful for HSP mode? if (!gps_stop_now) gps_stop_now=1; // If HSP port, shutdown gps for timed interval if (port_data[port].device_type == DEVICE_SERIAL_TNC_HSP_GPS) { // return dtr to normal port_dtr(port,0); } } return(have_valid_string); }
void check_delayed_transmit_queue(int curr_sec) { delayed_ack_record_p ptr = delayed_ack_list_head; int active_records = 0; // Skip this function if we did it during this second already. if (delayed_transmit_last_check == curr_sec) { return; } delayed_transmit_last_check = curr_sec; //fprintf(stderr, "Checking delayed TX queue for something to transmit.\n"); //fprintf(stderr, "."); // Run down the linked list checking every record. while (ptr != NULL) { if (ptr->active_time != 0) { // Active record char new_path[MAX_LINE_SIZE+1]; //fprintf(stderr, "Found active record\n"); active_records++; // Check for a custom path having been set in the Send // Message dialog. If so, use this for our outgoing // path instead and reset all of the queued message // paths to this station to this new path. // get_send_message_path(ptr->to_call_sign, new_path, sizeof(new_path)); if (new_path[0] != '\0' && strcmp(new_path, ptr->path) != 0) { // We have a custom path set which is different than // the path saved with the outgoing message. Change // the path to match the new path. // //fprintf(stderr, // "Changing queued ack's to new path: %s\n", // new_path); xastir_snprintf(ptr->path, sizeof(ptr->path), "%s", new_path); } if (ptr->active_time <= sec_now()) { // Transmit it //fprintf(stderr,"Found something delayed to transmit! %ld\n",sec_now()); if (ptr->path[0] == '\0') { transmit_message_data(ptr->to_call_sign, ptr->message_line, NULL); } else { transmit_message_data(ptr->to_call_sign, ptr->message_line, ptr->path); } ptr->active_time = (time_t)0; } } ptr = ptr->next; } // Check if entire list contains inactive records. If so, // delete the list. // if (!active_records && (delayed_ack_list_head != NULL)) { // No active records, but the list isn't empty. Reclaim the // records in the list. while (delayed_ack_list_head != NULL) { ptr = delayed_ack_list_head->next; free(delayed_ack_list_head); //fprintf(stderr,"Free'ing delayed_ack record\n"); delayed_ack_list_head = ptr; } } }
void get_tiger_local_file(char * local_filename, char * fileimg){ #ifdef HAVE_MAGICK // char local_filename[MAX_FILENAME]; // char fileimg[MAX_FILENAME]; // Ascii name of image file, read from GEO file time_t query_start_time, query_end_time; #ifdef USE_MAP_CACHE int map_cache_return = 1; // Default = cache miss char *cache_file_id; #endif // USE_MAP_CACHE char temp_file_path[MAX_VALUE]; if (debug_level & 512) { query_start_time=time(&query_start_time); } #ifdef USE_MAP_CACHE if (!map_cache_fetch_disable) { // Delete old copy from the cache if (map_cache_fetch_disable && fileimg[0] != '\0') { if (map_cache_del(fileimg)) { if (debug_level & 512) { fprintf(stderr,"Couldn't delete old map from cache\n"); } } } set_dangerous("map_tiger: map_cache_get"); map_cache_return = map_cache_get(fileimg,local_filename); clear_dangerous(); } if (debug_level & 512) { fprintf(stderr,"map_cache_return: <%d> bytes returned: %d\n", map_cache_return, (int) strlen(local_filename)); } if (map_cache_return != 0 ) { set_dangerous("map_tiger: map_cache_fileid"); cache_file_id = map_cache_fileid(); xastir_snprintf(local_filename, MAX_FILENAME, // hardcoded to avoid sizeof() "%s/map_%s.%s", get_user_base_dir("map_cache", temp_file_path, sizeof(temp_file_path)), cache_file_id, "gif"); free(cache_file_id); clear_dangerous(); #else // USE_MAP_CACHE xastir_snprintf(local_filename, MAX_FILENAME, // hardcoded to avoid sizeof() "%s/map.%s", get_user_base_dir("tmp", temp_file_path, sizeof(temp_file_path)), "gif"); #endif // USE_MAP_CACHE // Erase any previously existing local file by the same name. // This avoids the problem of having an old map image here and // the code trying to display it when the download fails. unlink( local_filename ); if (fetch_remote_file(fileimg, local_filename)) { // Had trouble getting the file. Abort. return; } // For debugging the MagickError/MagickWarning segfaults. //system("cat /dev/null >/var/tmp/xastir_hacker_map.gif"); #ifdef USE_MAP_CACHE set_dangerous("map_tiger: map_cache_put"); map_cache_put(fileimg,local_filename); clear_dangerous(); } // end if is cached DHBROWN #endif // MAP_CACHE if (debug_level & 512) { fprintf (stderr, "Fetch or query took %d seconds\n", (int) (time(&query_end_time) - query_start_time)); } // Set permissions on the file so that any user can overwrite it. chmod(local_filename, 0666); #endif //HAVE_MAGICK } // end get_tiger_local_file
void Download_trail_now(Widget w, XtPointer clientData, XtPointer callData) { char temp[MAX_CALLSIGN+1]; static char fileimg[400]; static char log_filename[200]; char *temp_ptr; pthread_t download_trail_thread; static XtPointer download_client_data = NULL; char tmp_base_dir[MAX_VALUE]; get_user_base_dir("tmp",tmp_base_dir, sizeof(tmp_base_dir)); // If we're already fetching a trail, we shouldn't be calling // this callback function. Get out. if (fetching_findu_trail_now) return; // Pass two parameters to findu_transfer_thread via a struct track_ptrs.download_client_ptrs[0] = log_filename; track_ptrs.download_client_ptrs[1] = fileimg; download_client_data = &track_ptrs; // Check whether it's ok to do a download currently. if (read_file) { // No, we're already in the middle of reading in some file. // Skip trying to download yet another file. fprintf(stderr,"Processing another file. Wait a bit, then try again\n"); popup_message_always(langcode("POPEM00035"), langcode("POPEM00041")); return; } // busy_cursor(appshell); xastir_snprintf(log_filename, sizeof(log_filename), "%s/map.log", tmp_base_dir); // Erase any previously existing local file by the same name. // This avoids the problem of having an old tracklog here and // the code trying to display it when the download fails. unlink( log_filename ); XmScaleGetValue(posit_start_value , &posit_start); XmScaleGetValue(posit_length_value , &posit_length); temp_ptr = XmTextFieldGetString(download_trail_station_data); xastir_snprintf(temp, sizeof(temp), "%s", temp_ptr); XtFree(temp_ptr); (void)remove_trailing_spaces(temp); (void)remove_trailing_dash_zero(temp); xastir_snprintf(download_trail_station_call, sizeof(download_trail_station_call), "%s", temp); //Download_trail_destroy_shell(w, clientData, callData); // New URL's for findu. The second one looks very promising. //http://www.findu.com/cgi-bin/raw.cgi?call=k4hg-8&time=1 //http://www.findu.com/cgi-bin/rawposit.cgi?call=k4hg-8&time=1 // // The last adds this to the beginning of the line: // // "20030619235323," // // which is a date/timestamp. We'll need to do some extra stuff // here in order to actually use that date/timestamp though. // Setting the read_file_ptr to the downloaded file won't do it. // "http://www.findu.com/cgi-bin/rawposit.cgi?call=%s&start=%d&length=%d&time=1", // New, with timestamp xastir_snprintf(fileimg, sizeof(fileimg), // // Posits only: // "http://www.findu.com/cgi-bin/rawposit.cgi?call=%s&start=%d&length=%d", // // Posits plus timestamps (we can't handle timestamps yet): // "http://www.findu.com/cgi-bin/rawposit.cgi?call=%s&start=%d&length=%d&time=1", // New, with timestamp // // Download all packets, not just posits: "http://www.findu.com/cgi-bin/raw.cgi?call=%s&start=%d&length=%d", // download_trail_station_call,posit_start,posit_length); if (debug_level & 1024) { fprintf(stderr, "%s\n", fileimg); } //----- Start New Thread ----- if (pthread_create(&download_trail_thread, NULL, findu_transfer_thread, download_client_data)) { fprintf(stderr,"Error creating findu transfer thread\n"); } else { // We're off and running with the new thread! } display_zoom_status(); Download_trail_destroy_shell(w, clientData, callData); }
void location_view(/*@unused@*/ Widget w, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer callData) { int i,x; char *location; XmString *list; int found,done; FILE *f; char temp[200]; char name[100]; char pos[100]; char *temp_ptr; char s_lat[20]; char s_long[20]; char s_sz[10]; char location_file_path[MAX_VALUE]; found=0; XtVaGetValues(location_list,XmNitemCount,&i,XmNitems,&list,NULL); for (x=1; x<=i;x++) { if (XmListPosSelected(location_list,x)) { found=1; if (XmStringGetLtoR(list[(x-1)],XmFONTLIST_DEFAULT_TAG,&location)) x=i+1; } } get_user_base_dir("config/locations.sys", location_file_path, sizeof(location_file_path)); if (found) { f=fopen(location_file_path,"r"); if (f!=NULL) { done=0; while (!feof(f) & !done) { (void)get_line(f,temp,200); if (!feof(f) && strlen(temp)>8) { temp_ptr=strtok(temp,"|"); /* get the name */ if (temp_ptr!=NULL) { xastir_snprintf(name, sizeof(name), "%s", temp); temp_ptr=strtok(NULL,"|"); /* get the pos */ xastir_snprintf(pos, sizeof(pos), "%s", temp_ptr); if (strcmp(location,name)==0) { if (3 != sscanf(pos,"%19s %19s %9s", s_lat, s_long, s_sz)) { fprintf(stderr,"location_view:sscanf parsing error\n"); } map_pos(convert_lat_s2l(s_lat),convert_lon_s2l(s_long),atol(s_sz)); done=1; } } } } (void)fclose(f); } else { fprintf(stderr,"Couldn't open file: %s\n", location_file_path ); } XtFree(location); } }
void location_add(/*@unused@*/ Widget w, XtPointer clientData, /*@unused@*/ XtPointer callData) { char name[100]; char s_long[20]; char s_lat[20]; FILE *f, *fout; char temp[200]; char *temp_ptr; Widget my_text = (Widget) clientData; int len,n,found; char location_file_path[MAX_VALUE]; char location_db_path[MAX_VALUE]; get_user_base_dir("config/locations.sys", location_file_path, sizeof(location_file_path)); get_user_base_dir("data/locations_db.dat", location_db_path, sizeof(location_db_path)); temp_ptr = XmTextFieldGetString(my_text); xastir_snprintf(name, sizeof(name), "%s", temp_ptr); XtFree(temp_ptr); (void)remove_trailing_spaces(name); XmTextFieldSetString(my_text,""); /* should check for name used already */ found=0; f=fopen(location_file_path,"r"); if (f!=NULL) { while (!feof(f) && !found) { (void)get_line(f,temp,200); if (!feof(f) && strlen(temp)>8) { temp_ptr=strtok(temp,"|"); /* get the name */ if (temp_ptr!=NULL) { if (strcmp(name,temp)==0) found=1; } } } (void)fclose(f); } else fprintf(stderr,"Couldn't open file: %s\n", location_file_path ); if (!found) { /* delete entire list available */ XmListDeleteAllItems(location_list); len = (int)strlen(name); if (len>0 && len<100){ fout = fopen(location_file_path,"a"); if (fout!=NULL) { convert_lat_l2s(center_latitude, s_lat, sizeof(s_lat), CONVERT_HP_NOSP); convert_lon_l2s(center_longitude, s_long, sizeof(s_long), CONVERT_HP_NOSP); fprintf(fout,"%s|%s %s %ld\n",name,s_lat,s_long,scale_y); (void)fclose(fout); } else fprintf(stderr,"Couldn't open file: %s\n", location_file_path ); } else popup_message_always(langcode("POPEM00022"),langcode("POPEM00023")); /* resort the list and put it back up */ n=1; clear_sort_file(location_db_path); jump_sort(); sort_list(location_db_path,200,location_list,&n); } else popup_message_always(langcode("POPEM00022"),langcode("POPEM00024")); /* dupe name */ }
void location_delete(/*@unused@*/ Widget w, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer callData) { int i,x; char *location; XmString *list; int found,ok; FILE *f,*fout; char temp[200]; char name[100]; char pos[100]; char *temp_ptr; char filen[400]; char filen_bak[400]; char location_file_path[MAX_VALUE]; char location_sys_path[MAX_VALUE]; get_user_base_dir("config/locations.sys", location_file_path, sizeof(location_file_path)); get_user_base_dir("config/locations.sys-tmp", location_sys_path, sizeof(location_sys_path)); found=0; ok=0; XtVaGetValues(location_list,XmNitemCount,&i,XmNitems,&list,NULL); for (x=1; x<=i;x++) { if (XmListPosSelected(location_list,x)) { found=1; if (XmStringGetLtoR(list[(x-1)],XmFONTLIST_DEFAULT_TAG,&location)) { XmListDeletePos(location_list,x); x=i+1; } } } if(found) { f=fopen(location_file_path,"r"); if (f!=NULL) { fout=fopen(location_sys_path,"a"); if (fout!=NULL) { while (!feof(f)) { (void)get_line(f,temp,200); if (!feof(f) && strlen(temp)>8) { temp_ptr=strtok(temp,"|"); /* get the name */ if (temp_ptr!=NULL) { xastir_snprintf(name, sizeof(name), "%s", temp); temp_ptr=strtok(NULL,"|"); /* get the pos */ xastir_snprintf(pos, sizeof(pos), "%s", temp_ptr); if (strcmp(location,name)!=0) { fprintf(fout,"%s|%s\n",name,pos); } } } } (void)fclose(fout); ok=1; } else fprintf(stderr,"Couldn't open file: %s\n", location_sys_path ); (void)fclose(f); } else { fprintf(stderr,"Couldn't open file: %s\n", location_file_path ); } XtFree(location); } if (ok==1){ xastir_snprintf(filen, sizeof(filen), "%s", location_file_path); xastir_snprintf(filen_bak, sizeof(filen_bak), "%s", location_sys_path); (void)unlink(filen); (void)rename(filen_bak,filen); } }
// 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; } } }
void check_and_transmit_messages(time_t time) { int i; char temp[200]; char to_call[40]; // Skip this function if we did it during this second already. if (last_check_and_transmit == time) { return; } last_check_and_transmit = time; for (i=0; i<MAX_OUTGOING_MESSAGES;i++) { if (message_pool[i].active==MESSAGE_ACTIVE) { if (message_pool[i].wait_on_first_ack!=1) { // Tx only if 0 if (message_pool[i].active_time < time) { char *last_ack_ptr; char last_ack[5+1]; if (message_pool[i].tries < MAX_TRIES) { char new_path[MAX_LINE_SIZE+1]; /* sending message let the tnc and net transmits check to see if we should */ if (debug_level & 2) fprintf(stderr, "Time %ld Active time %ld next time %ld\n", (long)time, (long)message_pool[i].active_time, (long)message_pool[i].next_time); if (debug_level & 2) fprintf(stderr,"Send message#%d to <%s> from <%s>:%s-%s\n", message_pool[i].tries, message_pool[i].to_call_sign, message_pool[i].from_call_sign, message_pool[i].message_line, message_pool[i].seq); pad_callsign(to_call,message_pool[i].to_call_sign); // Add Leading ":" as per APRS Spec. // Add trailing '}' to signify that we're // Reply/Ack protocol capable. last_ack_ptr = get_most_recent_ack(to_call); if (last_ack_ptr != NULL) xastir_snprintf(last_ack, sizeof(last_ack), "%s", last_ack_ptr); else last_ack[0] = '\0'; xastir_snprintf(temp, sizeof(temp), ":%s:%s{%s}%s", to_call, message_pool[i].message_line, message_pool[i].seq, last_ack); if (debug_level & 2) fprintf(stderr,"MESSAGE OUT>%s<\n",temp); // Check for a custom path having been set // in the Send Message dialog. If so, use // this for our outgoing path instead and // reset all of the queued message paths to // this station to this new path. // get_send_message_path(to_call, new_path, sizeof(new_path)); //fprintf(stderr,"get_send_message_path(%s) returned: %s\n",to_call,new_path); if (new_path[0] != '\0' && strcmp(new_path,message_pool[i].path) != 0) { // We have a custom path set which is // different than the path saved with // the outgoing message. // // Change all messages to that callsign // to match the new path. // change_path_outgoing_messages_to(to_call,new_path); } // Transmit the message transmit_message_data(message_pool[i].to_call_sign, temp, message_pool[i].path); message_pool[i].active_time = time + message_pool[i].next_time; //fprintf(stderr,"%d\n",(int)message_pool[i].next_time); } /* fprintf(stderr, "Msg Interval = %3ld seconds or %4.1f minutes\n", message_pool[i].next_time, message_pool[i].next_time / 60.0); */ // Record the interval we're using. Put it with // the message in the general message pool, so // that the Send Message dialog can display it. // It will only display it if the message is // actively being transmitted. If it has been // cancelled, timed out, or hasn't made it to // the transmit position yet, it won't be shown. // msg_record_interval_tries(message_pool[i].to_call_sign, message_pool[i].from_call_sign, message_pool[i].seq, message_pool[i].next_time, // Interval message_pool[i].tries); // Tries // Start at 7 seconds for the interval. We set // it to 7 seconds in output_message() above. // Double the interval each retry until we hit // 10 minutes. Keep transmitting at 10 minute // intervals until we hit MAX_TRIES. // Double the interval between messages message_pool[i].next_time = message_pool[i].next_time * 2; // Limit the max interval to 10 minutes if (message_pool[i].next_time > (time_t)600l) message_pool[i].next_time = (time_t)600l; message_pool[i].tries++; // Expire it if we hit the limit if (message_pool[i].tries > MAX_TRIES) { char temp[150]; char temp_to[20]; xastir_snprintf(temp,sizeof(temp),"To: %s, Msg: %s", message_pool[i].to_call_sign, message_pool[i].message_line); //popup_message(langcode("POPEM00004"),langcode("POPEM00017")); popup_message( "Retries Exceeded!", temp ); // Fake the system out: We're pretending // that we got an ACK back from it so that // we can either release the next message to // go out, or at least make the send button // sensitive again. // We need to copy the to_call_sign into // another variable because the // clear_acked_message() function clears out // the message then needs this parameter to // do another compare (to enable the Send Msg // button again). xastir_snprintf(temp_to, sizeof(temp_to), "%s", message_pool[i].to_call_sign); // Record a fake ack and add "*TIMEOUT*" to // the message. This will be displayed in // the Send Message dialog. msg_record_ack(temp_to, message_pool[i].from_call_sign, message_pool[i].seq, 1, // "1" specifies a timeout 0); // Not a cancel clear_acked_message(temp_to, message_pool[i].from_call_sign, message_pool[i].seq); // if (mw[i].send_message_dialog!=NULL) /* clear submit */ // XtSetSensitive(mw[i].button_ok,TRUE); } } } else { if (debug_level & 2) fprintf(stderr,"Message #%s is waiting to have a previous one cleared\n",message_pool[i].seq); } } } }
void transmit_message_data_delayed(char *to, char *message, char *path, time_t when) { delayed_ack_record_p ptr = delayed_ack_list_head; // We need to run down the current list looking for any records // that are identical and within 30 seconds time-wise of this // one. If so, don't allocate a new record. This keeps the // dupes down on transmit so that at the most we transmit one // ack per 30 seconds per QSO, except of course for real-time // ack's which don't go through this function. // Run through the queue and check each record while (ptr != NULL) { if ( strcmp(ptr->to_call_sign,to) == 0 && strcmp(ptr->message_line,message) == 0 ) { // // We have matches on call_sign and message. Check the // time next. // if (abs(when - ptr->active_time) < 30) { // // We're within 30 seconds of an identical ack. // Drop this new one (don't add it). // //fprintf(stderr,"Dropping delayed ack: Too close timewise to another: %s, %s\n", // to, message); return; // Don't allocate new record on queue } } ptr = ptr->next; } // If we made it to here, there aren't any queued ACK's that are // close enough in time to drop this new one. Add it to the // queue. //fprintf(stderr, "Queuing ACK for delayed transmit: %s, %s\n", // to, message); // Allocate a record to hold it ptr = (delayed_ack_record_p)malloc(sizeof(delayed_ack_record)); // Fill in the record xastir_snprintf(ptr->to_call_sign, sizeof(ptr->to_call_sign), "%s", to); xastir_snprintf(ptr->message_line, sizeof(ptr->message_line), "%s", message); if (path == NULL) { ptr->path[0] = '\0'; } else { xastir_snprintf(ptr->path, sizeof(ptr->path), "%s", path); } ptr->active_time = when; // Add the record to the head of the list ptr->next = delayed_ack_list_head; delayed_ack_list_head = ptr; }
void group_build_list(char *filename) { char *ptr; FILE *f; struct stat group_stat; int i; if (group_data_count == group_data_max) { ptr = realloc(group_data_list, (size_t)(group_data_max+10)*10); if (ptr) { group_data_list = ptr; group_data_max += 10; //fprintf(stderr, "group_data_max: %d\n", group_data_max); } else { fprintf(stderr, "Unable to allocate more memory for group_data_list (1)\n"); } } // Make sure we always listen for ourself, XASTIR, & our Version groups xastir_snprintf(&group_data_list[0],10,"%s",my_callsign); xastir_snprintf(&group_data_list[10],10,"XASTIR"); xastir_snprintf(&group_data_list[20],10,"%s",XASTIR_TOCALL); group_data_count = 3; // If we are in special group look for messages. if (altnet) { xastir_snprintf(&group_data_list[group_data_count*10],10,"%s",altnet_call); group_data_count++; } // if (! stat(filename, &group_stat) ) f = fopen(filename, "r"); // File exists else f = fopen(filename, "w+"); // No file. Create it and open it. if (f == NULL) { fprintf(stderr,"Couldn't open file for reading -or- appending: %s\n", filename); return; } while (!feof(f)) { if (group_data_count == group_data_max) { ptr = realloc(group_data_list, (size_t)(group_data_max+10)*10); if (ptr) { group_data_list = ptr; group_data_max += 10; //fprintf(stderr, "group_data_max(2): %d\n", group_data_max); } else { fprintf(stderr, "Unable to allocate more memory for group_data_list (2)\n"); } } if (group_data_count < group_data_max) { group_data_list[group_data_count*10] = '\0'; (void)fgets(&group_data_list[group_data_count*10], 10, f); if ((ptr = strchr(&group_data_list[group_data_count*10], '\n'))) *ptr = '\0'; else while ((i = fgetc(f)) != EOF && i != '\n'); // clean-up after long group name // check for DOS EOL markup! if ((ptr = strchr(&group_data_list[group_data_count*10], '\r'))) *ptr = '\0'; if (group_data_list[group_data_count*10]) group_data_count++; } } (void)fclose(f); qsort(group_data_list, (size_t)group_data_count, 10, group_comp); if (debug_level & 2) { for (i = 0; i < group_data_count; i++) fprintf(stderr,"Group %2d: %s\n", i, &group_data_list[i*10]); } }
void draw_tiger_map (Widget w, char *filenm, int destination_pixmap, int nocache) { // For future implementation of a "refresh cached map" option char file[MAX_FILENAME]; // Complete path/name of image file char short_filenm[MAX_FILENAME]; FILE *f; // Filehandle of image file char fileimg[MAX_FILENAME]; // Ascii name of image file, read from GEO file char tigertmp[MAX_FILENAME*2]; // Used for putting together the tigermap query int width, height; tiepoint tp[2]; // Calibration points for map, read in from .geo file register long map_c_T, map_c_L; // map delta NW edge coordinates, DNN: these should be signed register long tp_c_dx, tp_c_dy; // tiepoint coordinate differences unsigned long c_x_min, c_y_min;// top left coordinates of map inside screen unsigned long c_y_max; // bottom right coordinates of map inside screen double c_x; // Xastir coordinates 1/100 sec, 0 = 180°W double c_y; // Xastir coordinates 1/100 sec, 0 = 90°N long map_y_0; // map pixel pointer prior to TM adjustment register long map_x, map_y; // map pixel pointers, DNN: this was a float, chg to long long map_x_min, map_x_max; // map boundaries for in screen part of map long map_y_min, map_y_max; // long map_x_ctr; // half map width in pixel long map_y_ctr; // half map height in pixel int map_seen = 0; int map_act; int map_done; long map_c_yc; // map center, vert coordinate long map_c_xc; // map center, hor coordinate double map_c_dx, map_c_dy; // map coordinates increment (pixel width) double c_dx; // adjusted map pixel width long scr_x, scr_y; // screen pixel plot positions long scr_xp, scr_yp; // previous screen plot positions int scr_dx, scr_dy; // increments in screen plot positions long scr_x_mc; // map center in screen units long scr_c_xr; long scale_xa; // adjusted for topo maps double scale_x_nm; // nm per Xastir coordinate unit long scale_x0; // at widest map area char local_filename[MAX_FILENAME]; ExceptionInfo exception; Image *image; ImageInfo *image_info; PixelPacket *pixel_pack; PixelPacket temp_pack; IndexPacket *index_pack; int l; XColor my_colors[256]; double left, right, top, bottom, map_width, map_height; double lat_center = 0; double long_center = 0; char map_it[MAX_FILENAME]; char tmpstr[100]; int geo_image_width; // Image width from GEO file int geo_image_height; // Image height from GEO file // initialize this local_filename[0]='\0'; // Create a shorter filename for display (one that fits the // status line more closely). Subtract the length of the // "Indexing " and/or "Loading " strings as well. if (strlen(filenm) > (41 - 9)) { int avail = 41 - 11; int new_len = strlen(filenm) - avail; xastir_snprintf(short_filenm, sizeof(short_filenm), "..%s", &filenm[new_len]); } else { xastir_snprintf(short_filenm, sizeof(short_filenm), "%s", filenm); } xastir_snprintf(map_it, sizeof(map_it), langcode ("BBARSTA028"), short_filenm); statusline(map_it,0); // Loading ... // Check whether we're indexing or drawing the map if ( (destination_pixmap == INDEX_CHECK_TIMESTAMPS) || (destination_pixmap == INDEX_NO_TIMESTAMPS) ) { // We're indexing only. Save the extents in the index. // Force the extents to the edges of the earth for the // index file. index_update_xastir(filenm, // Filename only 64800000l, // Bottom 0l, // Top 0l, // Left 129600000l, // Right 0); // Default Map Level // Update statusline xastir_snprintf(map_it, sizeof(map_it), langcode ("BBARSTA039"), short_filenm); statusline(map_it,0); // Loading/Indexing ... return; // Done indexing this file } // Tiepoint for upper left screen corner // tp[0].img_x = 0; // Pixel Coordinates tp[0].img_y = 0; // Pixel Coordinates tp[0].x_long = NW_corner_longitude; // Xastir Coordinates tp[0].y_lat = NW_corner_latitude; // Xastir Coordinates // Tiepoint for lower right screen corner // tp[1].img_x = screen_width - 1; // Pixel Coordinates tp[1].img_y = screen_height - 1; // Pixel Coordinates tp[1].x_long = SE_corner_longitude; // Xastir Coordinates tp[1].y_lat = SE_corner_latitude; // Xastir Coordinates left = (double)((NW_corner_longitude - 64800000l )/360000.0); // Lat/long Coordinates top = (double)(-((NW_corner_latitude - 32400000l )/360000.0)); // Lat/long Coordinates right = (double)((SE_corner_longitude - 64800000l)/360000.0);//Lat/long Coordinates bottom = (double)(-((SE_corner_latitude - 32400000l)/360000.0));//Lat/long Coordinates map_width = right - left; // Lat/long Coordinates map_height = top - bottom; // Lat/long Coordinates geo_image_width = screen_width; geo_image_height = screen_height; long_center = (left + right)/2.0l; lat_center = (top + bottom)/2.0l; // Example query to the census map server.... /* xastir_snprintf(fileimg, sizeof(fileimg), "\'http://tiger.census.gov/cgi-bin/mapper/map.gif?on=CITIES&on=GRID&on=counties&on=majroads&on=places&&on=interstate&on=states&on=ushwy&on=statehwy&lat=%f\046lon=%f\046wid=%f\046ht=%f\046iwd=%i\046iht=%i\'",\ lat_center, long_center, map_width, map_height, tp[1].img_x + 1, tp[1].img_y + 1); */ xastir_snprintf(tigertmp, sizeof(tigertmp), "http://tiger.census.gov/cgi-bin/mapper/map.gif?"); if (tiger_show_grid) strncat(tigertmp, "&on=GRID", sizeof(tigertmp) - 1 - strlen(tigertmp)); else strncat(tigertmp, "&off=GRID", sizeof(tigertmp) - 1 - strlen(tigertmp)); if (tiger_show_counties) strncat(tigertmp, "&on=counties", sizeof(tigertmp) - 1 - strlen(tigertmp)); else strncat(tigertmp, "&off=counties", sizeof(tigertmp) - 1 - strlen(tigertmp)); if (tiger_show_cities) strncat(tigertmp, "&on=CITIES", sizeof(tigertmp) - 1 - strlen(tigertmp)); else strncat(tigertmp, "&off=CITIES", sizeof(tigertmp) - 1 - strlen(tigertmp)); if (tiger_show_places) strncat(tigertmp, "&on=places", sizeof(tigertmp) - 1 - strlen(tigertmp)); else strncat(tigertmp, "&off=places", sizeof(tigertmp) - 1 - strlen(tigertmp)); if (tiger_show_majroads) strncat(tigertmp, "&on=majroads", sizeof(tigertmp) - 1 - strlen(tigertmp)); else strncat(tigertmp, "&off=majroads", sizeof(tigertmp) - 1 - strlen(tigertmp)); if (tiger_show_streets) strncat(tigertmp, "&on=streets", sizeof(tigertmp) - 1 - strlen(tigertmp)); // Don't turn streets off since this will automagically show up as you zoom in. if (tiger_show_railroad) strncat(tigertmp, "&on=railroad", sizeof(tigertmp) - 1 - strlen(tigertmp)); else strncat(tigertmp, "&off=railroad", sizeof(tigertmp) - 1 - strlen(tigertmp)); if (tiger_show_states) strncat(tigertmp, "&on=states", sizeof(tigertmp) - 1 - strlen(tigertmp)); else strncat(tigertmp, "&off=states", sizeof(tigertmp) - 1 - strlen(tigertmp)); if (tiger_show_interstate) strncat(tigertmp, "&on=interstate", sizeof(tigertmp) - 1 - strlen(tigertmp)); else strncat(tigertmp, "&off=interstate", sizeof(tigertmp) - 1 - strlen(tigertmp)); if (tiger_show_ushwy) strncat(tigertmp, "&on=ushwy", sizeof(tigertmp) - 1 - strlen(tigertmp)); else strncat(tigertmp, "&off=ushwy", sizeof(tigertmp) - 1 - strlen(tigertmp)); if (tiger_show_statehwy) strncat(tigertmp, "&on=statehwy", sizeof(tigertmp) - 1 - strlen(tigertmp)); else strncat(tigertmp, "&off=statehwy", sizeof(tigertmp) - 1 - strlen(tigertmp)); if (tiger_show_water) strncat(tigertmp, "&on=water", sizeof(tigertmp) - 1 - strlen(tigertmp)); else strncat(tigertmp, "&off=water", sizeof(tigertmp) - 1 - strlen(tigertmp)); if (tiger_show_lakes) strncat(tigertmp, "&on=shorelin", sizeof(tigertmp) - 1 - strlen(tigertmp)); else strncat(tigertmp, "&off=shorelin", sizeof(tigertmp) - 1 - strlen(tigertmp)); if (tiger_show_misc) strncat(tigertmp, "&on=miscell", sizeof(tigertmp) - 1 - strlen(tigertmp)); else strncat(tigertmp, "&off=miscell", sizeof(tigertmp) - 1 - strlen(tigertmp)); xastir_snprintf(tmpstr, sizeof(tmpstr), "&lat=%f\046lon=%f\046", lat_center, long_center); strncat (tigertmp, tmpstr, sizeof(tigertmp) - 1 - strlen(tigertmp)); xastir_snprintf(tmpstr, sizeof(tmpstr), "wid=%f\046ht=%f\046", map_width, map_height); strncat (tigertmp, tmpstr, sizeof(tigertmp) - 1 - strlen(tigertmp)); xastir_snprintf(tmpstr, sizeof(tmpstr), "iwd=%i\046iht=%i", tp[1].img_x + 1, tp[1].img_y + 1); strncat (tigertmp, tmpstr, sizeof(tigertmp) - 1 - strlen(tigertmp)); xastir_snprintf(fileimg, sizeof(fileimg), "%s", tigertmp); if (debug_level & 512) { fprintf(stderr,"left side is %f\n", left); fprintf(stderr,"right side is %f\n", right); fprintf(stderr,"top is %f\n", top); fprintf(stderr,"bottom is %f\n", bottom); fprintf(stderr,"lat center is %f\n", lat_center); fprintf(stderr,"long center is %f\n", long_center); fprintf(stderr,"screen width is %li\n", screen_width); fprintf(stderr,"screen height is %li\n", screen_height); fprintf(stderr,"map width is %f\n", map_width); fprintf(stderr,"map height is %f\n", map_height); fprintf(stderr,"fileimg is %s\n", fileimg); fprintf(stderr,"ftp or http file: %s\n", fileimg); } // Hopefully this will eventually allow us to get maps in the background // while (sometimeout !=0 && local_filename[0]==NULL){ if (local_filename[0]=='\0' ){ if (debug_level & 512 ) { fprintf(stderr,"tiger_local_file=<%s>\n",local_filename); } HandlePendingEvents(app_context); if (interrupt_drawing_now) { // Update to screen (void)XCopyArea(XtDisplay(da), pixmap, XtWindow(da), gc, 0, 0, (unsigned int)screen_width, (unsigned int)screen_height, 0, 0); return; } get_tiger_local_file(local_filename,fileimg); } // whackadoodle // Tell ImageMagick where to find it xastir_snprintf(file, sizeof(file), "%s", local_filename); GetExceptionInfo(&exception); image_info=CloneImageInfo((ImageInfo *) NULL); xastir_snprintf(image_info->filename, sizeof(image_info->filename), "%s", file); if (debug_level & 512) { fprintf(stderr,"Copied %s into image info.\n", file); fprintf(stderr,"image_info got: %s\n", image_info->filename); fprintf(stderr,"Entered ImageMagick code.\n"); fprintf(stderr,"Attempting to open: %s\n", image_info->filename); } // We do a test read first to see if the file exists, so we // don't kill Xastir in the ReadImage routine. f = fopen (image_info->filename, "r"); if (f == NULL) { if (debug_level & 512) fprintf(stderr,"File could not be read\n"); #ifdef USE_MAP_CACHE // clear from cache if bad if (map_cache_del(fileimg)) { if (debug_level & 512) { fprintf(stderr,"Couldn't delete unreadable map from cache\n"); } } #endif if (image_info) DestroyImageInfo(image_info); DestroyExceptionInfo(&exception); return; } (void)fclose (f); image = ReadImage(image_info, &exception); if (image == (Image *) NULL) { MagickWarning(exception.severity, exception.reason, exception.description); //fprintf(stderr,"MagickWarning\n"); #ifdef USE_MAP_CACHE // clear from cache if bad if (map_cache_del(fileimg)) { if (debug_level & 512) { fprintf(stderr,"Couldn't delete map from cache\n"); } } #endif if (image_info) DestroyImageInfo(image_info); DestroyExceptionInfo(&exception); return; } if (debug_level & 512) fprintf(stderr,"Color depth is %i \n", (int)image->depth); if (image->colorspace != RGBColorspace) { fprintf(stderr,"TBD: I don't think we can deal with colorspace != RGB"); if (image) DestroyImage(image); if (image_info) DestroyImageInfo(image_info); DestroyExceptionInfo(&exception); return; } width = image->columns; height = image->rows; // Code to mute the image so it's not as bright. /* if (raster_map_intensity < 1.0) { char tempstr[30]; if (debug_level & 512) fprintf(stderr,"level=%s\n", tempstr); xastir_snprintf(tempstr, sizeof(tempstr), "%d, 100, 100", (int)(raster_map_intensity * 100.0)); ModulateImage(image, tempstr); } */ // If were are drawing to a low bpp display (typically < 8bpp) // try to reduce the number of colors in an image. // This may take some time, so it would be best to do ahead of // time if it is a static image. #if (MagickLibVersion < 0x0540) if (visual_type == NOT_TRUE_NOR_DIRECT && GetNumberColors(image, NULL) > 128) { #else // MagickLib >= 540 if (visual_type == NOT_TRUE_NOR_DIRECT && GetNumberColors(image, NULL, &exception) > 128) { #endif // MagickLib Version if (image->storage_class == PseudoClass) { #if (MagickLibVersion < 0x0549) CompressColormap(image); // Remove duplicate colors #else // MagickLib >= 0x0549 CompressImageColormap(image); // Remove duplicate colors #endif // MagickLibVersion < 0x0549 } // Quantize down to 128 will go here... } pixel_pack = GetImagePixels(image, 0, 0, image->columns, image->rows); if (!pixel_pack) { fprintf(stderr,"pixel_pack == NULL!!!"); if (image) DestroyImage(image); if (image_info) DestroyImageInfo(image_info); DestroyExceptionInfo(&exception); return; } index_pack = GetIndexes(image); if (image->storage_class == PseudoClass && !index_pack) { fprintf(stderr,"PseudoClass && index_pack == NULL!!!"); if (image) DestroyImage(image); if (image_info) DestroyImageInfo(image_info); DestroyExceptionInfo(&exception); return; } if (image->storage_class == PseudoClass && image->colors <= 256) { for (l = 0; l < (int)image->colors; l++) { // Need to check how to do this for ANY image, as ImageMagick can read in all sorts // of image files temp_pack = image->colormap[l]; if (debug_level & 512) fprintf(stderr,"Colormap color is %i %i %i \n", temp_pack.red, temp_pack.green, temp_pack.blue); // Here's a tricky bit: PixelPacket entries are defined as Quantum's. Quantum // is defined in /usr/include/magick/image.h as either an unsigned short or an // unsigned char, depending on what "configure" decided when ImageMagick was installed. // We can determine which by looking at MaxRGB or QuantumDepth. // if (QuantumDepth == 16) { // Defined in /usr/include/magick/image.h if (debug_level & 512) fprintf(stderr,"Color quantum is [0..65535]\n"); my_colors[l].red = temp_pack.red * raster_map_intensity; my_colors[l].green = temp_pack.green * raster_map_intensity; my_colors[l].blue = temp_pack.blue * raster_map_intensity; } else { // QuantumDepth = 8 if (debug_level & 512) fprintf(stderr,"Color quantum is [0..255]\n"); my_colors[l].red = (temp_pack.red << 8) * raster_map_intensity; my_colors[l].green = (temp_pack.green << 8) * raster_map_intensity; my_colors[l].blue = (temp_pack.blue << 8) * raster_map_intensity; } // Get the color allocated on < 8bpp displays. pixel color is written to my_colors.pixel if (visual_type == NOT_TRUE_NOR_DIRECT) { // XFreeColors(XtDisplay(w), cmap, &(my_colors[l].pixel),1,0); XAllocColor(XtDisplay(w), cmap, &my_colors[l]); } else { pack_pixel_bits(my_colors[l].red, my_colors[l].green, my_colors[l].blue, &my_colors[l].pixel); } if (debug_level & 512) fprintf(stderr,"Color allocated is %li %i %i %i \n", my_colors[l].pixel, my_colors[l].red, my_colors[l].blue, my_colors[l].green); } } /* * Here are the corners of our viewport, using the Xastir * coordinate system. Notice that Y is upside down: * * left edge of view = NW_corner_longitude * right edge of view = SE_corner_longitude * top edge of view = NW_corner_latitude * bottom edge of view = SE_corner_latitude * * The corners of our map will soon be (after translating the * tiepoints to the corners if they're not already there): * * left edge of map = tp[0].x_long in Xastir format * right edge of map = tp[1].x_long * top edge of map = tp[0].y_lat * bottom edge of map = tp[1].y_lat * */ map_c_L = tp[0].x_long - NW_corner_longitude; // map left coordinate map_c_T = tp[0].y_lat - NW_corner_latitude; // map top coordinate tp_c_dx = (long)(tp[1].x_long - tp[0].x_long);// Width between tiepoints tp_c_dy = (long)(tp[1].y_lat - tp[0].y_lat); // Height between tiepoints // Check for tiepoints being in wrong relation to one another if (tp_c_dx < 0) tp_c_dx = -tp_c_dx; // New width between tiepoints if (tp_c_dy < 0) tp_c_dy = -tp_c_dy; // New height between tiepoints // Calculate step size per pixel map_c_dx = ((double) tp_c_dx / abs(tp[1].img_x - tp[0].img_x)); map_c_dy = ((double) tp_c_dy / abs(tp[1].img_y - tp[0].img_y)); // Scaled screen step size for use with XFillRectangle below scr_dx = (int) (map_c_dx / scale_x) + 1; scr_dy = (int) (map_c_dy / scale_y) + 1; // calculate top left map corner from tiepoints if (tp[0].img_x != 0) { tp[0].x_long -= (tp[0].img_x * map_c_dx); // map left edge longitude map_c_L = tp[0].x_long - NW_corner_longitude; // delta ?? tp[0].img_x = 0; if (debug_level & 512) fprintf(stderr,"Translated tiepoint_0 x: %d\t%lu\n", tp[0].img_x, tp[0].x_long); } if (tp[0].img_y != 0) { tp[0].y_lat -= (tp[0].img_y * map_c_dy); // map top edge latitude map_c_T = tp[0].y_lat - NW_corner_latitude; tp[0].img_y = 0; if (debug_level & 512) fprintf(stderr,"Translated tiepoint_0 y: %d\t%lu\n", tp[0].img_y, tp[0].y_lat); } // calculate bottom right map corner from tiepoints // map size is geo_image_width / geo_image_height if (tp[1].img_x != (geo_image_width - 1) ) { tp[1].img_x = geo_image_width - 1; tp[1].x_long = tp[0].x_long + (tp[1].img_x * map_c_dx); // right if (debug_level & 512) fprintf(stderr,"Translated tiepoint_1 x: %d\t%lu\n", tp[1].img_x, tp[1].x_long); } if (tp[1].img_y != (geo_image_height - 1) ) { tp[1].img_y = geo_image_height - 1; tp[1].y_lat = tp[0].y_lat + (tp[1].img_y * map_c_dy); // bottom if (debug_level & 512) fprintf(stderr,"Translated tiepoint_1 y: %d\t%lu\n", tp[1].img_y, tp[1].y_lat); } if (debug_level & 512) { fprintf(stderr,"X tiepoint width: %ld\n", tp_c_dx); fprintf(stderr,"Y tiepoint width: %ld\n", tp_c_dy); fprintf(stderr,"Loading imagemap: %s\n", file); fprintf(stderr,"\nImage: %s\n", file); fprintf(stderr,"Image size %d %d\n", geo_image_width, geo_image_height); fprintf(stderr,"XX: %ld YY:%ld Sx %f %d Sy %f %d\n", map_c_L, map_c_T, map_c_dx,(int) (map_c_dx / scale_x), map_c_dy, (int) (map_c_dy / scale_y)); fprintf(stderr,"Image size %d %d\n", width, height); #if (MagickLibVersion < 0x0540) fprintf(stderr,"Unique colors = %d\n", GetNumberColors(image, NULL)); #else // MagickLib < 540 fprintf(stderr,"Unique colors = %ld\n", GetNumberColors(image, NULL, &exception)); #endif // MagickLib < 540 fprintf(stderr,"XX: %ld YY:%ld Sx %f %d Sy %f %d\n", map_c_L, map_c_T, map_c_dx,(int) (map_c_dx / scale_x), map_c_dy, (int) (map_c_dy / scale_y)); fprintf(stderr,"image matte is %i\n", image->matte); } // debug_level & 512 // draw the image from the file out to the map screen // Get the border values for the X and Y for loops used // for the XFillRectangle call later. map_c_yc = (tp[0].y_lat + tp[1].y_lat) / 2; // vert center of map as reference map_y_ctr = (long)(height / 2 +0.499); scale_x0 = get_x_scale(0,map_c_yc,scale_y); // reference scaling at vert map center map_c_xc = (tp[0].x_long + tp[1].x_long) / 2; // hor center of map as reference map_x_ctr = (long)(width / 2 +0.499); scr_x_mc = (map_c_xc - NW_corner_longitude) / scale_x; // screen coordinates of map center // calculate map pixel range in y direction that falls into screen area c_y_max = 0ul; map_y_min = map_y_max = 0l; for (map_y_0 = 0, c_y = tp[0].y_lat; map_y_0 < (long)height; map_y_0++, c_y += map_c_dy) { scr_y = (c_y - NW_corner_latitude) / scale_y; // current screen position if (scr_y > 0) { if (scr_y < screen_height) { map_y_max = map_y_0; // update last map pixel in y c_y_max = (unsigned long)c_y;// bottom map inside screen coordinate } else break; // done, reached bottom screen border } else { // pixel is above screen map_y_min = map_y_0; // update first map pixel in y } } c_y_min = (unsigned long)(tp[0].y_lat + map_y_min * map_c_dy); // top map inside screen coordinate map_x_min = map_x_max = 0l; for (map_x = 0, c_x = tp[0].x_long; map_x < (long)width; map_x++, c_x += map_c_dx) { scr_x = (c_x - NW_corner_longitude)/ scale_x; // current screen position if (scr_x > 0) { if (scr_x < screen_width) map_x_max = map_x; // update last map pixel in x else break; // done, reached right screen border } else { // pixel is left from screen map_x_min = map_x; // update first map pixel in x } } c_x_min = (unsigned long)(tp[0].x_long + map_x_min * map_c_dx); // left map inside screen coordinate scr_yp = -1; scr_c_xr = SE_corner_longitude; c_dx = map_c_dx; // map pixel width scale_xa = scale_x0; // the compiler likes it ;-) map_done = 0; map_act = 0; map_seen = 0; scr_y = screen_height - 1; // loop over map pixel rows for (map_y_0 = map_y_min, c_y = (double)c_y_min; (map_y_0 <= map_y_max); map_y_0++, c_y += map_c_dy) { HandlePendingEvents(app_context); if (interrupt_drawing_now) { if (image) DestroyImage(image); if (image_info) DestroyImageInfo(image_info); // Update to screen (void)XCopyArea(XtDisplay(da), pixmap, XtWindow(da), gc, 0, 0, (unsigned int)screen_width, (unsigned int)screen_height, 0, 0); DestroyExceptionInfo(&exception); return; } scr_y = (c_y - NW_corner_latitude) / scale_y; if (scr_y != scr_yp) { // don't do a row twice scr_yp = scr_y; // remember as previous y scr_xp = -1; // loop over map pixel columns map_act = 0; scale_x_nm = calc_dscale_x(0,(long)c_y) / 1852.0; // nm per Xastir coordinate for (map_x = map_x_min, c_x = (double)c_x_min; map_x <= map_x_max; map_x++, c_x += c_dx) { scr_x = (c_x - NW_corner_longitude) / scale_x; if (scr_x != scr_xp) { // don't do a pixel twice scr_xp = scr_x; // remember as previous x map_y = map_y_0; if (map_y >= 0 && map_y <= tp[1].img_y) { // check map boundaries in y direction map_seen = 1; map_act = 1; // detects blank screen rows (end of map) // now copy a pixel from the map image to the screen l = map_x + map_y * image->columns; if (image->storage_class == PseudoClass) { XSetForeground(XtDisplay(w), gc, my_colors[index_pack[l]].pixel); } else { // It is not safe to assume that the red/green/blue // elements of pixel_pack of type Quantum are the // same as the red/green/blue of an XColor! if (QuantumDepth==16) { my_colors[0].red=pixel_pack[l].red; my_colors[0].green=pixel_pack[l].green; my_colors[0].blue=pixel_pack[l].blue; } else { // QuantumDepth=8 // shift the bits of the 8-bit quantity so that // they become the high bigs of my_colors.* my_colors[0].red=pixel_pack[l].red<<8; my_colors[0].green=pixel_pack[l].green<<8; my_colors[0].blue=pixel_pack[l].blue<<8; } // NOW my_colors has the right r,g,b range for // pack_pixel_bits pack_pixel_bits(my_colors[0].red * raster_map_intensity, my_colors[0].green * raster_map_intensity, my_colors[0].blue * raster_map_intensity, &my_colors[0].pixel); XSetForeground(XtDisplay(w), gc, my_colors[0].pixel); } (void)XFillRectangle (XtDisplay (w),pixmap,gc,scr_x,scr_y,scr_dx,scr_dy); } // check map boundaries in y direction } } // loop over map pixel columns if (map_seen && !map_act) map_done = 1; } } // loop over map pixel rows if (image) DestroyImage(image); if (image_info) DestroyImageInfo(image_info); DestroyExceptionInfo(&exception); }
int SayText(char *text) { OSErr err; pid_t child_pid; //if (debug_level & 2) //fprintf(stderr,"SayText: %s\n",text); // Check whether the last text was the same and it hasn't been // enough time between them (30 seconds). if ( (strcmp(last_speech_text,text) == 0) // Strings match && (last_speech_time + 30 > sec_now()) ) { //fprintf(stderr,"Same text, skipping speech: %d seconds, %s\n", // (int)(sec_now() - last_speech_time), // text); return(1); } //fprintf(stderr,"Speaking: %s\n",text); xastir_snprintf(last_speech_text, sizeof(last_speech_text), "%s", text); last_speech_time = sec_now(); // Check for the variable going out-of-bounds if (macspeech_processes < 0) { macspeech_processes = 0; } // Allow only so many processes to be queued up ready to send // text to the speech subsystem. // if (macspeech_processes > 10) { // Too many processes queued up! return(1); // Don't send this string, return to calling program } // Create a separate process to handle the speech so that our // main process can continue processing packets and displaying // maps. // child_pid = fork(); if (child_pid == -1) { // The fork failed return(1); } if (child_pid == 0) { // Child process macspeech_processes++; // Go back to default signal handler instead of calling // restart() on SIGHUP (void) signal(SIGHUP,SIG_DFL); // Wait for the speech system to be freed up. Note that if // we have multiple processes queued up we don't know in // which order they'll get access to the speech subsystem. // while (SpeechBusy() == true) { usleep(1000000); } // The speech system is free, so send it our text. Right // now we ignore any errors. // err = SpeakText(channel, text, strlen(text)); macspeech_processes--; // Exit this child process. We don't need it anymore. exit(0); } else { // Parent process // Drop through to the return } return(0); // Return to the calling program }
/* ******************************************************************** */ int search_rac_data(char *callsign, rac_record *data) { FILE *fdb; FILE *fndx; char *rc; long call_offset = 0l; char char_offset[16]; char index[32]; int found = 0; rac_record racdata; /*char filler[8];*/ char amacall_path[MAX_VALUE]; get_user_base_dir("data/AMACALL.ndx", amacall_path, sizeof(amacall_path)); xastir_snprintf(index, sizeof(index)," "); xastir_snprintf(racdata.callsign, sizeof(racdata.callsign)," "); /* ==================================================================== */ /* Search thru the index, get the RBA */ /* */ fndx = fopen(amacall_path, "r"); if(fndx != NULL) { rc = fgets(index, (int)sizeof(index), fndx); xastir_snprintf(char_offset, sizeof(char_offset), "%s", &index[6]); while (!feof(fndx) && strncmp(callsign, index, 6) > 0) { xastir_snprintf(char_offset, sizeof(char_offset), "%s", &index[6]); rc = fgets(index, (int)sizeof(index), fndx); } } else { fprintf(stderr, "Search:Could not open RAC data base index: %s\n", amacall_path ); return (0); } call_offset = atol(char_offset); (void)fclose(fndx); /* ==================================================================== */ /* Now we have our pointer into the main database (text) file. */ /* Start from there and linear search the data. */ /* This will take an avg of 1/2 of the # skipped making the index */ /* */ fdb = fopen(get_data_base_dir("fcc/AMACALL.LST"), "r"); if (fdb != NULL) { (void)fseek(fdb, call_offset, SEEK_SET); if (callsign[5] == '-') (void)chomp(callsign,5); while (!feof(fdb) && strncmp((char *)&racdata, callsign, 6) < 0) //WE7U // Problem here: We're sticking 8 bytes too many into racdata! rc = fgets((char *)&racdata, sizeof(racdata), fdb); } else fprintf(stderr,"Search:Could not open RAC data base: %s\n", get_data_base_dir("fcc/AMACALL.LST") ); /* || (callsign[5] == '-' && strncmp((char *)&racdata,callsign,5) < 0)) */ (void)chomp(racdata.callsign, 6); if (!strncmp((char *)racdata.callsign, callsign, 6)) { found = 1; // Some of these cause problems on 64-bit processors, so commented // them out for now. // (void)chomp(racdata.first_name, 35); // (void)chomp(racdata.last_name, 35); // (void)chomp(racdata.address, 70); // (void)chomp(racdata.city, 35); // (void)chomp(racdata.province, 2); // (void)chomp(racdata.postal_code, 10); // (void)chomp(racdata.qual_a, 1); // (void)chomp(racdata.qual_b, 1); // (void)chomp(racdata.qual_c, 1); // (void)chomp(racdata.qual_d, 1); // (void)chomp(racdata.club_name, 141); // (void)chomp(racdata.club_address, 70); // (void)chomp(racdata.club_city, 35); // (void)chomp(racdata.club_province, 2); // (void)chomp(racdata.club_postal_code, 9); xastir_snprintf(data->callsign, sizeof(data->callsign), "%s", racdata.callsign); xastir_snprintf(data->first_name, sizeof(data->first_name), "%s", racdata.first_name); xastir_snprintf(data->last_name, sizeof(data->last_name), "%s", racdata.last_name); xastir_snprintf(data->address, sizeof(data->address), "%s", racdata.address); xastir_snprintf(data->city, sizeof(data->city), "%s", racdata.city); xastir_snprintf(data->province, sizeof(data->province), "%s", racdata.province); xastir_snprintf(data->postal_code, sizeof(data->postal_code), "%s", racdata.postal_code); xastir_snprintf(data->qual_a, sizeof(data->qual_a), "%s", racdata.qual_a); xastir_snprintf(data->qual_b, sizeof(data->qual_b), "%s", racdata.qual_b); xastir_snprintf(data->qual_c, sizeof(data->qual_c), "%s", racdata.qual_c); xastir_snprintf(data->qual_d, sizeof(data->qual_d), "%s", racdata.qual_d); xastir_snprintf(data->club_name, sizeof(data->club_name), "%s", racdata.club_name); xastir_snprintf(data->club_address, sizeof(data->club_address), "%s", racdata.club_address); xastir_snprintf(data->club_city, sizeof(data->club_city), "%s", racdata.club_city); xastir_snprintf(data->club_province, sizeof(data->club_province), "%s", racdata.club_province); xastir_snprintf(data->club_postal_code, sizeof(data->club_postal_code), "%s", racdata.club_postal_code); } (void)fclose(fdb); if (!found) { // "Callsign Search", "Callsign Not Found!" popup_message_always(langcode("STIFCC0101"), langcode("STIFCC0102") ); } return(found); }
// This function is destructive to its first parameter // // GPGGA,UTC-Time,lat,N/S,long,E/W,GPS-Quality,nsat,HDOP,MSL-Meters,M,Geoidal-Meters,M,DGPS-Data-Age(seconds),DGPS-Ref-Station-ID[*CHK] // GPGGA,hhmmss[.sss],ddmm.mm[mm],{N|S},dddmm.mm[mm],{E|W},{0-8},dd,[d]d.d,[-dddd]d.d,M,[-ddd]d.d,M,[dddd.d],[dddd][*CHK] // // GPS-Quality: // 0: Invalid Fix // 1: GPS Fix // 2: DGPS Fix // 3: PPS Fix // 4: RTK Fix // 5: Float RTK Fix // 6: Estimated (dead-reckoning) Fix // 7: Manual Input Mode // 8: Simulation Mode // // $GPGGA,170834,4124.8963,N,08151.6838,W,1,05,1.5,280.2,M,-34.0,M,,,*75 // $GPGGA,104438.833,4301.1439,N,08803.0338,W,1,05,1.8,185.8,M,-34.2,M,0.0,0000*40 // int decode_gps_gga( char *data, char *long_pos, int long_pos_length, char *lat_pos, int lat_pos_length, char *sats, char *alt, char *aunit, int *status ) { char *temp_ptr; char *temp_ptr2; char temp_data[MAX_LINE_SIZE+1]; // Big in case we get concatenated packets (it happens!) char long_pos_x[11]; char long_ew; char lat_pos_y[10]; char lat_ns; char sats_visible[4]; char altitude[8]; char alt_unit; // We should check for a minimum line length before parsing, // and check for end of input while tokenizing. if ( (data == NULL) || (strlen(data) < 35) ) // Not enough data to parse position from. return(0); if (strncmp(data,"$GPGGA,",7) != 0) return(0); if (strchr(data,',') == NULL) return(0); if (strtok(data,",") == NULL) // get GPGGA and skip it return(0); if(strtok(NULL,",") == NULL) // get time and skip it return(0); temp_ptr = strtok(NULL,","); // get latitude if (temp_ptr == NULL) return(0); xastir_snprintf(lat_pos_y, sizeof(lat_pos_y), "%s", temp_ptr); lat_pos_y[9] = '\0'; // Note that some GPS's put out latitude with extra precision, such as 4801.1234 // Check for comma char, replace with '\0' temp_ptr2 = strstr(lat_pos_y, ","); if (temp_ptr2) temp_ptr2[0] = '\0'; temp_ptr = strtok(NULL,","); // get N-S if (temp_ptr == NULL) return(0); xastir_snprintf(temp_data, sizeof(temp_data), "%s", temp_ptr); temp_data[1] = '\0'; lat_ns=toupper((int)temp_data[0]); if(lat_ns != 'N' && lat_ns != 'S') return(0); temp_ptr = strtok(NULL,","); // get long if(temp_ptr == NULL) return(0); xastir_snprintf(long_pos_x, sizeof(long_pos_x), "%s", temp_ptr); long_pos_x[10] = '\0'; // Note that some GPS's put out longitude with extra precision, such as 12201.1234 // Check for comma char, replace with '\0' temp_ptr2 = strstr(long_pos_x, ","); if (temp_ptr2) temp_ptr2[0] = '\0'; temp_ptr = strtok(NULL,","); // get E-W if (temp_ptr == NULL) return(0); xastir_snprintf(temp_data, sizeof(temp_data), "%s", temp_ptr); temp_data[1] = '\0'; long_ew=toupper((int)temp_data[0]); if (long_ew != 'E' && long_ew != 'W') return(0); temp_ptr = strtok(NULL,","); // get FIX Quality if (temp_ptr == NULL) return(0); xastir_snprintf(temp_data, sizeof(temp_data), "%s", temp_ptr); temp_data[1] = '\0'; // '0' = bad fix, positive numbers = ok if(temp_data[0] == '0') return(0); // Save the fix quality in "status" *status = atoi(temp_data); temp_ptr=strtok(NULL,","); // Get sats vis if (temp_ptr == NULL) return(0); xastir_snprintf(sats_visible, sizeof(sats_visible), "%s", temp_ptr); sats_visible[2] = '\0'; temp_ptr=strtok(NULL,","); // get hoz dil if (temp_ptr == NULL) return(0); temp_ptr=strtok(NULL,","); // Get altitude if (temp_ptr == NULL) return(0); // Get altitude xastir_snprintf(altitude, sizeof(altitude), "%s", temp_ptr); altitude[7] = '\0'; temp_ptr=strtok(NULL,","); // get UNIT if (temp_ptr == NULL) return(0); // get UNIT xastir_snprintf(temp_data, sizeof(temp_data), "%s", temp_ptr); temp_data[1] = '\0'; alt_unit=temp_data[0]; // Data is good xastir_snprintf(long_pos, long_pos_length, "%s%c", long_pos_x, long_ew); xastir_snprintf(lat_pos, lat_pos_length, "%s%c", lat_pos_y, lat_ns); xastir_snprintf(sats, 4, "%s", sats_visible); xastir_snprintf(alt, 8, "%s", altitude); xastir_snprintf(aunit, 2, "%c", alt_unit); return(1); }