示例#1
0
  /* vcb should be locked before calling video_record_start()
  */
void
video_record_start(VideoCircularBuffer *vcb, int start_state)
	{
	char	*s, *tag, *path, seq_buf[12];
	int		*seq;

	if (vcb->state == VCB_STATE_MANUAL_RECORD)
		return;

	if (start_state == VCB_STATE_MOTION_RECORD_START)
		{
		tag = pikrellcam.video_motion_tag;
		seq = &pikrellcam.video_motion_sequence;
		}
	else
		{
		tag = pikrellcam.video_manual_tag;
		seq = &pikrellcam.video_manual_sequence;
		}

	snprintf(seq_buf, sizeof(seq_buf), "%d", *seq);
	path = media_pathname(pikrellcam.video_dir, pikrellcam.video_filename,
						'N',  seq_buf,
						'M', tag);
	*seq += 1;
	dup_string(&pikrellcam.video_pathname, path);
	free(path);
	path = pikrellcam.video_pathname;

	if ((s = strstr(path, ".mp4")) != NULL && *(s + 4) == '\0')
		{
		asprintf(&path, "%s.h264", pikrellcam.video_pathname);
		dup_string(&pikrellcam.video_h264, path);
		free(path);
		path = pikrellcam.video_h264;
		pikrellcam.video_mp4box = TRUE;
		}
	else
		pikrellcam.video_mp4box = FALSE;

	if ((vcb->file = fopen(path, "w")) == NULL)
		log_printf("Could not create video file %s.  %m\n", path);
	else
		{
		log_printf("Video record: %s ...\n", path);
		vcb->state = start_state;
		}
	}
示例#2
0
boolean
config_set_option(char *opt, char *arg, boolean set_safe)
	{
	Config	*cfg;
	boolean	result = FALSE;

	if (!opt || !*opt || !arg || !*arg)
		return FALSE;

	for (cfg = &config[0]; cfg < &config[CONFIG_SIZE]; ++cfg)
		{
		if (   (cfg->safe && !set_safe)
		    || strcmp(opt, cfg->option)
		   )
			continue;

		dup_string(&cfg->arg, arg);
		result = (*cfg->config_func)(arg, &cfg->result);	/* Allocates new storage for strings */

		if (pikrellcam.verbose && !set_safe)
			printf("config_set_option: %s %s\n", cfg->option, arg);
		break;
		}
	return result;
	}
示例#3
0
boolean
mmalcam_config_parameter_set(char *name, char *arg, boolean set_camera)
	{
	CameraParameter	*param;
	boolean			found = FALSE;
	MMAL_STATUS_T	status = MMAL_SUCCESS;

	for (param = &camera_parameters[0];
				param < &camera_parameters[CAMERA_PARAMETERS_SIZE]; ++param)
		{
		if (!strcmp(param->name, name) && param->func)
			{
			found = TRUE;
			if (set_camera)
				status = (param->func)(name, arg);
			if (status == MMAL_SUCCESS)
				dup_string(&param->arg, arg);		/* replace in config table */
			break;
			}
		}
	if (status != MMAL_SUCCESS)
		log_printf("mmalcam_config_parameter_set: %s %s [%s]\n", name, arg,
				!found ? "not found" :
					(set_camera ? mmal_status[status] : "config set (not camera)"));
	return (found && (status == MMAL_SUCCESS));
	}
示例#4
0
MMAL_STATUS_T
flip_control_set(char *option, char *setting)
	{
	MMAL_PARAMETER_MIRROR_T mirror =
                    {{MMAL_PARAMETER_MIRROR, sizeof(MMAL_PARAMETER_MIRROR_T)},
                    MMAL_PARAM_MIRROR_NONE};
	CameraParameter *param;
	int             hflip = FALSE,
	                vflip = FALSE;
	int             i;
	MMAL_STATUS_T   status = MMAL_EINVAL;

	if (!strcmp(option, "hflip"))
		{
		hflip = config_boolean_value(setting);
		if (!hflip)
			setting = "off";	/* config transition */
		param = mmalcam_config_parameter_get("hflip");
		dup_string(&param->arg, setting);

		param = mmalcam_config_parameter_get("vflip");
		vflip = config_boolean_value(param->arg);
		}
	else
		{
		vflip = config_boolean_value(setting);
		param = mmalcam_config_parameter_get("vflip");
		dup_string(&param->arg, setting);

		param = mmalcam_config_parameter_get("hflip");
		hflip = config_boolean_value(param->arg);
		}
	if (hflip && vflip)
		mirror.value = MMAL_PARAM_MIRROR_BOTH;
	else if (hflip)
		mirror.value = MMAL_PARAM_MIRROR_HORIZONTAL;
	else if (vflip)
		mirror.value = MMAL_PARAM_MIRROR_VERTICAL;

	for (i = 0; i < MAX_CAMERA_PORTS; ++i)
		if ((status = mmal_port_parameter_set(camera.component->output[i],
				&mirror.hdr)) != MMAL_SUCCESS)
			break;

	return status;
	}
示例#5
0
/* Caller must g_free() the returned filename. */
gchar *
ghid_dialog_file_select_save (gchar * title, gchar ** path, gchar * file,
			      gchar * shortcuts)
{
  GtkWidget *dialog;
  gchar *result = NULL, *folder, *seed;
  GHidPort *out = &ghid_port;

  dialog = gtk_file_chooser_dialog_new (title,
					GTK_WINDOW (out->top_window),
					GTK_FILE_CHOOSER_ACTION_SAVE,
					GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
					GTK_STOCK_OK, GTK_RESPONSE_OK,
					NULL);

  gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog),
                                                  TRUE);
  gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);

  if (path && *path && **path)
    gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), *path);

  if (file && *file)
    {
      gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog),
                                         g_path_get_basename(file));
      gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog),
                                           g_path_get_dirname (file));
    }

  if (shortcuts && *shortcuts)
    {
      folder = g_strdup (shortcuts);
      seed = folder;
      while ((folder = strtok (seed, ":")) != NULL)
	{
	  gtk_file_chooser_add_shortcut_folder (GTK_FILE_CHOOSER (dialog),
						folder, NULL);
	  seed = NULL;
	}
      g_free (folder);
    }
  if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK)
    {
      result = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
      folder =
	gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (dialog));
      if (folder && path)
	{
	  dup_string (path, folder);
	  g_free (folder);
	}
    }
  gtk_widget_destroy (dialog);


  return result;
}
示例#6
0
  /* vcb should be locked before calling video_record_stop()
  */
void
video_record_stop(VideoCircularBuffer *vcb)
	{
	Event	*event = NULL;
	char	*cmd;

	if (!vcb->file)
		return;

	fclose(vcb->file);
	vcb->file = NULL;

	log_printf("Video %s record stopped.\n",
			(vcb->state & VCB_STATE_MOTION_RECORD) ? "motion" : "manual");

	if (pikrellcam.video_mp4box)
		{
		asprintf(&cmd, "(MP4Box %s -fps %d -add %s %s %s ; rm %s)",
				pikrellcam.verbose ? "" : "-quiet",
				pikrellcam.camera_adjust.mp4_box_fps,
				pikrellcam.video_h264, pikrellcam.video_pathname,
				pikrellcam.verbose ? "" : "2> /dev/null",
				pikrellcam.video_h264);
		if (   (vcb->state & VCB_STATE_MOTION_RECORD)
		    && *pikrellcam.on_motion_end_cmd
		   )
			event = exec_child_event("motion end command", cmd, NULL);
		else
			exec_no_wait(cmd, NULL);
		free(cmd);
		}
	dup_string(&pikrellcam.video_last_save, pikrellcam.video_pathname);

	pikrellcam.video_notify = TRUE;
	event_count_down_add("video saved notify",
				pikrellcam.notify_duration * EVENT_LOOP_FREQUENCY,
				event_notify_expire, &pikrellcam.video_notify);
	if (vcb->state & VCB_STATE_MOTION_RECORD)
		{
		if (!strcmp(pikrellcam.motion_preview_save_mode, "best"))
			event_add("preview save command", pikrellcam.t_now, 0,
					event_preview_save_cmd, pikrellcam.on_motion_preview_save_cmd);

		if (event)	/* a mp4 video save event needs a MP4Box child exit */
			{
			event->data = pikrellcam.on_motion_end_cmd;
			event->func = event_motion_end_cmd;
			}
		else if (*pikrellcam.on_motion_end_cmd)	/* a h264 video save */
			event_add("motion end command", pikrellcam.t_now, 0,
					event_motion_end_cmd, pikrellcam.on_motion_end_cmd);
		}
	event_add("preview dispose", pikrellcam.t_now, 0,
					event_preview_dispose, NULL);
	vcb->state = VCB_STATE_NONE;
	vcb->pause = FALSE;
	}
