/** * OS time is not reliable, so we use GPS time to determine relative span. * GPS tow can be smaller than previous when cross GPS week. * Anyway, restart a new log file when time reverse detected */ void track_add(/*double lat, double lon, U4 gps_tow*/) { static const float threshold = TRACK_MAX_DELTA * (180.0 / (WGS84_SEMI_MAJOR_AXIS * M_PI)); /* NOTE: make max frequency is 1 HZ, since we record time offset with unit of seconds */ //if (g_gpsdata.llh_itow - previous_gps_tow < 1000) // return; trackpoint_t *tp; if (tracks->count > 0) { tp = &(tracks->tps[tracks->count-1]); float lat_delta = (float)fabs(g_gpsdata.lat - tp->wgs84.lat); float lon_delta = (float)fabs(g_gpsdata.lon - tp->wgs84.lon); if (sqrt(lat_delta * lat_delta + lon_delta * lon_delta) < threshold) return; /* new GPS week: split track file */ if (g_context.track_enabled && (g_gpsdata.llh_itow < previous_gps_tow)) { track_save(TRUE, FALSE); track_init(TRUE); return; } } else { tracks->starttime = time(NULL); first_gps_tow = g_gpsdata.llh_itow; } tp = &(tracks->tps[tracks->count]); /* Copy values */ tp->wgs84.lat = g_gpsdata.lat; tp->wgs84.lon = g_gpsdata.lon; tp->id = tracks->total_count; tp->time_offset = (g_gpsdata.llh_itow - first_gps_tow) / (U4)1000; previous_gps_tow = g_gpsdata.llh_itow; ++tracks->count; ++tracks->total_count; if (tracks->count >= TRACK_MAX_IN_MEM_RECORDS) { int saved_count = 0; if (g_context.track_enabled) saved_count = track_save(FALSE, FALSE); if (saved_count == 0) { /* lose data but we need space */ saved_count = tracks->count / 2; } /* move the remaining elements to array head */ tracks->count -= saved_count; memcpy(&tracks->tps[0], &(tracks->tps[saved_count]), tracks->count * sizeof(trackpoint_t)); } }
void track_cleanup() { /* better to do this after death of polling thread */ if (g_context.track_enabled) track_save(TRUE, TRUE); track_replay_cleanup(); }
static void stop_track_button_clicked(GtkWidget *widget, gpointer data) { if (! g_context.track_enabled) return; g_context.track_enabled = FALSE; gtk_widget_set_sensitive(new_track_button, TRUE); gtk_widget_set_sensitive(stop_track_button, FALSE); track_save(TRUE, FALSE); ctx_gpsfix_on_track_state_changed(); }
int main(int argc, char **argv) { if (argc > 1 && strcmp(argv[1], "--version") == 0) { printf("%s\n", COURIER_COPYRIGHT); exit(0); } if (chdir(courierdir())) { perror("chdir"); return (1); } if (argc < 2) return (0); if (strcmp(argv[1], "stop") == 0) { int fd; trigger(TRIGGER_STOP); /* Wait until the exclusive lock goes away: */ signal(SIGHUP, SIG_DFL); if ((fd=open(TMPDIR "/courierd.lock", O_RDWR|O_CREAT, 0600)) < 0) clog_msg_errno(); alarm(15); /* But abort after 15 seconds. */ ll_lock_ex(fd); return (0); } if (strcmp(argv[1], "restart") == 0) { trigger(TRIGGER_RESTART); return (0); } if (strcmp(argv[1], "flush") == 0) { ino_t n; struct ctlfile ctf; if (getuid()) { /* ** We'll fail trying to open the pipe anyway, but let's ** give a meaningful error message now. */ fprintf(stderr, "courier flush can be executed only by the superuser.\n"); exit(1); } if (argc < 3) { trigger(TRIGGER_FLUSH); /* Everything */ exit(0); } if (comparseqid(argv[2], &n) == 0 && ctlfile_openi(n, &ctf, 1) == 0) { int c=ctlfile_searchfirst(&ctf, COMCTLFILE_MSGID); if (c >= 0 && strcmp(ctf.lines[c]+1, argv[2]) == 0) { char *s=courier_malloc(sizeof(TRIGGER_FLUSHMSG)+1+ strlen(argv[2])); strcat(strcat(strcpy(s, TRIGGER_FLUSHMSG), argv[2]), "\n"); trigger(s); ctlfile_close(&ctf); return (0); } ctlfile_close(&ctf); } fprintf(stderr, "No such message.\n"); exit(1); return (1); } /* Might as well... */ if (strcmp(argv[1], "start") == 0) { pid_t p; int waitstat; char dummy; /* ** Ok, courierd will close file descriptor 3 when it starts, so we ** put a pipe on there, and wait for it to close. */ int pipefd[2]; close(3); if (open("/dev/null", O_RDONLY) != 3 || pipe(pipefd)) { fprintf(stderr, "Cannot open pipe\n"); exit(1); } if (getuid()) { /* ** We'll fail trying to execute courierd anyway, but let's ** give a meaningful error message now. */ fprintf(stderr, "courier start can be executed only by the superuser.\n"); return (1); } signal(SIGCHLD, SIG_DFL); while ((p=fork()) == -1) { perror("fork"); sleep(10); } if (p == 0) { dup2(pipefd[1], 3); close(pipefd[1]); close(pipefd[0]); while ((p=fork()) == -1) { perror("fork"); sleep(10); } if (p == 0) { /* ** stdin from the bitbucket. stdout to ** /dev/null, or the bitbucket. */ signal(SIGHUP, SIG_IGN); close(0); open("/dev/null", O_RDWR); dup2(0, 1); dup2(0, 2); /* See if we can disconnect from the terminal */ #ifdef TIOCNOTTY { int fd=open("/dev/tty", O_RDWR); if (fd >= 0) { ioctl(fd, TIOCNOTTY, 0); close(fd); } } #endif /* Remove any process groups */ #if HAVE_SETPGRP #if SETPGRP_VOID setpgrp(); #else setpgrp(0, 0); #endif #endif execl( DATADIR "/courierctl.start", "courierctl.start", (char *)0); perror("exec"); _exit(1); } _exit(0); } close(pipefd[1]); while (wait(&waitstat) != p) ; if (read(pipefd[0], &dummy, 1) < 0) ; /* ignore */ close(pipefd[0]); close(3); return (0); } if (strcmp(argv[1], "clear") == 0 && argc > 2) { libmail_changeuidgid(MAILUID, MAILGID); if (strcmp(argv[2], "all") == 0) { courier_clear_all(); } else { track_save(argv[2], TRACK_ADDRACCEPTED); printf("%s cleared.\n", argv[2]); } return (0); } if (argc > 2 && strcmp(argv[1], "show") == 0 && strcmp(argv[2], "all") == 0) { libmail_changeuidgid(MAILUID, MAILGID); courier_show_all(); } return (0); }