Ejemplo n.º 1
0
static void
file_recv_request_cb(GaimXfer *xfer, gpointer handle)
{
	GaimAccount *account;
	GaimBlistNode *node;
	const char *pref;
	char *filename;
	char *dirname;

	account = xfer->account;
	node = (GaimBlistNode *)gaim_find_buddy(account, xfer->who);

	if (!node)
	{
		if (gaim_prefs_get_bool(PREF_STRANGER))
			xfer->status = GAIM_XFER_STATUS_CANCEL_LOCAL;
		return;
	}

	node = node->parent;
	g_return_if_fail(GAIM_BLIST_NODE_IS_CONTACT(node));

	pref = gaim_prefs_get_string(PREF_PATH);
	switch (gaim_blist_node_get_int(node, "autoaccept"))
	{
		case FT_ASK:
			break;
		case FT_ACCEPT:
			if (ensure_path_exists(pref))
			{
				dirname = g_build_filename(pref, xfer->who, NULL);

				if (!ensure_path_exists(dirname))
				{
					g_free(dirname);
					break;
				}
				
				filename = g_build_filename(dirname, xfer->filename, NULL);

				gaim_xfer_request_accepted(xfer, filename);

				g_free(dirname);
				g_free(filename);
			}
			
			gaim_signal_connect(gaim_xfers_get_handle(), "file-recv-complete", handle,
								GAIM_CALLBACK(auto_accept_complete_cb), xfer);
			break;
		case FT_REJECT:
			xfer->status = GAIM_XFER_STATUS_CANCEL_LOCAL;
			break;
	}
}
Ejemplo n.º 2
0
PRIVATE void ensure_path_exists( char *mpath, char *base ) {
    
    if( !strcmp( mpath, base ) )
	return;

    GtkWidget *menuaction = gtk_ui_manager_get_widget( ui_manager, mpath );
    if( menuaction == NULL ) {
	char *updir = g_path_get_dirname( mpath );
	char *aname = g_path_get_basename( mpath );
	ensure_path_exists( updir, base );
	GtkAction *tmpact = gtk_action_new( aname, aname, NULL, NULL );
	gtk_action_group_add_action( component_actiongroup, tmpact );

	gtk_ui_manager_add_ui( ui_manager, 
		gtk_ui_manager_new_merge_id( ui_manager ),
		updir,
		aname,
		g_strdup(aname),
		GTK_UI_MANAGER_MENU,
		TRUE );

	//free( aname );
	//free( updir );
    }
}
Ejemplo n.º 3
0
int set_cache_dir (const char * path)
{
    if (ensure_path_exists(path, 0700)) {
        logprintfl (EUCAERROR, "failed to set cache directory to '%s'\n", path);
        return 1;
    }
    safe_strncpy (cache_path, path, EUCA_MAX_PATH);
    return 0;
}
Ejemplo n.º 4
0
int set_work_dir (const char * path)
{
    struct stat mystat;

    if (stat (path, &mystat)) {
        work_was_created = TRUE; // remember that work directory had to be created
    }
    if (ensure_path_exists(path, 0700)) {
        logprintfl (EUCAERROR, "failed to set work directory to '%s'\n", path);
        return 1;
    }
    safe_strncpy (work_path, path, EUCA_MAX_PATH);

    return 0;
}
Ejemplo n.º 5
0
/* if path=A/B/C/D but only A exists, this will try to create B and C, but not D */
int ensure_subdirectory_exists (const char * path)
{
    int len = strlen(path);
    char * path_copy = strdup(path);
    int i;

    if (path_copy==NULL) return errno;

    for (i=len-1; i>0; i--) {
		if (path[i]=='/') {
			path_copy[i] = '\0';
			ensure_path_exists (path_copy);
			break;
		}
	}
	
	free (path_copy);
	return 0;	
}
Ejemplo n.º 6
0
// if path=A/B/C but only A exists, this will try to create B, but not C
int ensure_dir_exists (const char * path, mode_t mode)
{
    int len = strlen (path);
    char * path_copy = strdup (path);
    int i, err = 0;

    if (path_copy==NULL)
        return errno;

    for (i=len-1; i>0; i--) {
        if (path[i]=='/') {
            path_copy[i] = '\0';
            err = ensure_path_exists (path_copy, mode);
            break;
        }
    }

    free (path_copy);
    return err;
}
Ejemplo n.º 7
0
PUBLIC void comp_create_action( char *menuitem, ComponentClass *k, gpointer init_data, char *name, char *label ) 
{

    char *long_name = g_path_get_basename( menuitem );
    char *base = "/ui/MainMenu/AddComp";
    char *mpath = g_strdup_printf( "%s/%s", base, menuitem );

//    GtkAction *action = g_object_new( COMPACTION_TYPE, 
//	    "component-class", k, 
//	    "init-data", init_data, 
    GtkAction *action = g_object_new( GALAN_TYPE_COMPACTION, 
	    "klass", k, 
	    "init_data", init_data, 

	    "name", g_strdup(name),
	    "label", long_name,
	    "short-label", g_strdup(name),
	    "hide-if-empty", FALSE,

	    NULL );

    gtk_action_group_add_action( component_actiongroup, action );

    char *dir_path = g_path_get_dirname( mpath);
    ensure_path_exists( dir_path, base );
    
    //XXX: the half baked tree model
    GtkTreeIter iter;
  galan_comptree_model_lookup( tmodel, menuitem, &iter, TRUE );
  gtk_tree_store_set( GTK_TREE_STORE(tmodel), &iter, 1, TRUE, 2, action, -1 );
    //XXX:

    //printf( "name  = %s\n", gtk_action_get_name( action ) );
    gtk_ui_manager_add_ui( ui_manager, 
	    gtk_ui_manager_new_merge_id( ui_manager ),
	    dir_path,
	    name,
	    name,
	    GTK_UI_MANAGER_MENUITEM,
	    TRUE );
}
Ejemplo n.º 8
0
int reserve_cache_slot (disk_item * di)
{
    // TODO: check if there is enough disk space?

    if (cache_limit==EUCA_SIZE_UNLIMITED) { // cache is always big enough, we never purge
        cache_used += di->total_size;
        goto create;
    }

    if (di->total_size > cache_limit) // cache isn't big enough
        return ERROR;

    while (di->total_size > (cache_limit-cache_used) ) {
        time_t oldest_mtime = time (NULL) + 1;
        off_t  oldest_size = 0;
        disk_item * oldest_entry = NULL;
        struct stat mystat;
        disk_item * e;

        // run through cache and find the LRU entry
        for ( e = cache_head; e; e=e->next) {
            if (stat (e->path, &mystat)<0) {
                logprintfl (EUCAERROR, "error: ok_to_cache() can't stat %s\n", e->path);
                return ERROR;
            }
            if (mystat.st_mtime<oldest_mtime) {
                oldest_mtime = mystat.st_mtime;
                oldest_size = e->total_size; // (mystat.st_size doesn't include digest)
                oldest_entry = e;
            } else {
                if (mystat.st_mtime==oldest_mtime) { // with same age, smaller ones get purged first
                    if (oldest_size > e->total_size) {
                        oldest_size = e->total_size;
                        oldest_entry = e;
                    }
                }
            }
        }

        if ( oldest_entry ) { // remove it
            logprintfl (EUCAINFO, "purging from cache entry %s\n", oldest_entry->base);
            if ( oldest_entry->next ) {
                oldest_entry->next->prev = oldest_entry->prev;
            }
            if ( oldest_entry->prev ) {
                oldest_entry->prev->next = oldest_entry->next;
            } else {
                cache_head = oldest_entry->next;
            }
            delete_disk_item (oldest_entry);
            cache_used -= oldest_entry->total_size;
            free_disk_item (oldest_entry);
        } else {
            logprintfl (EUCAERROR, "error: cannot find oldest entry in cache\n");
            return 1;
        }
    }

 create:

    if (ensure_path_exists (di->base, 0700)) {
        logprintfl (EUCAERROR, "error: failed to create cache entry '%d'\n", di->base);
        return ERROR;
    }

    add_to_cache (di);

    return OK;
}
Ejemplo n.º 9
0
/* returns size of the file in bytes if OK, otherwise a negative error */
static long long get_cached_file (const char * user_id, const char * url, const char * file_id, const char * instance_id, const char * file_name, char * file_path, sem * s, int convert_to_disk, long long limit_mb) 
{
    char tmp_digest_path [BUFSIZE];
	char cached_dir      [BUFSIZE]; 
	char cached_path     [BUFSIZE];
	char staging_path    [BUFSIZE];
	char digest_path     [BUFSIZE];

	snprintf (file_path,       BUFSIZE, "%s/%s/%s/%s",    sc_instance_path, user_id, instance_id, file_name);
	snprintf (tmp_digest_path, BUFSIZE, "%s-digest",      file_path);
	snprintf (cached_dir,      BUFSIZE, "%s/%s/cache/%s", sc_instance_path, EUCALYPTUS_ADMIN, file_id); /* cache is in admin's directory */
	snprintf (cached_path,     BUFSIZE, "%s/%s",          cached_dir, file_name);
	snprintf (staging_path,    BUFSIZE, "%s-staging",     cached_path);
	snprintf (digest_path,     BUFSIZE, "%s-digest",      cached_path);

retry:

    /* under a lock, figure out the state of the file */
    sem_p (sc_sem); /***** acquire lock *****/
    ensure_subdirectory_exists (file_path); /* creates missing directories */

	struct stat mystat;
    int cached_exists  = ! stat (cached_path, &mystat);
    int staging_exists = ! stat (staging_path, &mystat);

    int e = ERROR;
    int action;
    enum { ABORT, VERIFY, WAIT, STAGE };
    if ( staging_exists ) {
        action = WAIT;
    } else {
        if ( cached_exists ) {
            action = VERIFY;
        } else {
            action = STAGE;
        }
    }

    /* we return the sum of these */
    long long file_size_b = 0;
    long long digest_size_b = 0;
   
    /* while still under lock, decide whether to cache */
    int should_cache = 0;
    if (action==STAGE) { 
        e = walrus_object_by_url (url, tmp_digest_path, 0); /* get the digest to see how big the file is */
        if (e==OK && stat (tmp_digest_path, &mystat)) {
            digest_size_b = (long long)mystat.st_size;
        }
        if (e==OK) {
            /* pull the size out of the digest */
            char * xml_file = file2str (tmp_digest_path);
            if (xml_file) {
                file_size_b = str2longlong (xml_file, "<size>", "</size>");
                free (xml_file);
            }
            if (file_size_b > 0) {
                long long full_size_b = file_size_b+digest_size_b;
                if (convert_to_disk) {
                    full_size_b += swap_size_mb*MEGABYTE + MEGABYTE; /* TODO: take into account extra padding required for disks (over partitions) */
                }
                if ( full_size_b/MEGABYTE + 1 > limit_mb ) {
                    logprintfl (EUCAFATAL, "error: insufficient disk capacity remaining (%lldMB) in VM Type of instance %s for component %s\n", limit_mb, instance_id, file_name);
                    action = ABORT;
                    
                } else if ( ok_to_cache (cached_path, full_size_b) ) { /* will invalidate the cache, if needed */
                    ensure_path_exists (cached_dir); /* creates missing directories */
                    should_cache = 1;
                    if ( touch (staging_path) ) { /* indicate that we'll be caching it */
                        logprintfl (EUCAERROR, "error: failed to create staging file %s\n", staging_path);
                        action = ABORT;
                    }
                }
            } else {
                logprintfl (EUCAERROR, "error: failed to obtain file size from digest %s\n", url);
                action = ABORT;
            }
        } else {
            logprintfl (EUCAERROR, "error: failed to obtain digest from %s\n", url);
            action = ABORT;
        }
    }
    sem_v (sc_sem); /***** release lock *****/
    
    switch (action) {
    case STAGE:
        logprintfl (EUCAINFO, "downloding image into %s...\n", file_path);		
        e = walrus_image_by_manifest_url (url, file_path, 1);

        /* for KVM, convert partition into disk */
        if (e==OK && convert_to_disk) { 
            sem_p (s);
            /* for the cached disk swap==0 and ephemeral==0 as we'll append them below */
            if ((e=vrun("%s %s %d %d", disk_convert_command_path, file_path, 0, 0))!=0) {
                logprintfl (EUCAERROR, "error: partition-to-disk image conversion command failed\n");
            }
            sem_v (s);
            
            /* recalculate file size now that it was converted */
            if ( stat (file_path, &mystat ) != 0 ) {
                logprintfl (EUCAERROR, "error: file %s not found\n", file_path);
            } else if (mystat.st_size < 1) {
                logprintfl (EUCAERROR, "error: file %s has the size of 0\n", file_path);
            } else {
                file_size_b = (long long)mystat.st_size;
            }
        }

        /* cache the partition or disk, if possible */
        if ( e==OK && should_cache ) {
            if ( (e=vrun ("cp -a %s %s", file_path, cached_path)) != 0) {
                logprintfl (EUCAERROR, "failed to copy file %s into cache at %s\n", file_path, cached_path);
            }
            if ( e==OK && (e=vrun ("cp -a %s %s", tmp_digest_path, digest_path)) != 0) {
                logprintfl (EUCAERROR, "failed to copy digest file %s into cache at %s\n", tmp_digest_path, digest_path);
            }
        }
        
        sem_p (sc_sem);
        if (should_cache) {
            unlink (staging_path);            
        }
        if ( e ) {
            logprintfl (EUCAERROR, "error: failed to download file from Walrus into %s\n", file_path);
            unlink (file_path);
            unlink (tmp_digest_path);
            if (should_cache) {
                unlink (cached_path);
                unlink (digest_path);
                if ( rmdir(cached_dir) ) {
                    logprintfl (EUCAWARN, "warning: failed to remove cache directory %s\n", cached_dir);
                }
            }
        }
        sem_v (sc_sem);
        break;
        
    case WAIT:
        logprintfl (EUCAINFO, "waiting for disapperance of %s...\n", staging_path);
        /* wait for staging_path to disappear, which means both either the
         * download succeeded or it failed */
        if ( (e=wait_for_file (NULL, staging_path, 180, "cached image")) ) 
            return 0L;        
        /* yes, it is OK to fall through */
        
    case VERIFY:
        logprintfl (EUCAINFO, "verifying cached file in %s...\n", cached_path);
        sem_p (sc_sem); /***** acquire lock *****/
        e = ERROR;
        if ( stat (cached_path, &mystat ) != 0 ) {
            logprintfl (EUCAERROR, "error: file %s not found\n", cached_path);
        } else if (mystat.st_size < 1) {
            logprintfl (EUCAERROR, "error: file %s has the size of 0\n", cached_path);
        } else if ((e=walrus_verify_digest (url, digest_path))<0) {
            /* negative status => digest changed */
            unlink (cached_path);
            unlink (staging_path); /* TODO: needed? */
            unlink (digest_path);
            if ( rmdir (cached_dir) ) {
                logprintfl (EUCAWARN, "warning: failed to remove cache directory %s\n", cached_dir);
            } else {
                logprintfl (EUCAINFO, "due to failure, removed cache directory %s\n", cached_dir);
            }
        } else {
            file_size_b = mystat.st_size;

            /* touch the digest so cache can use mtime for invalidation */
            if ( touch (digest_path) ) {
                logprintfl (EUCAERROR, "error: failed to touch digest file %s\n", digest_path);
            } else if ( stat (digest_path, &mystat) ) {
                logprintfl (EUCAERROR, "error: digest file %s not found\n", digest_path);
            } else {
                digest_size_b = (long long)mystat.st_size;
            }
        }
        sem_v (sc_sem); /***** release lock *****/
        
        if (e<0) { /* digest changed */
            if (action==VERIFY) { /* i.e. we did not download/waited for this file */
                /* try downloading anew */
                goto retry;
            } else {
                logprintfl (EUCAERROR, "error: digest mismatch, giving up\n");
                return 0L;
            }
        } else if (e>0) { /* problem with file or digest */
            return 0L;
            
        } else { /* all good - copy it, finally */
            ensure_subdirectory_exists (file_path); /* creates missing directories */            
            if ( (e=vrun ("cp -a %s %s", cached_path, file_path)) != 0) {
                logprintfl (EUCAERROR, "failed to copy file %s from cache at %s\n", file_path, cached_path);
                return 0L;
            }
        }
        break;
        
    case ABORT:
        logprintfl (EUCAERROR, "get_cached_file() failed (errno=%d)\n", e);
        e = ERROR;
    }

    if (e==OK && file_size_b > 0 && convert_to_disk ) { // if all went well above
        long long ephemeral_mb = limit_mb - swap_size_mb - (file_size_b+digest_size_b)/MEGABYTE;
        if ( swap_size_mb>0L || ephemeral_mb>0L ) {
            sem_p (s);
            if ((e=vrun("%s %s %lld %lld", disk_convert_command_path, file_path, swap_size_mb, ephemeral_mb))!=0) {
                logprintfl (EUCAERROR, "error: failed to add swap or ephemeral to the disk image\n");
            }
            sem_v (s);

            /* recalculate file size (again!) now that it was converted */
            if ( stat (file_path, &mystat ) != 0 ) {
                logprintfl (EUCAERROR, "error: file %s not found\n", file_path);
            } else if (mystat.st_size < 1) {
                logprintfl (EUCAERROR, "error: file %s has the size of 0\n", file_path);
            } else {
                file_size_b = (long long)mystat.st_size;
            }
        }
    }

    if (e==OK && action!=ABORT)
        return file_size_b + digest_size_b;
    return 0L;
}
Ejemplo n.º 10
0
static void
file_recv_request_cb(PurpleXfer *xfer, gpointer handle)
{
	PurpleAccount *account;
	PurpleBlistNode *node;
	const char *pref;
	char *filename;
	char *dirname;

    int accept_setting;

	account = xfer->account;
	node = PURPLE_BLIST_NODE(purple_find_buddy(account, xfer->who));

	/* If person is on buddy list, use the buddy setting; otherwise, use the
	   stranger setting. */
	if (node) {
		node = purple_blist_node_get_parent(node);
		g_return_if_fail(PURPLE_BLIST_NODE_IS_CONTACT(node));
		accept_setting = purple_blist_node_get_int(node, "autoaccept");
	} else {
		accept_setting = purple_prefs_get_int(PREF_STRANGER);
	}

	switch (accept_setting)
	{
		case FT_ASK:
			break;
		case FT_ACCEPT:
            pref = purple_prefs_get_string(PREF_PATH);
			if (ensure_path_exists(pref))
			{
				int count = 1;
				const char *escape;
				gchar **name_and_ext;
				const gchar *name;
				gchar *ext;

				if (purple_prefs_get_bool(PREF_NEWDIR))
					dirname = g_build_filename(pref, purple_normalize(account, xfer->who), NULL);
				else
					dirname = g_build_filename(pref, NULL);

				if (!ensure_path_exists(dirname))
				{
					g_free(dirname);
					break;
				}

				/* Escape filename (if escaping is turned on) */
				if (purple_prefs_get_bool(PREF_ESCAPE)) {
					escape = purple_escape_filename(xfer->filename);
				} else {
					escape = xfer->filename;
				}
				filename = g_build_filename(dirname, escape, NULL);

				/* Split at the first dot, to avoid uniquifying "foo.tar.gz" to "foo.tar-2.gz" */
				name_and_ext = g_strsplit(escape, ".", 2);
				name = name_and_ext[0];
				g_return_if_fail(name != NULL);
				if (name_and_ext[1] != NULL) {
					/* g_strsplit does not include the separator in each chunk. */
					ext = g_strdup_printf(".%s", name_and_ext[1]);
				} else {
					ext = g_strdup("");
				}

				/* Make sure the file doesn't exist. Do we want some better checking than this? */
				/* FIXME: There is a race here: if the newly uniquified file name gets created between
				 *        this g_file_test and the transfer starting, the file created in the meantime
				 *        will be clobbered. But it's not at all straightforward to fix.
				 */
				while (g_file_test(filename, G_FILE_TEST_EXISTS)) {
					char *file = g_strdup_printf("%s-%d%s", name, count++, ext);
					g_free(filename);
					filename = g_build_filename(dirname, file, NULL);
					g_free(file);
				}

				purple_xfer_request_accepted(xfer, filename);

				g_strfreev(name_and_ext);
				g_free(ext);
				g_free(dirname);
				g_free(filename);
			}

			purple_signal_connect(purple_xfers_get_handle(), "file-recv-complete", handle,
								PURPLE_CALLBACK(auto_accept_complete_cb), xfer);
			break;
		case FT_REJECT:
			xfer->status = PURPLE_XFER_STATUS_CANCEL_LOCAL;
			break;
	}
}