示例#7
0
/* Create a malloc'ed copy of the java string.
 * Caller must free it.
 */
char *get_c_string(JNIEnv *jnienv, jstring jstr)
{
	const jbyte *utf;
	char *retval;

	utf = (*jnienv)->GetStringUTFChars(jnienv, jstr, NULL);
	retval = dup_string((const char *)utf);
	(*jnienv)->ReleaseStringUTFChars(jnienv, jstr, utf);
	return retval;
}
示例#8
0
文件: class.c 项目: davidben/zephyr
static Triplet *
triplet_alloc(String *classname,
	      String *inst,
	      String *recipient)
{
    Triplet *triplet;

    triplet = (Triplet *) malloc(sizeof(Triplet));
    if (!triplet)
	return NULL;

    triplet->dest.classname = dup_string(classname);
    triplet->dest.inst = dup_string(inst);
    triplet->dest.recip = dup_string(recipient);
    triplet->clients = NULL;
    triplet->acl = NULL;

    return triplet;
}
示例#9
0
boolean
still_capture(char *fname)
	{
	Event			*event;
	int				n;
	MMAL_STATUS_T	status;
	boolean			result = FALSE;

	/* timelapse_shapshot() also uses the still_jpeg_encoder, so wait if busy.
	*/
	for (n = 0; n < 5; ++n)
		{
		if (still_jpeg_encoder.file == NULL)
			break;
		usleep(50000);
		}
	if (still_jpeg_encoder.file != NULL)
		{
		/* inform() */
		log_printf("still capture failed because jpeg encoder is busy.\n");
		return FALSE;
		}

	if ((still_jpeg_encoder.file = fopen(fname, "w")) == NULL)
		log_printf("Could not create still file %s.  %m\n", fname);
	else
		{
		if ((status = mmal_port_parameter_set_boolean(
						camera.component->output[CAMERA_CAPTURE_PORT],
						MMAL_PARAMETER_CAPTURE, 1)) != MMAL_SUCCESS)
			{
			fclose(still_jpeg_encoder.file);
			still_jpeg_encoder.file = NULL;
			log_printf("Still capture startup failed. Status %s\n",
						mmal_status[status]);
			}
		else
			{
			result = TRUE;
			log_printf("Still: %s\n", fname);
			dup_string(&pikrellcam.still_last_save, fname);
			n = pikrellcam.notify_duration * EVENT_LOOP_FREQUENCY;

			if ((event = event_find("still saved")) != NULL)
				event->count = n;	/* rapid stills, extend the time */
			else
				event_count_down_add("still saved", n,
						event_notify_expire, &pikrellcam.still_notify);
			pikrellcam.still_capture_event = TRUE;
			pikrellcam.still_notify = TRUE;
			}
		}
	return result;
	}
示例#10
0
  /* Motion events are finished with any preview jpeg handling, so delete it.
  */
void
event_preview_dispose(void)
	{
	if (! *pikrellcam.preview_filename)
		return;

	log_printf("event_preview_dispose(); removing %s\n",
					pikrellcam.preview_filename);
	unlink(pikrellcam.preview_filename);
	dup_string(&pikrellcam.preview_filename, "");
	}
示例#11
0
文件: mstrings.c 项目: khamidou/mojo
void create_string_object(void)
{
	/* init number object */
	number_object = clone_object(base_object);
	number_object->type = T_STRING;
	number_object->name = "String";
	number_object->value.s_value = dup_string("");
	
	struct Object *plus_met = clone_object(builtin_object);
	plus_met->name = "+";
	plus_met->value.c_method = (struct Object * (*)(struct Object *parent, struct Object *arg1, 
						   struct Object *arg2))num_plus;

	list_append(number_object->methods, plus_met);
}
示例#12
0
void
still_jpeg_callback(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer)
	{
	CameraObject			*data = (CameraObject *) port->userdata;
	int						n;
	static int		bytes_written;

	if (buffer->length && still_jpeg_encoder.file)
		{
		mmal_buffer_header_mem_lock(buffer);
		n = fwrite(buffer->data, 1, buffer->length, still_jpeg_encoder.file);
		bytes_written += n;
		mmal_buffer_header_mem_unlock(buffer);
		if (n != buffer->length)
			{
			log_printf("still_jpeg_callback: %s file write error.  %m\n", data->name);
			exit(1);
			}
		}
	if (buffer->flags & MMAL_BUFFER_HEADER_FLAG_FRAME_END)
		{
		fclose(still_jpeg_encoder.file);
		if (pikrellcam.still_capture_event)
			event_add("still capture command", pikrellcam.t_now, 0,
					event_still_capture_cmd,
					pikrellcam.on_still_capture_cmd);
		else if (pikrellcam.timelapse_capture_event)
			{
			if (bytes_written > 0)
				time_lapse.sequence += 1;
			else if (pikrellcam.timelapse_jpeg_last)
				{
				unlink(pikrellcam.timelapse_jpeg_last);
				dup_string(&pikrellcam.timelapse_jpeg_last, "failed");
				}
			}
		pikrellcam.still_capture_event = FALSE;
		pikrellcam.timelapse_capture_event = FALSE;
		bytes_written = 0;
		pikrellcam.state_modified = TRUE;
		still_jpeg_encoder.file = NULL;
		}
	return_buffer_to_port(port, buffer);
	}
示例#13
0
static boolean
config_string_set(char *arg, ConfigResult *result)
	{
	dup_string(result->string, arg);
	return TRUE;
	}
