static int config_mark_ctx(calipso_config_t *config, short state) { if( strlen(_block) > 0 ) { switch(state) { case CTX_BLOCK_BEGIN: config_set_option(config, CONF_CTX_OPT, CONF_BEGIN_CTX, _block); break; case CTX_BLOCK_END: config_set_option(config, CONF_CTX_OPT, CONF_END_CTX, _block); break; } } return 1; }
int ub_ctx_set_option(struct ub_ctx* ctx, char* opt, char* val) { lock_basic_lock(&ctx->cfglock); if(ctx->finalized) { lock_basic_unlock(&ctx->cfglock); return UB_AFTERFINAL; } if(!config_set_option(ctx->env->cfg, opt, val)) { lock_basic_unlock(&ctx->cfglock); return UB_SYNTAX; } lock_basic_unlock(&ctx->cfglock); return UB_NOERROR; }
int main(int argc, char *argv[]) { int fifo; int i, n; char *opt, *arg, *equal_arg, *homedir, *user; char *line, *eol, buf[4096]; pgm_name = argv[0]; bcm_host_init(); time(&pikrellcam.t_now); config_set_defaults(); for (i = 1; i < argc; i++) get_arg_pass1(argv[i]); if (!config_load(pikrellcam.config_file)) config_save(pikrellcam.config_file); if (!motion_regions_config_load(pikrellcam.motion_regions_config_file)) motion_regions_config_save(pikrellcam.motion_regions_config_file); if (!at_commands_config_load(pikrellcam.at_commands_config_file)) at_commands_config_save(pikrellcam.at_commands_config_file); for (i = 1; i < argc; i++) { if (get_arg_pass1(argv[i])) continue; opt = argv[i]; /* Just for initial install-pikrellcam.sh run to create config files. */ if (!strcmp(opt, "-quit")) exit(0); /* Accept: --opt arg -opt arg opt=arg --opt=arg -opt=arg */ for (i = 0; i < 2; ++i) if (*opt == '-') ++opt; if ((equal_arg = strchr(opt, '=')) != NULL) { *equal_arg++ = '\0'; arg = equal_arg; ++i; } else arg = argv[i + 1]; /* For camera parameters, do not set the camera, only replace | values in the parameter table. */ if ( !config_set_option(opt, arg, TRUE) && !mmalcam_config_parameter_set(opt, arg, FALSE) ) { log_printf("Bad arg: %s\n", opt); exit(1); } } homedir = getpwuid(geteuid())->pw_dir; user = strrchr(homedir, '/'); pikrellcam.effective_user = strdup(user ? user + 1 : "pi"); if (*pikrellcam.log_file != '/') { snprintf(buf, sizeof(buf), "%s/%s", pikrellcam.install_dir, pikrellcam.log_file); dup_string(&pikrellcam.log_file, buf); } if (*pikrellcam.media_dir != '/') { snprintf(buf, sizeof(buf), "%s/%s", pikrellcam.install_dir, pikrellcam.media_dir); dup_string(&pikrellcam.media_dir, buf); } strftime(buf, sizeof(buf), "%F %T", localtime(&pikrellcam.t_now)); log_printf("\n%s ==== PiKrellCam started ====\n", buf); snprintf(buf, sizeof(buf), "%s/%s", pikrellcam.install_dir, "www"); check_modes(buf, 0775); asprintf(&pikrellcam.command_fifo, "%s/www/FIFO", pikrellcam.install_dir); asprintf(&pikrellcam.script_dir, "%s/scripts", pikrellcam.install_dir); asprintf(&pikrellcam.mjpeg_filename, "%s/mjpeg.jpg", pikrellcam.mjpeg_dir); log_printf("using FIFO: %s\n", pikrellcam.command_fifo); log_printf("using mjpeg: %s\n", pikrellcam.mjpeg_filename); /* Subdirs must match www/config.php and the init script is supposed | to take care of that. */ asprintf(&pikrellcam.video_dir, "%s/%s", pikrellcam.media_dir, PIKRELLCAM_VIDEO_SUBDIR); asprintf(&pikrellcam.still_dir, "%s/%s", pikrellcam.media_dir, PIKRELLCAM_STILL_SUBDIR); asprintf(&pikrellcam.timelapse_dir, "%s/%s", pikrellcam.media_dir, PIKRELLCAM_TIMELAPSE_SUBDIR); if (!make_dir(pikrellcam.media_dir)) exit(1); snprintf(buf, sizeof(buf), "%s/scripts-dist/init $I $m $M $P $G", pikrellcam.install_dir); exec_wait(buf, NULL); /* User may have enabled a mount disk on media_dir */ exec_wait(pikrellcam.on_startup_cmd, NULL); check_modes(pikrellcam.media_dir, 0775); if ( !make_dir(pikrellcam.mjpeg_dir) || !make_dir(pikrellcam.video_dir) || !make_dir(pikrellcam.still_dir) || !make_dir(pikrellcam.timelapse_dir) || !make_fifo(pikrellcam.command_fifo) ) exit(1); if ((fifo = open(pikrellcam.command_fifo, O_RDONLY | O_NONBLOCK)) < 0) { log_printf("Failed to open FIFO: %s. %m\n", pikrellcam.command_fifo); exit(1); } fcntl(fifo, F_SETFL, 0); read(fifo, buf, sizeof(buf)); sun_times_init(); camera_start(); config_timelapse_load_status(); signal(SIGINT, signal_quit); signal(SIGTERM, signal_quit); signal(SIGCHLD, event_child_signal); while (1) { usleep(1000000 / EVENT_LOOP_FREQUENCY); event_process(); /* Process lines in the FIFO. Single lines via an echo "xxx" > FIFO | or from a web page may not have a terminating \n. | Local scripts may dump multiple \n terminated lines into the FIFO. */ if ((n = read(fifo, buf, sizeof(buf) - 2)) > 0) { if (buf[n - 1] != '\n') buf[n++] = '\n'; /* ensures all lines in buf end in \n */ buf[n] = '\0'; line = buf; eol = strchr(line, '\n'); while (eol > line) { *eol++ = '\0'; command_process(line); while (*eol == '\n') ++eol; line = eol; eol = strchr(line, '\n'); } } } return 0; }
void command_process(char *command_line) { VideoCircularBuffer *vcb = &video_circular_buffer; Command *cmd; char command[64], args[128], buf[32], *path; int i, n; if (!command_line || *command_line == '\0') return; n = sscanf(command_line, "%63s %[^\n]", command, args); if (n < 1 || command[0] == '#') return; for (cmd = NULL, i = 0; i < COMMAND_SIZE; cmd = NULL, ++i) { cmd = &commands[i]; if (!strcmp(command, cmd->name)) { if (cmd->n_args != n - 1) { log_printf("Wrong number of args for command: %s\n", command); return; } break; } } if (!cmd) { if ( !config_set_option(command, args, FALSE) && !mmalcam_config_parameter_set(command, args, TRUE) ) log_printf("Bad command: [%s] [%s]\n", command, args); return; } if (cmd->code != display_cmd) log_printf("command_process: %s\n", command_line); if (cmd->code < display_cmd && !display_is_default()) { display_set_default(); return; } switch (cmd->code) { case record: pthread_mutex_lock(&vcb->mutex); if (config_boolean_value(args) == TRUE) { if (vcb->pause) vcb->pause = FALSE; else { if (vcb->state == VCB_STATE_MOTION_RECORD) video_record_stop(vcb); video_record_start(vcb, VCB_STATE_MANUAL_RECORD_START); } } else video_record_stop(vcb); pthread_mutex_unlock(&vcb->mutex); break; case record_pause: /* Can pause manual record only. Because of event_gap/capture | times, I'm not even sure what it would mean to pause a | motion record. */ pthread_mutex_lock(&vcb->mutex); if (vcb->state == VCB_STATE_MANUAL_RECORD) vcb->pause = vcb->pause ? FALSE : TRUE; else vcb->pause = FALSE; pthread_mutex_unlock(&vcb->mutex); break; case still: snprintf(buf, sizeof(buf), "%d", pikrellcam.still_sequence); path = media_pathname(pikrellcam.still_dir, pikrellcam.still_filename, 'N', buf, '\0', NULL); pikrellcam.still_sequence += 1; still_capture(path); free(path); break; case tl_start: if ((n = atoi(args)) < 1) n = 0; time_lapse.activated = TRUE; time_lapse.on_hold = FALSE; if (!time_lapse.event && n > 0) { time_lapse.sequence = 0; ++time_lapse.series; time_lapse.event = event_add("timelapse", pikrellcam.t_now, n, timelapse_capture, NULL); } else if (n > 0) /* Change the period */ { time_lapse.event->time += (n - time_lapse.period); time_lapse.event->period = n; } if (n > 0) time_lapse.period = n; /* n == 0 just sets on_hold FALSE */ config_timelapse_save_status(); break; case tl_hold: config_set_boolean(&time_lapse.on_hold, args); config_timelapse_save_status(); break; case tl_end: if (time_lapse.activated) { event_remove(time_lapse.event); time_lapse.event = NULL; time_lapse.activated = FALSE; time_lapse.on_hold = FALSE; config_timelapse_save_status(); exec_no_wait(pikrellcam.on_timelapse_end_cmd, NULL); } break; case tl_inform_convert: if (!strcmp(args, "done")) { event_remove(time_lapse.inform_event); dup_string(&time_lapse.convert_name, ""); time_lapse.convert_size = 0; } else { dup_string(&time_lapse.convert_name, args); time_lapse.inform_event = event_add("tl_inform_convert", pikrellcam.t_now, 5, timelapse_inform_convert, NULL); } break; case tl_show_status: config_set_boolean(&time_lapse.show_status, args); break; case display_cmd: display_command(args); break; case motion_cmd: motion_command(args); break; case motion_enable: n = motion_frame.motion_enable; config_set_boolean(&motion_frame.motion_enable, args); if (n && !motion_frame.motion_enable) { pthread_mutex_lock(&vcb->mutex); if (vcb->state == VCB_STATE_MOTION_RECORD) video_record_stop(vcb); pthread_mutex_unlock(&vcb->mutex); } break; case save_config: config_save(pikrellcam.config_file); break; case quit: config_timelapse_save_status(); if (pikrellcam.config_modified) config_save(pikrellcam.config_file); display_quit(); exit(0); break; default: log_printf("command in table with no action!\n"); break; } }
static void config_parse_line(calipso_config_t *config , char *line, int nline) { char option[MAXOPTLEN]= {0}, value[MAXOPTLEN] = {0}; char *s, *delim = NULL; if(strlen(line) > MAXOPTLEN ) parser_error(nline, PERR_LINE); //printf("line '%s' %d\n", line, nline); if(block_begin(line)) { if(!strlen(_block)) { s = strtok(line, BLOCK_BEGIN); if(s) { strncpy(_block, s, MAXOPTLEN); trim(_block); //mark context begin config_mark_ctx(config, CTX_BLOCK_BEGIN); } else parser_error(nline, PERR_BLOCK); } else parser_error(nline, PERR_BEGIN); //printf("begin '%s'\n", _block); return; } if(block_end(line)) { if(strlen(_block) > 0) { //mark context end config_mark_ctx(config, CTX_BLOCK_END); memset(_block, 0 , MAXOPTLEN); } else parser_error(nline, PERR_END); //printf("end '%s'\n", _block); return; } if(strstr(line , DELIM_EQU)) delim = DELIM_EQU; else if(strstr(line , DELIM_SPACE)) delim = DELIM_SPACE; else if(strstr(line, DELIM_TAB)) delim = DELIM_TAB; else parser_error(nline, PERR_DELIM); s = strtok (line, delim); if (s) { strncpy (option, s, MAXOPTLEN); } s = strtok (NULL, delim); if (s) { strncpy (value, s, MAXOPTLEN); } if ( strlen(option) && strlen(value)) { trim(option); trim(value); config_set_option(config, option, value, strlen(_block) ? _block : NULL ); } else { parser_error(nline, PERR_PAIR); } }
boolean config_load(char *config_file) { FILE *f; char linebuf[128], opt[64], args[128]; int n; char *s; if ((f = fopen(config_file, "r")) == NULL) return FALSE; pikrellcam.config_sequence_new = 13; while (fgets(linebuf, sizeof(linebuf), f)) { n = sscanf(linebuf, "%63s %[^\n]", opt, args); s = args + strlen(args) - 1; if (n == 2) while (*s == ' ' || *s == '\t' || *s == '\r') *s-- = '\0'; if (n < 1 || opt[0] == '#') continue; if ( n != 2 || ( !config_set_option(opt, args, TRUE) && !mmalcam_config_parameter_set(opt, args, FALSE) ) ) printf("Bad config file option: %s\n", linebuf); } fclose(f); if (pikrellcam.motion_magnitude_limit < 3) pikrellcam.motion_magnitude_limit = 3; if (pikrellcam.motion_magnitude_limit_count < 2) pikrellcam.motion_magnitude_limit_count = 2; if (pikrellcam.motion_burst_count < 20) pikrellcam.motion_burst_count = 20; if (pikrellcam.motion_burst_frames < 2) pikrellcam.motion_burst_frames = 2; if ( pikrellcam.motion_record_time_limit != 0 && pikrellcam.motion_record_time_limit < 10 ) pikrellcam.motion_record_time_limit = 10; if (pikrellcam.motion_vectors_dimming < 30) pikrellcam.motion_vectors_dimming = 30; if (pikrellcam.motion_vectors_dimming > 60) pikrellcam.motion_vectors_dimming = 60; if (pikrellcam.motion_times.post_capture > pikrellcam.motion_times.event_gap) pikrellcam.motion_times.event_gap = pikrellcam.motion_times.post_capture; camera_adjust_temp = pikrellcam.camera_adjust; motion_times_temp = pikrellcam.motion_times; if (pikrellcam.config_sequence_new != pikrellcam.config_sequence) { pikrellcam.config_sequence = pikrellcam.config_sequence_new; pikrellcam.config_modified = TRUE; } return TRUE; }