示例#14
0
/******************************************************************************
MODULE:  open_input

PURPOSE:  Sets up the input data structure, opens the input TOA file for
read access, opens the input brightness temp file for read access, allocates
space, and stores some of the metadata for later reference.

RETURN VALUE:
Type = Input_t*
Value      Description
-----      -----------
NULL       Error occurred opening or reading the files
non-NULL   Successful completion
 

PROJECT:  Land Satellites Data System Science Research and Development (LSRD)
at the USGS EROS

HISTORY:
Date        Programmer       Reason
--------    ---------------  -------------------------------------
1/2/2012    Gail Schmidt     Original Development (based on input routines
                             from the LEDAPS lndsr application)

NOTES:
  1. This routine opens the input TOA reflectance and brightness temperature
     files and associated SDSs.  It also allocates memory for pointers in the
     input structure.  It is up to the caller to use close_input and
     free_input to close the HDF files and free up the memory when done
     using the input data structure.
******************************************************************************/
Input_t *open_input
(
    char *refl_file_name,     /* I: input TOA reflectance filename */
    char *btemp_file_name     /* I: input brightness temp filename */
)
{
    char FUNC_NAME[] = "open_input";   /* function name */
    char errmsg[STR_SIZE];    /* error message */
    char sds_name[STR_SIZE];  /* name of the current SDS */
    int ib;                   /* index for bands */
    int ir;                   /* index for dimension rank */
    double dval[10];          /* double value for reading the attributes for
                                 the current band like fill, saturation
                                 value, and scale factor */
    Myhdf_dim_t *dim[2];      /* dimensions for the current SDS */
    Input_t *this = NULL;     /* input data structure to be initialized,
                                 populated, and returned to the caller */
    Myhdf_attr_t attr;        /* values for the SDS attributes */
    int16 *buf = NULL;        /* temporary buffer to allocate memory for
                                 the TOA reflectance bands */
  
    /* Create the Input data structure */
    this = (Input_t *) malloc (sizeof (Input_t));
    if (this == NULL) 
    {
        strcpy (errmsg, "Error allocating memory for Input data structure");
        error_handler (true, FUNC_NAME, errmsg);
        return (NULL);
    }
  
    /* Populate the filenames in the data structure */
    this->refl_file_name = dup_string (refl_file_name);
    if (this->refl_file_name == NULL)
    {
        free (this);
        strcpy (errmsg, "Error duplicating the TOA reflectance filename");
        error_handler (true, FUNC_NAME, errmsg);
        return (NULL);
    }

    this->btemp_file_name = dup_string (btemp_file_name);
    if (this->btemp_file_name == NULL)
    {
        free (this);
        strcpy (errmsg, "Error duplicating the brightness temp filename");
        error_handler (true, FUNC_NAME, errmsg);
        return (NULL);
    }
  
    /* Open the files for SD access */
    this->refl_sds_file_id = SDstart ((char *)refl_file_name, DFACC_RDONLY);
    if (this->refl_sds_file_id == HDF_ERROR)
    {
        free (this->refl_file_name);
        free (this);  
        sprintf (errmsg, "Error opening the input TOA reflectance file: %s",
            refl_file_name);
        error_handler (true, FUNC_NAME, errmsg);
        return (NULL);
    }
    this->refl_open = true;
  
    this->btemp_sds_file_id = SDstart ((char *)btemp_file_name, DFACC_RDONLY);
    if (this->btemp_sds_file_id == HDF_ERROR)
    {
        free (this->refl_file_name);
        free (this->btemp_file_name);
        free (this);  
        sprintf (errmsg, "Error opening the input brightness temperature "
            "file: %s", btemp_file_name);
        error_handler (true, FUNC_NAME, errmsg);
        return (NULL);
    }
    this->btemp_open = true;
  
    /* Get the global metadata from the input TOA reflectance file */
    if (get_input_meta (this) != SUCCESS)
    {
        free (this->refl_file_name);
        free (this->btemp_file_name);
        free (this);  
        sprintf (errmsg, "Error reading the input metadata from file: %s",
            refl_file_name);
        error_handler (true, FUNC_NAME, errmsg);
        return (NULL);
    }
  
    /* Get SDS information and start SDS access */
    for (ib = 0; ib < this->nrefl_band; ib++)
    {
        this->refl_sds[ib].name = NULL;
        this->refl_sds[ib].dim[0].name = NULL;
        this->refl_sds[ib].dim[1].name = NULL;
        this->refl_buf[ib] = NULL;
    }
  
    this->btemp_sds.name = NULL;
    this->btemp_sds.dim[0].name = NULL;
    this->btemp_sds.dim[1].name = NULL;
    this->btemp_buf = NULL;
  
    /* Loop through the image bands and obtain the SDS information */
    strcpy (errmsg, "none");
    for (ib = 0; ib < this->nrefl_band; ib++)
    {
        /* Get the SDS name and information */
        sprintf (sds_name, "%s%d", SDS_PREFIX, this->meta.refl_band[ib]);
        this->refl_sds[ib].name = dup_string (sds_name);
        if (this->refl_sds[ib].name == NULL)
        {
            sprintf (errmsg, "Error getting the SDS name for TOA reflectance "
                "band %d", ib);
            break;
        }
    
        if (get_sds_info (this->refl_sds_file_id, &this->refl_sds[ib])
            != SUCCESS)
        {
            sprintf (errmsg, "Error getting the SDS info for TOA reflectance "
                "band %d", ib);
            break;
        }
    
        /* Check rank */
        if (this->refl_sds[ib].rank != 2)
        {
            sprintf (errmsg, "Invalid rank for the SDS for TOA reflectance "
                "band %d", ib);
            break;
        }
    
        /* Check SDS type */
        if (this->refl_sds[ib].type != DFNT_INT16)
        {
            sprintf (errmsg, "Invalid data type for the SDS for TOA "
                "reflectance band %d.  Should be INT16.", ib);
            break;
        }
    
        /* Get dimensions */
        for (ir = 0; ir < this->refl_sds[ib].rank; ir++)
        {
            dim[ir] = &this->refl_sds[ib].dim[ir];
            if (get_sds_dim_info (this->refl_sds[ib].id, ir, dim[ir])
                != SUCCESS)
            {
                sprintf (errmsg, "Error obtaining the dimensions of the SDS "
                    "for TOA reflectance band %d.", ib);
                break;
            }
        }
    
        /* Save and check line and sample dimensions */
        if (ib == 0)
        {
            this->nlines = dim[0]->nval;
            this->nsamps = dim[1]->nval;
        }
        else
        {
            if (this->nlines != dim[0]->nval)
            {
                sprintf (errmsg, "Dimensions for the number of lines in TOA "
                    "reflectance band %d does not match the previous "
                    "dimensions for band 0.", ib);
                break;
            }
            if (this->nsamps != dim[1]->nval)
            {
                sprintf (errmsg, "Dimensions for the number of samples in TOA "
                    "reflectance band %d does not match the previous "
                    "dimensions for band 0.", ib);
                break;
            }
        }
    
        /* If this is the first image band read the attribute metadata */
        if (ib == 0)
        {
            /* Fill value */
            attr.type = DFNT_INT16;
            attr.nval = 1;
            attr.name = INPUT_FILL_VALUE;
            if (get_attr_double (this->refl_sds[ib].id, &attr, dval) != SUCCESS)
            {
                sprintf (errmsg, "Error reading the fill value SDS attribute "
                    "for reflectance band %d.", ib);
                break;
            }
            if (attr.nval != 1) 
            {
                sprintf (errmsg, "Invalid number of values for the fill value "
                    "for reflectance band %d.", ib);
                break;
            }
            this->refl_fill = (int) dval[0];

            /* Scale factor */
            attr.type = DFNT_FLOAT32;
            attr.nval = 1;
            attr.name = INPUT_SCALE_FACTOR;
            if (get_attr_double (this->refl_sds[ib].id, &attr, dval) != SUCCESS)
            {
                sprintf (errmsg, "Error reading the scale factor SDS "
                    "attribute for reflectance band %d.", ib);
                break;
            }
            if (attr.nval != 1) 
            {
                sprintf (errmsg, "Invalid number of values for the scale "
                    "factor for reflectance band %d.", ib);
                break;
            }
            this->refl_scale_fact = dval[0];

            /* Saturation value */
            attr.type = DFNT_INT16;
            attr.nval = 1;
            attr.name = INPUT_SATURATE_VALUE;
            if (get_attr_double (this->refl_sds[ib].id, &attr, dval) != SUCCESS)
            {
                sprintf (errmsg, "Error reading the saturation value SDS "
                    "attribute for reflectance band %d.", ib);
                break;
            }
            if (attr.nval != 1) 
            {
                sprintf (errmsg, "Invalid number of values for the saturation "
                    "value for reflectance band %d.", ib);
                break;
            }
            this->refl_saturate_val = (int) dval[0];
        }  /* end if first band */
    }  /* for ib */
  
    /* Check for any errors processing the reflectance bands and use the
       error message already created */
    if (strcmp (errmsg, "none"))
    {
        close_input (this);
        free_input (this);
        error_handler (true, FUNC_NAME, errmsg);
        return (NULL);
    }

    /* For the single thermal band, obtain the SDS information */
    strcpy (sds_name, "band6");
    this->btemp_sds.name = dup_string (sds_name);
    if (this->btemp_sds.name == NULL)
    {
        close_input (this);
        free_input (this);
        sprintf (errmsg, "Error getting the brightness temperature SDS name");
        error_handler (true, FUNC_NAME, errmsg);
        return (NULL);
    }
    
    if (get_sds_info (this->btemp_sds_file_id, &this->btemp_sds) != SUCCESS)
    {
        close_input (this);
        free_input (this);
        sprintf (errmsg, "Error getting the SDS info for the brightness "
            "temperature band");
        error_handler (true, FUNC_NAME, errmsg);
        return (NULL);
    }
    
    /* Check rank */
    if (this->btemp_sds.rank != 2)
    {
        close_input (this);
        free_input (this);
        sprintf (errmsg, "Invalid rank for the brightness temp SDS");
        error_handler (true, FUNC_NAME, errmsg);
        return (NULL);
    }
    
    /* Check SDS type */
    if (this->btemp_sds.type != DFNT_INT16)
    {
        close_input (this);
        free_input (this);
        sprintf (errmsg, "Invalid data type for the brightness temp SDS.  "
            "Should be INT16.");
        error_handler (true, FUNC_NAME, errmsg);
        return (NULL);
    }
    
    /* Get dimensions */
    for (ir = 0; ir < this->btemp_sds.rank; ir++)
    {
        dim[ir] = &this->btemp_sds.dim[ir];
        if (get_sds_dim_info (this->btemp_sds.id, ir, dim[ir]))
        {
            close_input (this);
            free_input (this);
            sprintf (errmsg, "Error obtaining the dimensions of the SDS "
                "for brightness temperature.");
            error_handler (true, FUNC_NAME, errmsg);
            return (NULL);
        }
    }
    
    /* Check line and sample dimensions with the reflectance dimensions */
    if (this->nlines != dim[0]->nval)
    {
        close_input (this);
        free_input (this);
        sprintf (errmsg, "Dimensions for the number of lines in the "
            "brightness temp band does not match the dimensions for the "
            "reflectance TOA bands.");
        error_handler (true, FUNC_NAME, errmsg);
        return (NULL);
    }
    if (this->nsamps != dim[1]->nval)
    {
        close_input (this);
        free_input (this);
        sprintf (errmsg, "Dimensions for the number of samples in the "
            "brightness temp band does not match the dimensions for the "
            "reflectance TOA bands.");
        error_handler (true, FUNC_NAME, errmsg);
        return (NULL);
    }
    
    /* Read the attribute metadata */
    /* Fill value */
    attr.type = DFNT_INT16;
    attr.nval = 1;
    attr.name = INPUT_FILL_VALUE;
    if (get_attr_double (this->btemp_sds.id, &attr, dval) != SUCCESS)
    {
        close_input (this);
        free_input (this);
        sprintf (errmsg, "Error reading the fill value SDS attribute "
            "for the brightness temperature band.");
        error_handler (true, FUNC_NAME, errmsg);
        return (NULL);
    }
    if (attr.nval != 1) 
    {
        close_input (this);
        free_input (this);
        sprintf (errmsg, "Invalid number of values for the fill value "
            "for the brightness temperature band.");
        error_handler (true, FUNC_NAME, errmsg);
        return (NULL);
    }
    this->btemp_fill = (int) dval[0];

    /* Scale factor */
    attr.type = DFNT_FLOAT32;
    attr.nval = 1;
    attr.name = INPUT_SCALE_FACTOR;
    if (get_attr_double (this->btemp_sds.id, &attr, dval) != SUCCESS)
    {
        close_input (this);
        free_input (this);
        sprintf (errmsg, "Error reading the scale factor SDS "
            "attribute for the brightness temperature band.");
        error_handler (true, FUNC_NAME, errmsg);
        return (NULL);
    }
    if (attr.nval != 1) 
    {
        close_input (this);
        free_input (this);
        sprintf (errmsg, "Invalid number of values for the scale "
            "factor for the brightness temperature band.");
        error_handler (true, FUNC_NAME, errmsg);
        return (NULL);
    }
    this->btemp_scale_fact = dval[0];

    /* Saturation value */
    attr.type = DFNT_FLOAT32;
    attr.nval = 1;
    attr.name = INPUT_SATURATE_VALUE;
    if (get_attr_double (this->btemp_sds.id, &attr, dval) != SUCCESS)
    {
        close_input (this);
        free_input (this);
        sprintf (errmsg, "Error reading the saturation value SDS "
            "attribute for the brightness temperature band.");
        error_handler (true, FUNC_NAME, errmsg);
        return (NULL);
    }
    if (attr.nval != 1) 
    {
        close_input (this);
        free_input (this);
        sprintf (errmsg, "Invalid number of values for the saturation "
            "value for the brightness temperature band.");
        error_handler (true, FUNC_NAME, errmsg);
        return (NULL);
    }
    this->btemp_saturate_val = (int) dval[0];

    /* Allocate input buffers.  TOA reflectance buffer has multiple bands.
       Thermal band has one band.  Allocate PROC_NLINES of data for each
       band. */
    buf = (int16 *) calloc (PROC_NLINES * this->nsamps * this->nrefl_band,
        sizeof (int16));
    if (buf == NULL)
    {
        close_input (this);
        free_input (this);
        sprintf (errmsg, "Error allocating memory for input TOA reflectance "
            "buffer containing %d lines.", PROC_NLINES);
        error_handler (true, FUNC_NAME, errmsg);
        return (NULL);
    }
    else
    {
        /* Set up the memory buffers for each band */
        this->refl_buf[0] = buf;
        for (ib = 1; ib < this->nrefl_band; ib++)
            this->refl_buf[ib] = this->refl_buf[ib-1] +
                PROC_NLINES * this->nsamps;
    }
  
    this->btemp_buf = (int16 *) calloc (PROC_NLINES * this->nsamps,
        sizeof (int16));
    if (this->btemp_buf == NULL)
    {
        close_input (this);
        free_input (this);
        sprintf (errmsg, "Error allocating memory for input brightness temp "
            "buffer containing %d lines.", PROC_NLINES);
        error_handler (true, FUNC_NAME, errmsg);
        return (NULL);
    }
  
    return (this);
}
示例#15
0
  /* exec a command with the given arg.  Any strftime() % replacements should
  |  have been done before calling this so there will remain only pikrellcam
  |  specific $X conversions.  Change all '$X' to '%s' and printf in what we
  |  want according to X.
  */
static int
exec_command(char *command, char *arg, boolean wait, pid_t *pid)
	{
	struct tm *tm_now;
	CompositeVector *frame_vec = &motion_frame.final_preview_vector;
	char	specifier, *fmt, *fmt_arg, *copy, *cmd_line, *name, buf[BUFSIZ];
	int		t, i, status = 0;

	if (!command || !*command)
		return -1;

	copy = strdup(command);
	cmd_line = copy;
	while (   (fmt = strchr(copy, '$')) != NULL
	       && *(fmt + 1)
	      )
		{
		specifier = *(fmt + 1);
		*fmt++ = '%';
		*fmt = 's';
		switch (specifier)
			{
			case 'F':
				fmt_arg = arg ? arg : "";
				break;
			case 'H':
				fmt_arg = pikrellcam.hostname;
				break;
			case 'E':
				fmt_arg = pikrellcam.effective_user;
				break;
			case 'I':
				fmt_arg = pikrellcam.install_dir;
				break;
			case 's':
				fmt_arg = pikrellcam.still_last;
				break;
			case 'S':
				fmt_arg = pikrellcam.still_dir;
				break;
			case 'v':
				fmt_arg = pikrellcam.video_last;
				break;
			case 'V':
				fmt_arg = pikrellcam.video_dir;
				break;
			case 't':
				fmt_arg = pikrellcam.thumb_dir;
				break;
			case 'T':
				snprintf(buf, sizeof(buf), "%05d", time_lapse.series);
				name = media_pathname(pikrellcam.video_dir,
						pikrellcam.timelapse_video_name,
						'n',  buf, '\0', NULL);
				snprintf(buf, sizeof(buf), "%s", name);
				free(name);
				fmt_arg = buf;
				dup_string(&pikrellcam.timelapse_video_pending, fmt_arg);
				break;
			case 'l':
				snprintf(buf, sizeof(buf), "%05d", time_lapse.series);
				name = strdup(pikrellcam.timelapse_format);
				name = substitute_var(name, 'n', buf);
				name = substitute_var(name, 'N', "%05d");
				snprintf(buf, sizeof(buf), "%s", name);
				free(name);
				fmt_arg = buf;
				break;
			case 'L':
				fmt_arg = pikrellcam.timelapse_dir;
				break;
			case 'a':
				fmt_arg = pikrellcam.archive_dir;
				break;
			case 'm':
				fmt_arg = pikrellcam.media_dir;
				break;
			case 'M':
				fmt_arg = pikrellcam.mjpeg_filename;
				break;
			case 'P':
				fmt_arg = pikrellcam.command_fifo;
				break;
			case 'C':
				fmt_arg = pikrellcam.script_dir;
				break;
			case 'G':
				fmt_arg = pikrellcam.log_file;
				break;
			case 'N':
				snprintf(buf, sizeof(buf), "%05d", time_lapse.sequence);
				fmt_arg = buf;
				break;
			case 'n':
				snprintf(buf, sizeof(buf), "%05d", time_lapse.series);
				fmt_arg = buf;
				break;
			case 'i':	/* width of motion area */
				t = frame_vec->box_w;
				snprintf(buf, sizeof(buf), "%d", t);
				fmt_arg = buf;
				break;
			case 'J':	/* height of motion area */
				t = frame_vec->box_h;
				snprintf(buf, sizeof(buf), "%d", t);
				fmt_arg = buf;
				break;
			case 'K':	/* center X of motion area */
				t = frame_vec->x;
				snprintf(buf, sizeof(buf), "%d", t);
				fmt_arg = buf;
				break;
			case 'Y':	/* center Y of motion area */
				t = frame_vec->y;
				snprintf(buf, sizeof(buf), "%d", t);
				fmt_arg = buf;
				break;
			case 'D':	/* current_minute dawn sunrise sunset dusk */
				tm_now = localtime(&pikrellcam.t_now);
				snprintf(buf, sizeof(buf), "%d %d %d %d %d",
						tm_now->tm_hour * 60 + tm_now->tm_min,
						sun.dawn, sun.sunrise, sun.sunset, sun.dusk);
				fmt_arg = buf;
				break;
			case 'Z':
				fmt_arg = pikrellcam.version;
				break;

			default:
				fmt_arg = "?";
				break;
			}
		if (!fmt_arg || !fmt_arg)
			log_printf("  Bad fmt_arg %p for specifier %c\n", fmt_arg, specifier);
		asprintf(&cmd_line, copy, fmt_arg);
		free(copy);
		copy = cmd_line;
		}

	log_printf("execl:[%s]\n", cmd_line);

	if ((*pid = fork()) == 0)
		{			/* child - execute command in background */
		for (i = getdtablesize(); i > 2; --i)
			close(i);
		setsid();		/* new session group - ie detach */
		execl("/bin/sh", "sh", "-c", cmd_line, " &", NULL);
		_exit (EXIT_FAILURE);
		}
	else if (*pid < 0)
		{
		perror("Fork failed.");
		status = -1;
		}
	else if (wait)		/* If parent needs to wait */
		{
		if (waitpid (*pid, &status, 0) != *pid)
			status = -1;
		}
	free(cmd_line);
	return status;
	}
示例#16
0
/* Callback when the user clicks on a PCB node in the right node treeview.
 */
static void
node_selection_changed_cb (GtkTreeSelection * selection, gpointer data)
{
  GtkTreeIter iter;
  GtkTreeModel *model;
  LibraryMenuType *node_net;
  LibraryEntryType *node;
  ConnectionType conn;
  Coord x, y;
  static gchar *node_name;

  if (selection_holdoff)	/* PCB is highlighting, user is not selecting */
    return;

  /* Toggle off the previous selection.  Look up node_name to make sure
  |  it still exists.  This toggling can get out of sync if a node is
  |  toggled selected, then the net that includes the node is selected
  |  then unselected.
  */
  if ((node = node_get_node_from_name (node_name, &node_net)) != NULL)
    {
      /* If net node belongs to has been highlighted/unhighighed, toggling
      |  if off here will get our on/off toggling out of sync.
      */
      if (node_net == node_selected_net)
        {
          toggle_pin_selected (node);
          ghid_cancel_lead_user ();
        }
      g_free (node_name);
      node_name = NULL;
    }

  /* Get the selected treeview row.
   */
  if (!gtk_tree_selection_get_selected (selection, &model, &iter))
    {
      if (node)
        ghid_invalidate_all ();
      return;
    }

  /* From the treeview row, extract the node pointer stored there and
  |  we've got a pointer to the LibraryEntryType (node) the row
  |  represents.
  */
  gtk_tree_model_get (model, &iter, NODE_LIBRARY_COLUMN, &node, -1);

  dup_string (&node_name, node->ListEntry);
  node_selected_net = selected_net;

  /* Now just toggle a select of the node on the layout
   */
  toggle_pin_selected (node);
  IncrementUndoSerialNumber ();

  /* And lead the user to the location */
  if (SeekPad (node, &conn, false))
    switch (conn.type) {
      case PIN_TYPE:
        {
          PinType *pin = (PinType *) conn.ptr2;
          x = pin->X;
          y = pin->Y;
          gui->set_crosshair (x, y, 0);
          ghid_lead_user_to_location (x, y);
          break;
        }
      case PAD_TYPE:
        {
          PadType *pad = (PadType *) conn.ptr2;
          x = pad->Point1.X + (pad->Point2.X - pad->Point1.X) / 2;
          y = pad->Point1.Y + (pad->Point2.Y - pad->Point1.Y) / 2;
          gui->set_crosshair (x, y, 0);
          ghid_lead_user_to_location (x, y);
          break;
        }
    }
}
示例#17
0
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;
	}
示例#18
0
文件: gui-dialog.c 项目: bert/pcb
/* Caller must g_slist_free() the returned list .*/
GSList *
ghid_dialog_file_select_multiple(gchar * title, gchar ** path, gchar * shortcuts)
{
  GtkWidget *dialog;
  GSList *result = NULL;
  gchar *folder, *seed;
  GHidPort *out = &ghid_port;
  GtkFileFilter *no_filter;

  dialog = gtk_file_chooser_dialog_new (title,
					GTK_WINDOW (out->top_window),
					GTK_FILE_CHOOSER_ACTION_OPEN,
					GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
					GTK_STOCK_OK, GTK_RESPONSE_OK,
					NULL);

  gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);

  gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER (dialog), TRUE);

  /* add a default filter for not filtering files */
  no_filter = gtk_file_filter_new ();
  gtk_file_filter_set_name (no_filter, "all");
  gtk_file_filter_add_pattern (no_filter, "*.*");
  gtk_file_filter_add_pattern (no_filter, "*");
  gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), no_filter);

  /* in case we have a dialog for loading schematic files */
  if (strcmp (title, _("Load schematics")) == 0)
  {
    /* add a filter for schematic files */
    GtkFileFilter *sch_filter;
    sch_filter = gtk_file_filter_new ();
    gtk_file_filter_set_name (sch_filter, "sch");
    gtk_file_filter_add_mime_type (sch_filter, "application/x-geda-schematic");
    gtk_file_filter_add_pattern (sch_filter, "*.sch");
    gtk_file_filter_add_pattern (sch_filter, "*.SCH");
    gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), sch_filter);
  }

  if (path && *path)
    gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), *path);
  else
  {
	gchar *default_path;
	default_path = g_get_current_dir();
	gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), default_path);
	g_free(default_path);
  }

  if (shortcuts && *shortcuts)
    {
      folder = g_strdup (shortcuts);
      seed = folder;
      while ((folder = strtok (seed, ":")) != NULL)
	{
	  gtk_file_chooser_add_shortcut_folder (GTK_FILE_CHOOSER (dialog),
						folder, NULL);
	  seed = NULL;
	}
      g_free (folder);
    }

  if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK)
    {
      result = gtk_file_chooser_get_filenames (GTK_FILE_CHOOSER (dialog));
      folder =
	gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (dialog));
      if (folder && path)
	{
	  dup_string (path, folder);
	  g_free (folder);
	}
    }
  gtk_widget_destroy (dialog);


  return result;
}
示例#19
0
static struct value *sys_getenv(struct info *info, struct value *n) {
    assert(n->tag == V_STRING);
    struct value *v = make_value(V_STRING, ref(info));
    v->string = dup_string(getenv(n->string->str));
    return v;
}
示例#20
0
文件: file.c 项目: ralt/tffs-lib
int32 
TFFS_fopen(
	IN	tffs_handle_t hfs,
	IN	byte * file_path,
	IN	byte * open_mode,
	OUT	tfile_handle_t * phfile)
{
	int32 ret;
	tffs_t * ptffs = (tffs_t *)hfs;
	byte * fname, * path;
	byte * dup_file_path;
	tfile_t * pfile;
	tdir_t * pdir;
	tdir_entry_t * pdir_entry;

	if (!hfs || !file_path || !open_mode || !phfile)
		return ERR_TFFS_INVALID_PARAM;

	ret = TFFS_OK;
	pfile = (tfile_t *)Malloc(sizeof(tfile_t));
	dup_file_path = dup_string(file_path);
	pdir_entry = dirent_malloc();
	fname = (byte *)Malloc(DNAME_MAX);
	pfile->secbuf = (ubyte *)Malloc(ptffs->pbs->byts_per_sec);
	Memset(pfile->secbuf, 0, ptffs->pbs->byts_per_sec);

	path = dup_file_path;
	if (!divide_path(dup_file_path, fname)) {
		ret = ERR_TFFS_INVALID_PATH;
		goto _release;
	}
	
	if (!_parse_open_mode(open_mode, &pfile->open_mode)) {
		ret = ERR_TFFS_INVALID_OPENMODE;
		goto _release;
	}

	if ((dir_init(ptffs, path, &pdir)) != DIR_OK) {
		ret = ERR_TFFS_INVALID_PATH;
		goto _release;
	}

	if (dirent_find(pdir, fname, pdir_entry) != DIRENTRY_OK) {

		DBG("%s(): can't find file [%s] at [%s]\n", __FUNCTION__, fname, path);
		if (pfile->open_mode == OPENMODE_READONLY) {
			ret = ERR_TFFS_FILE_NOT_EXIST;
			goto _release;
		}
		
		if (!dirent_init(fname, 0, TRUE, pdir_entry)) {
			ret = ERR_TFFS_INVALID_PATH;
			goto _release;
		}

		if ((ret = dir_append_direntry(pdir, pdir_entry)) != DIR_OK) {
			if (ret == ERR_DIR_NO_FREE_SPACE) {
				ret = ERR_TFFS_NO_FREE_SPACE;
			}
			else {
				ret = ERR_TFFS_DEVICE_FAIL;
			}
			goto _release;
		}
	}
	
	ret = _initialize_file(ptffs, pdir, pdir_entry, pfile);
	if (ret == FILE_OK) {
		*phfile = (tfile_handle_t)pfile;
	}

_release:
	Free(fname);
	Free(dup_file_path);
	return ret;
}
示例#21
0
文件: wells.c 项目: GitPaean/opm-core
/* ---------------------------------------------------------------------- */
int
add_well(enum WellType  type     ,
         double         depth_ref,
         int            nperf    ,
         const double  *comp_frac, /* Injection fraction or NULL */
         const int     *cells    ,
         const double  *WI       , /* Well index per perf (or NULL) */
         const char    *name     , /* Well name (or NULL) */
         struct Wells  *W        )
/* ---------------------------------------------------------------------- */
{
    int ok, nw, np, nperf_tot, off;
    int nwalloc, nperfalloc;

    struct WellMgmt *m;

    assert (W != NULL);

    nw        = W->number_of_wells;
    nperf_tot = W->well_connpos[nw];

    m = W->data;

    ok = (nw < m->well_cpty) && (nperf_tot + nperf <= m->perf_cpty);

    if (! ok) {
        nwalloc    = alloc_size(nw       , 1    , m->well_cpty);
        nperfalloc = alloc_size(nperf_tot, nperf, m->perf_cpty);

        ok = wells_reserve(nwalloc, nperfalloc, W);
    }

    off = W->well_connpos[nw];

    if (ok && (nperf > 0)) {
        assert (cells != NULL);

        memcpy(W->well_cells + off,
               cells, nperf * sizeof *W->well_cells);

        if (WI != NULL) {
            memcpy(W->WI + off, WI, nperf * sizeof *W->WI);
        }
    }

    if (ok) {
        W->type     [nw] = type     ;
        W->depth_ref[nw] = depth_ref;

        if (name != NULL) {
             /* May return NULL, but that's fine for the current
              * purpose. */
            W->name [nw] = dup_string(name);
        }

        np = W->number_of_phases;
        if (comp_frac != NULL) {
            memcpy(W->comp_frac + np*nw, comp_frac, np * sizeof *W->comp_frac);
        }

        W->well_connpos[nw + 1]  = off + nperf;
        W->number_of_wells      += 1;
    }

    return ok;
}
示例#22
0
/* Callback when the user clicks on a PCB node in the right node treeview.
 */
static void
node_selection_changed_cb (GtkTreeSelection * selection, gpointer data)
{
  GtkTreeIter iter;
  GtkTreeModel *model;
  LibraryMenuType *node_net;
  LibraryEntryType *node;
  static gchar *node_name;
	gint		x0, y0, margin;

  if (selection_holdoff)	/* PCB is highlighting, user is not selecting */
    return;

  /* Toggle off the previous selection.  Look up node_name to make sure
  |  it still exists.  This toggling can get out of sync if a node is
  |  toggled selected, then the net that includes the node is selected
  |  then unselected.
  */
  if ((node = node_get_node_from_name (node_name, &node_net)) != NULL)
    {
      /* If net node belongs to has been highlighted/unhighighed, toggling
      |  if off here will get our on/off toggling out of sync.
      */
      if (node_net == node_selected_net)
	SelectPin (node, TRUE);
      g_free (node_name);
      node_name = NULL;
    }

  /* Get the selected treeview row.
   */
  if (!gtk_tree_selection_get_selected (selection, &model, &iter))
    {
      if (node)
        ghid_invalidate_all ();
      return;
    }

  /* From the treeview row, extract the node pointer stored there and
  |  we've got a pointer to the LibraryEntryType (node) the row
  |  represents.
  */
  gtk_tree_model_get (model, &iter, NODE_LIBRARY_COLUMN, &node, -1);

  dup_string (&node_name, node->ListEntry);
  node_selected_net = selected_net;

  /* Now just toggle a select of the node on the layout and pan.
   */
  SelectPin (node, TRUE);
  IncrementUndoSerialNumber ();
	margin = gport->view_width / 20;
	if (   Crosshair.X < gport->view_x0 + margin
	    || Crosshair.X > gport->view_x0 + gport->view_width - margin
	    || Crosshair.Y < gport->view_y0 + margin
	    || Crosshair.Y > gport->view_y0 + gport->view_height - margin
	   )
	  {

	    x0 = SIDE_X (Crosshair.X) - gport->view_width / 2;
	    y0 = SIDE_Y (Crosshair.Y) - gport->view_height / 2;
	    gport->view_x0 = x0;
	    gport->view_y0 = y0;
	    ghid_pan_fixup ();
	    gui->set_crosshair (Crosshair.X, Crosshair.Y, HID_SC_WARP_POINTER);
	  }
	ghid_screen_update();
}
示例#23
0
void
multicast_recv(void)
	{
	socklen_t	addrlen;
	int			msg_id, n, nbytes = 0;
	char		*line, *eol, *s, recv_buf[1025];
	char		from[128], to[256], message[256];
	char		msg_type[32], action[256];
	boolean		repeat, match;

	if (fd_recv < 0 || !pikrellcam.multicast_enable)
		return;
	ioctl(fd_recv, FIONREAD, &nbytes);
	if (nbytes <= 0)
		return;
	addrlen = sizeof(addr_recv);
	if ((nbytes = recvfrom(fd_recv, recv_buf, sizeof(recv_buf) - 1, 0,
						(struct sockaddr *) &addr_recv, &addrlen)) <= 0)
		return;
	if (recv_buf[nbytes - 1] != '\n')
		recv_buf[nbytes++] = '\n';
	recv_buf[nbytes] = '\0';
	line = recv_buf;
	while (*line)
		{
		eol = strchr(line, '\n');
		if (!eol)
			break;
		*eol++ = '\0';
		msg_id = 0;
		repeat = FALSE;
		from[0] = to[0] = message[0] = '\0';
		n = sscanf(line, "%127s %255s %255[^\n]", from, to, message);
		if (pikrellcam.verbose_multicast)
			printf("multicast recv: <%s> <%s> <%s>\n", from, to, message);
		if ((s = strchr(from, ':')) != NULL)
			{
			*s++ = '\0';
			msg_id = atoi(s);
			repeat = multicast_message_id_repeat(from, msg_id);
			}
		if (n == 3)
			{
			if ((match = hostname_match(from, to)) && !repeat)
				{
				if (pikrellcam.verbose_multicast)
					printf("  message accepted for %s\n", pikrellcam.hostname);
				if (sscanf(message, "%31s %255[^\n]", msg_type, action) == 2)
					{
					dup_string(&pikrellcam.multicast_from_hostname, from);
					if (!strcmp(msg_type, "command"))
						exec_no_wait(action, NULL);
					else if (!strcmp(msg_type, "pkc-message"))	/* user defined */
						exec_no_wait(pikrellcam.on_multicast_message_cmd, action);
					/* ack and other message types are ignored */
					}
				else
					if (pikrellcam.verbose_multicast)
						printf("  msg_type action parse fail.\n");
				}
			else
				if (pikrellcam.verbose_multicast)
					printf("  message rejected: %s\n",
						!match ? "hostname match failed" : "repeated message");
			if (match && msg_id > 0)
				multicast_ack(from, msg_id);
			}
		line = eol;
		}
	}
示例#24
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;
		}
	}
示例#25
0
文件: file.c 项目: ralt/tffs-lib
int32
TFFS_rmfile(
	IN	tffs_handle_t hfs,
	IN	byte * file_path)
{
	int32 ret;
    byte * fname, * path;
    byte * dup_file_path;
    tdir_t * pdir;
    tffs_t * ptffs;
	tdir_entry_t * pdir_entry;

	ret = TFFS_OK;

    if (!hfs || !file_path)
        return ERR_TFFS_INVALID_PARAM;
	
    ptffs = (tffs_t *)hfs;
    dup_file_path = dup_string(file_path);
    fname = (byte *)Malloc(DNAME_MAX);
	pdir_entry = dirent_malloc();

    path = dup_file_path;
    if (!divide_path(dup_file_path, fname)) {
        ret = ERR_TFFS_INVALID_PATH;
        goto _release;
    }

    if ((dir_init(ptffs, path, &pdir)) != DIR_OK) {
        ret = ERR_TFFS_INVALID_PATH;
        goto _release;
    }

	if ((ret = dirent_find(pdir, fname, pdir_entry)) == DIRENTRY_OK) {
		if (dirent_get_dir_attr(pdir_entry) & ATTR_DIRECTORY) {
			ret = ERR_TFFS_IS_NOT_A_FILE;
			goto _release;
		}

		if (dir_del_direntry(pdir, fname) != DIR_OK) {
			ret = ERR_TFFS_REMOVE_FILE_FAIL;
			goto _release;
		}

		if (fat_free_clus(pdir->ptffs->pfat, dirent_get_clus(pdir_entry)) != FAT_OK) {
			ret = ERR_TFFS_REMOVE_FILE_FAIL;
			goto _release;
		}
		
		ret = TFFS_OK;
	}
	else {
		ret = ERR_TFFS_NO_SUCH_FILE;
	    goto _release;
    }

_release:
	Free(fname);
	Free(dup_file_path);
	dirent_release(pdir_entry);
	dir_destroy(pdir);
	return ret;
}
示例#26
0
文件: gui-dialog.c 项目: bert/pcb
/* Caller must g_free() the returned filename.*/
gchar *
ghid_dialog_file_select_open (gchar * title, gchar ** path, gchar * shortcuts)
{
  GtkWidget *dialog;
  gchar *result = NULL, *folder, *seed;
  GHidPort *out = &ghid_port;
  GtkFileFilter *no_filter;

  dialog = gtk_file_chooser_dialog_new (title,
					GTK_WINDOW (out->top_window),
					GTK_FILE_CHOOSER_ACTION_OPEN,
					GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
					GTK_STOCK_OK, GTK_RESPONSE_OK,
					NULL);

  gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);

  /* add a default filter for not filtering files */
  no_filter = gtk_file_filter_new ();
  gtk_file_filter_set_name (no_filter, "all");
  gtk_file_filter_add_pattern (no_filter, "*.*");
  gtk_file_filter_add_pattern (no_filter, "*");
  gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), no_filter);

  /* in case we have a dialog for loading a footprint file */
  if (strcmp (title, _("Load element to buffer")) == 0)
  {
    /* add a filter for footprint files */
    GtkFileFilter *fp_filter;
    fp_filter = gtk_file_filter_new ();
    gtk_file_filter_set_name (fp_filter, "fp");
    gtk_file_filter_add_mime_type (fp_filter, "application/x-pcb-footprint");
    gtk_file_filter_add_pattern (fp_filter, "*.fp");
    gtk_file_filter_add_pattern (fp_filter, "*.FP");
    gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), fp_filter);
  }

  /* in case we have a dialog for loading a layout file */
  if ((strcmp (title, _("Load layout file")) == 0)
    || (strcmp (title, _("Load layout file to buffer")) == 0))
  {
    /* add a filter for layout files */
    GtkFileFilter *pcb_filter;
    pcb_filter = gtk_file_filter_new ();
    gtk_file_filter_set_name (pcb_filter, "pcb");
    gtk_file_filter_add_mime_type (pcb_filter, "application/x-pcb-layout");
    gtk_file_filter_add_pattern (pcb_filter, "*.pcb");
    gtk_file_filter_add_pattern (pcb_filter, "*.PCB");
    gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), pcb_filter);
  }

  /* in case we have a dialog for loading a netlist file */
  if (strcmp (title, _("Load netlist file")) == 0)
  {
    /* add a filter for netlist files */
    GtkFileFilter *net_filter;
    net_filter = gtk_file_filter_new ();
    gtk_file_filter_set_name (net_filter, "netlist");
    gtk_file_filter_add_mime_type (net_filter, "application/x-pcb-netlist");
    gtk_file_filter_add_pattern (net_filter, "*.net");
    gtk_file_filter_add_pattern (net_filter, "*.NET");
    gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), net_filter);
  }

  if (path && *path)
    gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), *path);
  else
  {
	gchar *default_path;
	default_path = g_get_current_dir();
	gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), default_path);
	g_free(default_path);
  }

  if (shortcuts && *shortcuts)
    {
      folder = g_strdup (shortcuts);
      seed = folder;
      while ((folder = strtok (seed, ":")) != NULL)
	{
	  gtk_file_chooser_add_shortcut_folder (GTK_FILE_CHOOSER (dialog),
						folder, NULL);
	  seed = NULL;
	}
      g_free (folder);
    }

  if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK)
    {
      result = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
      folder =
	gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (dialog));
      if (folder && path)
	{
	  dup_string (path, folder);
	  g_free (folder);
	}
    }
  gtk_widget_destroy (dialog);


  return result;
}
示例#27
0
static pam_handle_t *
perform_gssapi (void)
{
  struct pam_conv conv = { pam_conv_func, };
  OM_uint32 major, minor;
  gss_cred_id_t server = GSS_C_NO_CREDENTIAL;
  gss_cred_id_t client = GSS_C_NO_CREDENTIAL;
  gss_buffer_desc input = GSS_C_EMPTY_BUFFER;
  gss_buffer_desc output = GSS_C_EMPTY_BUFFER;
  gss_buffer_desc local = GSS_C_EMPTY_BUFFER;
  gss_buffer_desc display = GSS_C_EMPTY_BUFFER;
  gss_name_t name = GSS_C_NO_NAME;
  gss_ctx_id_t context = GSS_C_NO_CONTEXT;
  gss_OID mech_type = GSS_C_NO_OID;
  pam_handle_t *pamh = NULL;
  OM_uint32 flags = 0;
  char *str = NULL;
  OM_uint32 caps = 0;
  int res;

  server = GSS_C_NO_CREDENTIAL;
  res = PAM_AUTH_ERR;

  /* We shouldn't be writing to kerberos caches here */
  setenv ("KRB5CCNAME", "FILE:/dev/null", 1);

  debug ("reading kerberos auth from cockpit-ws");
  input.value = read_auth_until_eof (&input.length);

  major = gss_accept_sec_context (&minor, &context, server, &input,
                                  GSS_C_NO_CHANNEL_BINDINGS, &name, &mech_type,
                                  &output, &flags, &caps, &client);

  if (GSS_ERROR (major))
    {
      warnx ("gssapi auth failed: %s", gssapi_strerror (major, minor));
      goto out;
    }

  /*
   * In general gssapi mechanisms can require multiple challenge response
   * iterations keeping &context between each, however Kerberos doesn't
   * require this, so we don't care :O
   *
   * If we ever want this to work with something other than Kerberos, then
   * we'll have to have some sorta session that holds the context.
   */
  if (major & GSS_S_CONTINUE_NEEDED)
    goto out;

  major = gss_localname (&minor, name, mech_type, &local);
  if (major == GSS_S_COMPLETE)
    {
      minor = 0;
      str = dup_string (local.value, local.length);
      debug ("mapped gssapi name to local user '%s'", str);

      if (getpwnam (str))
        {
          res = pam_start ("cockpit", str, &conv, &pamh);
        }
      else
        {
          /* If the local user doesn't exist, pretend gss_localname() failed */
          free (str);
          str = NULL;
          major = GSS_S_FAILURE;
          minor = KRB5_NO_LOCALNAME;
        }
    }

  if (major != GSS_S_COMPLETE)
    {
      if (minor == (OM_uint32)KRB5_NO_LOCALNAME || minor == (OM_uint32)KRB5_LNAME_NOTRANS)
        {
          major = gss_display_name (&minor, name, &display, NULL);
          if (GSS_ERROR (major))
            {
              warnx ("couldn't get gssapi display name: %s", gssapi_strerror (major, minor));
              goto out;
            }

          str = dup_string (display.value, display.length);
          debug ("no local user mapping for gssapi name '%s'", str);

          res = pam_start ("cockpit", str, &conv, &pamh);
        }
      else
        {
          warnx ("couldn't map gssapi name to local user: %s", gssapi_strerror (major, minor));
          goto out;
        }
    }

  if (res != PAM_SUCCESS)
    errx (EX, "couldn't start pam: %s", pam_strerror (NULL, res));

  if (pam_set_item (pamh, PAM_RHOST, rhost) != PAM_SUCCESS ||
      pam_get_item (pamh, PAM_USER, (const void **)&user) != PAM_SUCCESS)
    errx (EX, "couldn't setup pam");

  assert (user != NULL);

  res = open_session (pamh, user);

out:
  write_auth_begin (res);
  if (user)
    write_auth_string ("user", user);
  if (output.value)
    write_auth_hex ("gssapi-output", output.value, output.length);

  if (output.value)
    gss_release_buffer (&minor, &output);
  output.value = NULL;
  output.length = 0;

  if (caps & GSS_C_DELEG_FLAG && client != GSS_C_NO_CREDENTIAL)
    {
#ifdef HAVE_GSS_IMPORT_CRED
      major = gss_export_cred (&minor, client, &output);
      if (GSS_ERROR (major))
        warnx ("couldn't export gssapi credentials: %s", gssapi_strerror (major, minor));
      else if (output.value)
        write_auth_hex ("gssapi-creds", output.value, output.length);
#else
      /* cockpit-ws will complain for us, if they're ever used */
      write_auth_hex ("gssapi-creds", (void *)"", 0);
#endif
    }

  write_auth_end ();

  if (display.value)
    gss_release_buffer (&minor, &display);
  if (output.value)
    gss_release_buffer (&minor, &output);
  if (local.value)
    gss_release_buffer (&minor, &local);
  if (client != GSS_C_NO_CREDENTIAL)
    gss_release_cred (&minor, &client);
  if (server != GSS_C_NO_CREDENTIAL)
    gss_release_cred (&minor, &server);
  if (name != GSS_C_NO_NAME)
     gss_release_name (&minor, &name);
  if (context != GSS_C_NO_CONTEXT)
     gss_delete_sec_context (&minor, &context, GSS_C_NO_BUFFER);
  free (input.value);
  free (str);

  unsetenv ("KRB5CCNAME");

  if (res != PAM_SUCCESS)
    exit (5);

  return pamh;
}
示例#28
0
void
timelapse_capture(void)
	{
	char			*path, seq_buf[12], series_buf[12];
	int				n, nd;
	MMAL_STATUS_T	status;

	if (time_lapse.on_hold)
		return;

	/* still_capture()  also uses the still_jpeg_encoder, so wait if busy.
	*/
	for (n = 0; n < 5; ++n)
		{
		if (still_jpeg_encoder.file == NULL)
			break;
		usleep(50000);
		}
	if (still_jpeg_encoder.file != NULL)
		{
		log_printf("timelapse capture failed because jpeg encoder is busy.\n");
		return;
		}

	snprintf(seq_buf, sizeof(seq_buf), "%05d", time_lapse.sequence);
	snprintf(series_buf, sizeof(series_buf), "%05d", time_lapse.series);
	path = media_pathname(pikrellcam.timelapse_dir,
						pikrellcam.timelapse_format,
						'N',  seq_buf,
						'n',  series_buf);
	time_lapse.sequence += 1;

	if ((still_jpeg_encoder.file = fopen(path, "w")) == NULL)
		log_printf("Could not create timelapse file %s.  %m\n", path);
	else
		{
		if ((status = mmal_port_parameter_set_boolean(
						camera.component->output[CAMERA_CAPTURE_PORT],
						MMAL_PARAMETER_CAPTURE, 1)) != MMAL_SUCCESS)
			{
			fclose(still_jpeg_encoder.file);
			still_jpeg_encoder.file = NULL;
			log_printf("Timelapse capture startup failed. Status %s\n",
						mmal_status[status]);
			}
		else
			{
			log_printf("Timelapse still: %s\n", path);
			dup_string(&pikrellcam.timelapse_last_save, path);

			/* timelapse_capture() is an event call (inside the event loop)
			|  and we here add an event to the list.
			|  This only modifies the last event list next pointer, and
			|  the event loop is not there yet.
			*/
			nd = pikrellcam.notify_duration;
			if (nd > time_lapse.period - 3)
				nd = time_lapse.period / 2;
			if (nd > 1)
				nd *= EVENT_LOOP_FREQUENCY;
			else
				nd = EVENT_LOOP_FREQUENCY / 2;

			event_count_down_add("timelapse saved", nd,
					event_notify_expire, &pikrellcam.timelapse_notify);
			pikrellcam.timelapse_notify = TRUE;
			}
		}
	free(path);
	}