Beispiel #1
0
/****************************************************************************
 * Name: tash_cd
 *
 * Description:
 *   change current working directory
 *
 * Usage:
 *   cd <directory or - or .. or ~>
 ****************************************************************************/
static int tash_cd(int argc, char **args)
{
	const char *path = args[1];
	char *temp = NULL;
	int ret;

	if (argc < 2 || strcmp(path, "~") == 0) {
		path = CONFIG_LIB_HOMEDIR;
	} else if (strcmp(path, "-") == 0) {
		temp = strdup(getwd(OLD_PWD));
		path = temp;
	} else if (strcmp(path, "..") == 0) {
		temp = strdup(getwd(PWD));
		path = dirname(temp);
	} else {
		temp = get_fullpath(path);
		path = temp;
	}
	ret = chdir(path);
	if (ret != 0) {
		FSCMD_OUTPUT(CMD_FAILED, args[0], path);
		ret = ERROR;
	}

	fscmd_free(temp);

	return ret;
}
Beispiel #2
0
int FOListViewItem::compare ( QListViewItem * i, int col, bool ascending ) const
{
  FOListViewItem *foi=(FOListViewItem *)i;

  std::string fp=get_fullpath();
  std::string fpi=foi->get_fullpath();


  if ((is_dir(fp) && is_dir(fpi)) || (!is_dir(fp) && !is_dir(fpi)) )
  {
    // compare filename
    std::string fn=basename();
    std::string fni=foi->basename();
    if (fn > fni)
      return 1;
    else
      return -1;

  }

  if (is_dir(fp) && !is_dir(fpi))
    return -1;
  if (!is_dir(fp) && is_dir(fpi))
    return 1;
  return 0; // should not go here
}
Beispiel #3
0
static void trace_truncate(const char *path, off_t length) {
    debug("trace_truncate %s %lu", path, length);

    char *fullpath = get_fullpath(path);
    if (fullpath == NULL) {
        return;
    }

    tprintf("file: '%s' %lu 0 0\n", fullpath, length);
}
Beispiel #4
0
static void trace_open(const char *path, int fd) {
    debug("trace_open %s %d", path, fd);

    char *fullpath = get_fullpath(path);
    if (fullpath == NULL) {
        return;
    }

    trace_file(fullpath, fd);
}
Beispiel #5
0
/**
 * Read source code into buffer.
 *
 * Returned value must be freed with jmem_heap_free_block if it's not NULL.
 * @return NULL, if read or allocation has failed
 *         pointer to the allocated memory block, otherwise
 */
static const uint8_t *
read_file (const char *file_name, /**< source code */
           size_t *out_size_p) /**< [out] number of bytes successfully read from source */
{
  FILE *file = fopen (get_fullpath(file_name), "r");
  if (file == NULL)
  {
    jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: cannot open file: %s\n", file_name);
    return NULL;
  }

  int fseek_status = fseek (file, 0, SEEK_END);
  if (fseek_status != 0)
  {
    jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Failed to seek (error: %d)\n", fseek_status);
    fclose (file);
    return NULL;
  }

  long script_len = ftell (file);
  if (script_len < 0)
  {
    jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Failed to get the file size(error %ld)\n", script_len);
    fclose (file);
    return NULL;
  }

  rewind (file);

  uint8_t *buffer = jmem_heap_alloc_block_null_on_error (script_len);

  if (buffer == NULL)
  {
    jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Out of memory error\n");
    fclose (file);
    return NULL;
  }

  size_t bytes_read = fread (buffer, 1u, script_len, file);

  if (!bytes_read || bytes_read != script_len)
  {
    jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: failed to read file: %s\n", file_name);
    jmem_heap_free_block ((void*) buffer, script_len);

    fclose (file);
    return NULL;
  }

  fclose (file);

  *out_size_p = bytes_read;
  return (const uint8_t *) buffer;
} /* read_file */
Beispiel #6
0
/****************************************************************************
 * Name: tash_umount
 *
 * Description:
 *   Unmount specific file system.
 *
 * Usage:
 *   umount <mounted directory>
 ****************************************************************************/
static int tash_umount(int argc, char **args)
{
	char *path = get_fullpath(args[1]);
	int ret = ERROR;

	if (path) {
		ret = umount(path);
		if (ret < 0) {
			FSCMD_OUTPUT(CMD_FAILED, args[0], args[1]);
		}
		fscmd_free(path);
	}

	return ret;
}
Beispiel #7
0
/****************************************************************************
 * Name: tash_mkdir
 *
 * Description:
 *   create directory
 *
 * Usage:
 *   mkdir [directory name]
 ****************************************************************************/
static int tash_mkdir(int argc, char **args)
{
	char *fullpath;
	int ret = ERROR;

	fullpath = get_fullpath(args[1]);
	if (fullpath) {
		ret = mkdir(fullpath, 0777);
		if (ret < 0) {
			FSCMD_OUTPUT(CMD_FAILED, args[0], "mkdir");
		}
		fscmd_free(fullpath);
	}

	return ret;
}
Beispiel #8
0
/****************************************************************************
 * Name: tash_rm
 *
 * Description:
 *   unlink target file
 *
 * Usage:
 *   rm [file path]
 ****************************************************************************/
static int tash_rm(int argc, char **args)
{
	char *fullpath;
	int ret = ERROR;

	fullpath = get_fullpath(args[1]);
	if (fullpath) {
		ret = unlink(fullpath);
		if (ret < 0) {
			FSCMD_OUTPUT(CMD_FAILED, args[0], "unlink");
		}
		fscmd_free(fullpath);
	}

	return ret;
}
Beispiel #9
0
CL_String CL_PathHelp::get_basepath(
	const CL_String &fullname,
	PathType path_type)
{
	CL_String path = get_fullpath(fullname, path_type);
#ifdef WIN32
	if (path_type == path_type_file && path.length() >= 2)
	{
		if (path[1] == ':')
			return path.substr(2);

		if (path[0] == '\\' && path[1] == '\\')
		{
			CL_String::size_type pos = path.find_first_of("/\\", 2);
			if (pos == CL_String::npos)
				return CL_String();
			else
				return path.substr(pos);
		}
	}
#endif
	return path;
}
Beispiel #10
0
/****************************************************************************
 * Name: tash_ls
 *
 * Description:
 *   Show contents of directory of specific directory.
 *   -R : shows contents recursively.
 *   -l  : shows size & attributes of contents
 *   -s : size of contents
 *
 * Usage:
 *   ls [-lRs] <directory>
 ****************************************************************************/
static int tash_ls(int argc, char **args)
{
	struct stat st;
	const char *relpath;
	unsigned int lsflags = 0;
	char *fullpath;
	int ret;
	int option;
	int badarg = false;

	optind = -1;
	while ((option = getopt(argc, args, "lRs")) != ERROR) {
		switch (option) {
		case 'l':
			lsflags |= (LSFLAGS_SIZE | LSFLAGS_LONG);
			break;

		case 'R':
			lsflags |= LSFLAGS_RECURSIVE;
			break;

		case 's':
			lsflags |= LSFLAGS_SIZE;
			break;

		case '?':
		default:
			badarg = true;
			break;
		}
	}
	if (badarg) {
		FSCMD_OUTPUT(INVALID_ARGS " : [-lRs] <dir-path>\n", args[0]);
		return 0;
	}

	if (optind + 1 < argc) {
		FSCMD_OUTPUT(TOO_MANY_ARGS, args[0]);
		return ERROR;
	} else if (optind >= argc) {
		relpath = getwd(PWD);
	} else {
		relpath = args[optind];
	}

	fullpath = get_fullpath(relpath);
	if (!fullpath) {
		return ERROR;
	}
	if (stat(fullpath, &st) < 0) {
		FSCMD_OUTPUT(CMD_FAILED, args[0], "stat");
		ret = ERROR;
	} else if (!S_ISDIR(st.st_mode)) {
		/*
		 * Pass a null dirent to ls_handler to signify
		 * that this is a single file
		 */
		ret = ls_handler(fullpath, NULL, (void *)lsflags);
	} else {
		/* List the directory contents */
		FSCMD_OUTPUT("%s:\n", fullpath);
		ret = foreach_direntry("ls", fullpath, ls_handler, (void *)lsflags);
		if (ret == OK && (lsflags & LSFLAGS_RECURSIVE) != 0) {
			/*
			 * Then recurse to list each directory
			 * within the directory
			 */
			ret = foreach_direntry("ls", fullpath, ls_recursive, (void *)lsflags);
		}
	}

	fscmd_free(fullpath);

	return ret;
}
Beispiel #11
0
/** process_directory
 * A recursive fuction that processes all directories
 * 
 * Parameters:
 *     struct Filename *file - the names associated with the file
 */
void*
process_directory(void *val){
	DIR *dptr;
	struct dirent *entry;
	struct dirent *ent_buf;
	struct Thread_args *ta;
	
	unsigned int my_flags;
	int max_depth;
	int path_max;
	
	ta = malloc(sizeof(struct Thread_args));
	if(ta == NULL){
		exit(EXIT_FAILURE);
	}
	ta = (struct Thread_args*)val;
	
	my_flags = ta->gl->my_flags;
	max_depth = ta->gl->max_depth;
	path_max = ta->gl->path_max;
	
	errno = 0;
	if((dptr = opendir(ta->fe->file->realptr)) == NULL){
		/* If the file was not opened successfully then print an error and 
		   move on to the next file */
		if(errno != 0){
			/* If an error occurred opening the file then print a message */
			if(ta->fe->file->is_cmd_line || (my_flags&QUIET) != QUIET){
				/* If the file was specified on the commandline or if the -q
	           	   flag was not selected then print the error */
				pthread_mutex_lock(&mu);
				if(ta->gl->is_network){
					char *output;

					output = calloc(sizeof(char), ta->gl->path_max);
					sprintf(output, "%s: %s\n", strerror(errno), ta->fe->file->name);
					write_error_line(output, ta->gl);
					free(output);
				}
				fprintf(stderr, "%s: %s\n", strerror(errno), ta->fe->file->name);
				pthread_mutex_unlock(&mu);
			}
			else{
				/* If the file error was not printed then increment the 
			   	   corresponding counter */
				ta->fe->file->counters->err_not_printed++;
			}
			if(ta->fe->file->counters->num_recurse == 0){
				pthread_mutex_lock(&mu);
				(*(ta->gl->num_threads))--;
				pthread_mutex_unlock(&mu);
			}
			ta->fe->file->counters->num_recurse--;
			check_print_counters(ta->fe, ta->gl);
			return NULL;
		}
	}
	
	if(deal_with_cstack(ta->fe, dptr, ta->gl) == FAILURE){
		/* If an error occurred adding the directory to the stack then return */
		if(ta->fe->file->counters->num_recurse == 0){
			pthread_mutex_lock(&mu);
			(*(ta->gl->num_threads))--;
			pthread_mutex_unlock(&mu);
		}
		ta->fe->file->counters->num_recurse--;
		check_print_counters(ta->fe, ta->gl);
		return NULL;
	}
	
	ent_buf = malloc(/*sizeof(struct dirent)*/path_max);
	if(ent_buf == NULL){
		/* If memory allocation failed, print an error */
		exit(EXIT_FAILURE);
	}
	
	while(1){
		int status;
		struct Filename *newfile;
		
		readdir_r(dptr, ent_buf, &entry);
		if(entry == NULL){
			break;
		}

		if(entry->d_name[0] == '.'){
			/* Handle hidden files separately */
			if((my_flags&DO_DOTS) == DO_DOTS){
				/* Handles the -a flag if it was selected */
				if(strcmp("..", entry->d_name) == 0 
						|| strcmp(".", entry->d_name) == 0){
					/* If the hidden directory is . or .. then ignore it */
					continue;
				}
				ta->fe->file->counters->dot_processed++;
			}
			else{
				/* If the -a flag wasn't selected then ignore the hidden file */
				continue;
			}
		}
		
		newfile = malloc(sizeof(struct Filename));
		if(newfile == NULL){
			/* If memory allocation failed, print an error */
			exit(EXIT_FAILURE);
		}
		newfile->name = malloc(path_max);
		newfile->realptr = malloc(path_max);
		newfile->fullptr = malloc(path_max);
		if(newfile->name == NULL || newfile->realptr == NULL || newfile->fullptr == NULL){
			/* If memory allocation failed, print an error */
			exit(EXIT_FAILURE);
		}
		strcpy(newfile->realptr, ta->fe->file->realptr);
		strcpy(newfile->name, entry->d_name);
		newfile->is_cmd_line = false;
		
		get_fullpath(newfile, &newfile->fullptr, ta->gl);
		if(newfile->fullptr == NULL){
			/* Continue onto the next file if there was a failure getting the 
			   realpath of this one */
			combine_counters(newfile->counters, ta->gl);
			continue;
		}
		
		newfile->counters = NULL;
		initialize_counters(&(newfile->counters));
		
		if(handle_link(newfile, ta->gl) == true){
			/* Try to handle a link. */
			combine_counters(newfile->counters, ta->gl);
			continue;
		}
		
		status = is_directory(newfile->fullptr, newfile, ta->gl);
		if(status == 1){
			/* Processes another directory */
			struct Thread_args *newta;
			pthread_t threadid;
			DIR *newdptr;

			newta = malloc(sizeof(struct Thread_args));
			if(newta == NULL){
				exit(EXIT_FAILURE);
			}
	
			newta->gl = malloc(sizeof(struct Globals));
			if(newta->gl == NULL){
				exit(EXIT_FAILURE);
			}
			
			/*****HERE UPDATE*****/
			newta->gl->my_flags = ta->gl->my_flags;
			newta->gl->num_chars = ta->gl->num_chars;
			newta->gl->max_lines = ta->gl->max_lines;
			newta->gl->max_depth = ta->gl->max_depth;
			newta->gl->path_max = ta->gl->path_max;
			newta->gl->allowed_threads = ta->gl->allowed_threads;
			newta->gl->num_threads = &(*(ta->gl->num_threads));
			newta->gl->machine = &(*(ta->gl->machine));
			newta->gl->is_printed = &(*(ta->gl->is_printed));
			newta->gl->final_counters = &(*(ta->gl->final_counters));
			newta->gl->donecmdln = &(*(ta->gl->donecmdln));
			newta->gl->is_network = ta->gl->is_network;
			newta->gl->num_networking = &(*(ta->gl->num_networking));
			newta->gl->fd = ta->gl->fd;
			
			newta->fe = malloc(sizeof(struct elem));
			if(newta->fe == NULL){
				exit(EXIT_FAILURE);
			}
			
			strcpy(newfile->realptr, ta->fe->file->name);
			if(newfile->realptr[strlen(newfile->realptr)-1] != '/')
				strcat(newfile->realptr, "/");
			strcat(newfile->realptr, entry->d_name);
			strcpy(newfile->name, newfile->realptr);
			
			free(newfile->realptr);
			get_realpath(newfile, &newfile->realptr, ta->gl);
			if(newfile->realptr == NULL){
				/* Continue onto the next file if there was a failure getting the 
				   realpath of this one */
				combine_counters(newfile->counters, newta->gl);
				continue;
			}
			
			pthread_mutex_lock(&mu);
			cstack_add(newfile, ta->fe, &newta->fe);
			pthread_mutex_unlock(&mu);
			
			errno = 0;
			if((newdptr = opendir(newta->fe->file->realptr)) == NULL){
				/* If the file was not opened successfully then print an error and 
				   move on to the next file */
				if(errno != 0){
					/* If an error occurred opening the file then print a message */
					if(newta->fe->file->is_cmd_line || (my_flags&QUIET) != QUIET){
						/* If the file was specified on the commandline or if the -q
			           	   flag was not selected then print the error */
						pthread_mutex_lock(&mu);
						if(newta->gl->is_network){
							char *output;

							output = calloc(sizeof(char), newta->gl->path_max);
							sprintf(output, "%s: %s\n", strerror(errno), newta->fe->file->name);
							write_error_line(output, newta->gl);
							free(output);
						}
						fprintf(stderr, "%s: %s\n", strerror(errno), newta->fe->file->name);
						pthread_mutex_unlock(&mu);
					}
					else{
						/* If the file error was not printed then increment the 
					   	   corresponding counter */
						newta->fe->file->counters->err_not_printed++;
					}
					if(newta->fe->file->counters->num_recurse == 0){
						pthread_mutex_lock(&mu);
						(*(ta->gl->num_threads))--;
						pthread_mutex_unlock(&mu);
					}
					combine_counters(newfile->counters, newta->gl);
					check_print_counters(newta->fe, ta->gl);
					continue;
				}
			}
	
			if(deal_with_cstack(newta->fe, newdptr, ta->gl) == FAILURE){
				/* If an error occurred adding the directory to the stack then return */
				if(ta->fe->file->counters->num_recurse == 0){
					pthread_mutex_lock(&mu);
					(*(ta->gl->num_threads))--;
					pthread_mutex_unlock(&mu);
				}
				check_print_counters(newta->fe, ta->gl);
				continue;
			}
			newta->fe->file->counters->dr_opened--;
			
			if(max_depth == DEFAULT_DEPTH || ta->fe->file->counters->max_depth < max_depth){
				if(*(newta->gl->num_threads) < newta->gl->allowed_threads || newta->gl->allowed_threads == DEFAULT_ALLOWED_THREADS){
					if((status = pthread_create(&threadid, NULL, process_directory, (void*)newta))){
						if(newta->gl->is_network){
							char *output;

							output = calloc(sizeof(char), newta->gl->path_max);
							sprintf(output, "Could not create thread: %s\n", strerror(status));
							write_error_line(output, newta->gl);
							free(output);
						}
						fprintf(stderr, "Could not create thread: %s\n", strerror(status));
						newta->fe->file->counters->num_recurse = ta->fe->file->counters->num_recurse + 1;
						process_directory((void*)newta);
					}
					else{
						pthread_mutex_lock(&mu);
						(*(ta->gl->num_threads))++;
						if(*(ta->gl->num_threads) > ta->fe->file->counters->max_dt_created)
							ta->fe->file->counters->max_dt_created = *(ta->gl->num_threads);
						pthread_mutex_unlock(&mu);
						pthread_detach(threadid);
						ta->fe->file->counters->num_dt_created++;
					}
				}
				else{
					if((my_flags&QUIET) != QUIET){
						/* If the file was specified on the commandline or if the -q
			           	   flag was not selected then print the error */
						if(ta->gl->is_network){
							char *output;

							output = calloc(sizeof(char), ta->gl->path_max);
							sprintf(output, "Descent thread pruned due to a -t%d flag\n", newta->gl->allowed_threads);
							write_error_line(output, ta->gl);
							free(output);
						}
						fprintf(stderr, "Descent thread pruned due to a -t%d flag\n", newta->gl->allowed_threads);
					}
					else{
						/* If the file error was not printed then increment the 
					   	   corresponding counter */
						ta->fe->file->counters->err_not_printed++;
					}
						
					ta->fe->file->counters->num_dt_notcreated++;
					newta->fe->file->counters->num_recurse = ta->fe->file->counters->num_recurse + 1;
					process_directory((void*)newta);
				}
			}
			else{
				process_directory((void*)newta);
			}
		}
		else if(status == 0){
			/* Else process the entry as a file */
			strcpy(newfile->name, newfile->fullptr);
			process_file(newfile, ta->gl);
			combine_counters(newfile->counters, ta->gl);
		}
	}
	
	if(ta->fe->file->counters->num_recurse == 0){
		pthread_mutex_lock(&mu);
		(*(ta->gl->num_threads))--;
		pthread_mutex_unlock(&mu);
	}
	ta->fe->file->counters->num_recurse--;
	closedir(dptr);
	check_print_counters(ta->fe, ta->gl);
	return NULL;
	/*process_directory*/
}
Beispiel #12
0
static int curl_download_internal(struct dload_payload *payload,
		const char *localpath, char **final_file, char **final_url)
{
	int ret = -1;
	FILE *localf = NULL;
	char *effective_url;
	char hostname[HOSTNAME_SIZE];
	char error_buffer[CURL_ERROR_SIZE] = {0};
	struct stat st;
	long timecond, remote_time = -1;
	double remote_size, bytes_dl;
	struct sigaction orig_sig_pipe, orig_sig_int;
	/* shortcut to our handle within the payload */
	alpm_handle_t *handle = payload->handle;
	CURL *curl = get_libcurl_handle(handle);
	handle->pm_errno = 0;

	/* make sure these are NULL */
	FREE(payload->tempfile_name);
	FREE(payload->destfile_name);
	FREE(payload->content_disp_name);

	payload->tempfile_openmode = "wb";
	if(!payload->remote_name) {
		STRDUP(payload->remote_name, get_filename(payload->fileurl),
				RET_ERR(handle, ALPM_ERR_MEMORY, -1));
	}
	if(curl_gethost(payload->fileurl, hostname, sizeof(hostname)) != 0) {
		_alpm_log(handle, ALPM_LOG_ERROR, _("url '%s' is invalid\n"), payload->fileurl);
		RET_ERR(handle, ALPM_ERR_SERVER_BAD_URL, -1);
	}

	if(payload->remote_name && strlen(payload->remote_name) > 0 &&
			strcmp(payload->remote_name, ".sig") != 0) {
		payload->destfile_name = get_fullpath(localpath, payload->remote_name, "");
		payload->tempfile_name = get_fullpath(localpath, payload->remote_name, ".part");
		if(!payload->destfile_name || !payload->tempfile_name) {
			goto cleanup;
		}
	} else {
		/* URL doesn't contain a filename, so make a tempfile. We can't support
		 * resuming this kind of download; partial transfers will be destroyed */
		payload->unlink_on_fail = 1;

		localf = create_tempfile(payload, localpath);
		if(localf == NULL) {
			goto cleanup;
		}
	}

	curl_set_handle_opts(payload, curl, error_buffer);

	if(localf == NULL) {
		localf = fopen(payload->tempfile_name, payload->tempfile_openmode);
		if(localf == NULL) {
			handle->pm_errno = ALPM_ERR_RETRIEVE;
			_alpm_log(handle, ALPM_LOG_ERROR,
					_("could not open file %s: %s\n"),
					payload->tempfile_name, strerror(errno));
			goto cleanup;
		}
	}

	_alpm_log(handle, ALPM_LOG_DEBUG,
			"opened tempfile for download: %s (%s)\n", payload->tempfile_name,
			payload->tempfile_openmode);

	curl_easy_setopt(curl, CURLOPT_WRITEDATA, localf);

	/* Ignore any SIGPIPE signals. With libcurl, these shouldn't be happening,
	 * but better safe than sorry. Store the old signal handler first. */
	mask_signal(SIGPIPE, SIG_IGN, &orig_sig_pipe);
	mask_signal(SIGINT, &inthandler, &orig_sig_int);

	/* perform transfer */
	payload->curlerr = curl_easy_perform(curl);
	_alpm_log(handle, ALPM_LOG_DEBUG, "curl returned error %d from transfer\n",
			payload->curlerr);

	/* disconnect relationships from the curl handle for things that might go out
	 * of scope, but could still be touched on connection teardown.  This really
	 * only applies to FTP transfers. */
	curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1L);
	curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, (char *)NULL);

	/* was it a success? */
	switch(payload->curlerr) {
		case CURLE_OK:
			/* get http/ftp response code */
			_alpm_log(handle, ALPM_LOG_DEBUG, "response code: %ld\n", payload->respcode);
			if(payload->respcode >= 400) {
				payload->unlink_on_fail = 1;
				/* non-translated message is same as libcurl */
				snprintf(error_buffer, sizeof(error_buffer),
						"The requested URL returned error: %ld", payload->respcode);
				_alpm_log(handle, ALPM_LOG_ERROR,
						_("failed retrieving file '%s' from %s : %s\n"),
						payload->remote_name, hostname, error_buffer);
				goto cleanup;
			}
			break;
		case CURLE_ABORTED_BY_CALLBACK:
			/* handle the interrupt accordingly */
			if(dload_interrupted == ABORT_OVER_MAXFILESIZE) {
				payload->curlerr = CURLE_FILESIZE_EXCEEDED;
				handle->pm_errno = ALPM_ERR_LIBCURL;
				/* use the 'size exceeded' message from libcurl */
				_alpm_log(handle, ALPM_LOG_ERROR,
						_("failed retrieving file '%s' from %s : %s\n"),
						payload->remote_name, hostname,
						curl_easy_strerror(CURLE_FILESIZE_EXCEEDED));
			}
			goto cleanup;
		default:
			/* delete zero length downloads */
			if(fstat(fileno(localf), &st) == 0 && st.st_size == 0) {
				payload->unlink_on_fail = 1;
			}
			if(!payload->errors_ok) {
				handle->pm_errno = ALPM_ERR_LIBCURL;
				_alpm_log(handle, ALPM_LOG_ERROR,
						_("failed retrieving file '%s' from %s : %s\n"),
						payload->remote_name, hostname, error_buffer);
			} else {
				_alpm_log(handle, ALPM_LOG_DEBUG,
						"failed retrieving file '%s' from %s : %s\n",
						payload->remote_name, hostname, error_buffer);
			}
			goto cleanup;
	}

	/* retrieve info about the state of the transfer */
	curl_easy_getinfo(curl, CURLINFO_FILETIME, &remote_time);
	curl_easy_getinfo(curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &remote_size);
	curl_easy_getinfo(curl, CURLINFO_SIZE_DOWNLOAD, &bytes_dl);
	curl_easy_getinfo(curl, CURLINFO_CONDITION_UNMET, &timecond);
	curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL, &effective_url);

	if(final_url != NULL) {
		*final_url = effective_url;
	}

	/* time condition was met and we didn't download anything. we need to
	 * clean up the 0 byte .part file that's left behind. */
	if(timecond == 1 && DOUBLE_EQ(bytes_dl, 0)) {
		_alpm_log(handle, ALPM_LOG_DEBUG, "file met time condition\n");
		ret = 1;
		unlink(payload->tempfile_name);
		goto cleanup;
	}

	/* remote_size isn't necessarily the full size of the file, just what the
	 * server reported as remaining to download. compare it to what curl reported
	 * as actually being transferred during curl_easy_perform() */
	if(!DOUBLE_EQ(remote_size, -1) && !DOUBLE_EQ(bytes_dl, -1) &&
			!DOUBLE_EQ(bytes_dl, remote_size)) {
		handle->pm_errno = ALPM_ERR_RETRIEVE;
		_alpm_log(handle, ALPM_LOG_ERROR, _("%s appears to be truncated: %jd/%jd bytes\n"),
				payload->remote_name, (intmax_t)bytes_dl, (intmax_t)remote_size);
		goto cleanup;
	}

	if (payload->trust_remote_name) {
		if(payload->content_disp_name) {
			/* content-disposition header has a better name for our file */
			free(payload->destfile_name);
			payload->destfile_name = get_fullpath(localpath, payload->content_disp_name, "");
		} else {
			const char *effective_filename = strrchr(effective_url, '/');
			if(effective_filename && strlen(effective_filename) > 2) {
				effective_filename++;

				/* if destfile was never set, we wrote to a tempfile. even if destfile is
				 * set, we may have followed some redirects and the effective url may
				 * have a better suggestion as to what to name our file. in either case,
				 * refactor destfile to this newly derived name. */
				if(!payload->destfile_name || strcmp(effective_filename,
							strrchr(payload->destfile_name, '/') + 1) != 0) {
					free(payload->destfile_name);
					payload->destfile_name = get_fullpath(localpath, effective_filename, "");
				}
			}
		}
	}

	ret = 0;

cleanup:
	if(localf != NULL) {
		fclose(localf);
		utimes_long(payload->tempfile_name, remote_time);
	}

	if(ret == 0) {
		const char *realname = payload->tempfile_name;
		if(payload->destfile_name) {
			realname = payload->destfile_name;
			if(rename(payload->tempfile_name, payload->destfile_name)) {
				_alpm_log(handle, ALPM_LOG_ERROR, _("could not rename %s to %s (%s)\n"),
						payload->tempfile_name, payload->destfile_name, strerror(errno));
				ret = -1;
			}
		}
		if(ret != -1 && final_file) {
			STRDUP(*final_file, strrchr(realname, '/') + 1,
					RET_ERR(handle, ALPM_ERR_MEMORY, -1));
		}
	}

	if((ret == -1 || dload_interrupted) && payload->unlink_on_fail &&
			payload->tempfile_name) {
		unlink(payload->tempfile_name);
	}

	/* restore the old signal handlers */
	unmask_signal(SIGINT, &orig_sig_int);
	unmask_signal(SIGPIPE, &orig_sig_pipe);
	/* if we were interrupted, trip the old handler */
	if(dload_interrupted) {
		raise(SIGINT);
	}

	return ret;
}
Beispiel #13
0
/*
 * cases like: ./dir, ./dir/ ../dir/.. or ../dir../
 * are resolved in this function.
 * it will be parsed as realpath(../dir/)+ name(..)
 * Note to myself: ~ is automatically parsed by shell as
 * absolute path
 * scan a given directory name
 * if it start with / it is a absolute path and copy it
 * if it is a relative name get its parent's realpath
 * then followed by its name
 */
static char* scan_dir_name(char *given)
{
	char *full_path,*relative_path,*rptr,*memptr,*real_given;
	int i,slash,given_length;
	full_path=NULL;
	given_length=strlen(given);
	slash=-1;
	if (given[0]=='/') /*absolute path*/
	{
		if ((full_path=malloc(given_length+1))==NULL)
		{
			perror("malloc():");
		}else
		{
			strcpy(full_path,given);
		}
	}else /* it is a given directory not starting with '/'*/
	{
		/* scan from 1 since we know it is not / at 0 */
		for (i=1;i<given_length;i++)
		{
			/* record the last appeared slash /
			 * but do not record the slash appeared
			 * at the last character
			 */
			if (given[i]=='/' && i!=given_length-1)
				slash=i;
		}
		/* if there is no slash is just the realpath of '.' +/+ given_name*/
		if (slash==-1)
			{
				relative_path=".";
				real_given=given;
			}
		else /* now we need to parse its realtive path realpath and the real given name*/
		{
			if ((relative_path=malloc(slash+1))==NULL)
			{
				perror("malloc():");
			}else
			{
				strncpy(relative_path,given,slash);
				relative_path[slash]='\0';
			}
			/* parse the real given name */
			if ((real_given=malloc(given_length))==NULL)
			{
				perror("malloc():");
			}else
			{
				/*get the real given name after the parsed relative path name */
				for (i=slash+1;i<given_length;i++)
					real_given[i-slash-1]=given[i];
				real_given[i-slash-1]='\0';
			}
		}

		if ((rptr = get_realpath(relative_path, &memptr, NULL)) == NULL) {
			/* error report has been done within get_realpath */
			if (memptr) {
				free(memptr);
			}
		}
		else /* generate the full path of level 0 from realpath of '.' followed by given name*/
		{
			full_path = get_fullpath(memptr, real_given,1);
			free(memptr);
		}
	}
	return full_path;
}
Beispiel #14
0
/****************************************************************************
 * Name: tash_mount
 *
 * Description:
 *   Mount specific file system.
 *
 * Usage:
 *   mount -t <filesystem name> <source directory> <target directory>
 ****************************************************************************/
static int tash_mount(int argc, char **args)
{
	int option;
	int ret;
	const char *fs = NULL;
	const char *source;
	char *fullsource;
	const char *target;
	char *fulltarget;
	bool badarg = false;

	if (argc < 2) {
		return mount_show(mount_handler, args[1]);
	}

	optind = -1;
	while ((option = getopt(argc, args, ":t:")) != ERROR) {
		switch (option) {
		case 't':
			fs = optarg;
			break;

		case ':':
			FSCMD_OUTPUT(MISSING_ARGS, args[0]);
			badarg = true;
			break;

		case '?':
		default:
			FSCMD_OUTPUT(INVALID_ARGS, args[0]);
			badarg = true;
			break;
		}
	}

	if (badarg) {
		FSCMD_OUTPUT(INVALID_ARGS " : [-t] <fs_type> <source> <target>\n", args[0]);

		return 0;
	}

	if (!fs || optind >= argc) {
		FSCMD_OUTPUT(MISSING_ARGS, args[0]);

		return ERROR;
	}

	source = NULL;
	target = args[optind];
	optind++;

	if (optind < argc) {
		source = target;
		target = args[optind];
		optind++;
		if (optind < argc) {
			FSCMD_OUTPUT(TOO_MANY_ARGS, args[0]);

			return ERROR;
		}
	}

	fullsource = NULL;
	fulltarget = NULL;
	if (source) {
		fullsource = get_fullpath(source);
		if (!fullsource) {
			return ERROR;
		}
	}
	fulltarget = get_fullpath(target);
	if (!fulltarget) {
		ret = ERROR;
		goto errout;
	}

	/* Perform the mount */

	ret = mount(fullsource, fulltarget, fs, 0, NULL);
	if (ret < 0) {
		FSCMD_OUTPUT(CMD_FAILED, args[0], fs);
	}

errout:
	fscmd_free(fulltarget);
	fscmd_free(fullsource);

	return ret;
}
Beispiel #15
0
int
pk_download(int argc, char *argv[])
{
	int rv;
	int opt;
	extern int	optind_av;
	extern char	*optarg_av;
	int oclass = 0;
	char *url = NULL;
	char *http_proxy = NULL;
	char *dir = NULL;
	char *outfile = NULL;
	char *proxy = NULL;
	int  proxy_port = 0;
	KMF_HANDLE_T	kmfhandle = NULL;
	KMF_ENCODE_FORMAT format;
	KMF_RETURN ch_rv = KMF_OK;
	char *fullpath = NULL;
	KMF_DATA cert = { 0, NULL };
	KMF_DATA cert_der = { 0, NULL };

	while ((opt = getopt_av(argc, argv,
	    "t:(objtype)u:(url)h:(http_proxy)o:(outfile)d:(dir)")) != EOF) {

		if (EMPTYSTRING(optarg_av))
			return (PK_ERR_USAGE);
		switch (opt) {
		case 't':
			if (oclass)
				return (PK_ERR_USAGE);
			oclass = OT2Int(optarg_av);
			if (!(oclass & (PK_CERT_OBJ | PK_CRL_OBJ)))
				return (PK_ERR_USAGE);
			break;
		case 'u':
			if (url)
				return (PK_ERR_USAGE);
			url = optarg_av;
			break;
		case 'h':
			if (http_proxy)
				return (PK_ERR_USAGE);
			http_proxy = optarg_av;
			break;
		case 'o':
			if (outfile)
				return (PK_ERR_USAGE);
			outfile = optarg_av;
			break;
		case 'd':
			if (dir)
				return (PK_ERR_USAGE);
			dir = optarg_av;
			break;
		default:
			cryptoerror(LOG_STDERR, gettext(
			    "unrecognized download option '%s'\n"),
			    argv[optind_av]);
			return (PK_ERR_USAGE);
		}
	}

	/* No additional args allowed. */
	argc -= optind_av;
	argv += optind_av;
	if (argc) {
		return (PK_ERR_USAGE);
	}

	/* Check the dir and outfile options */
	if (outfile == NULL) {
		/* If outfile is not specified, use the basename of URI */
		outfile = basename(url);
	}

	fullpath = get_fullpath(dir, outfile);
	if (fullpath == NULL) {
		cryptoerror(LOG_STDERR, gettext("Incorrect dir or outfile "
		    "option value \n"));
		return (PK_ERR_USAGE);
	}
	/* Check if the file exists and might be overwritten. */
	if (verify_file(fullpath) != KMF_OK) {
		cryptoerror(LOG_STDERR,
		    gettext("Warning: file \"%s\" exists, "
		    "will be overwritten."), fullpath);
		if (yesno(gettext("Continue with download? "),
		    gettext("Respond with yes or no.\n"), B_FALSE) == B_FALSE) {
			return (0);
		}
	}
	/* URI MUST be specified */
	if (url == NULL) {
		cryptoerror(LOG_STDERR, gettext("A URL must be specified\n"));
		rv = PK_ERR_USAGE;
		goto end;
	}

	/*
	 * Get the http proxy from the command "http_proxy" option or the
	 * environment variable.  The command option has a higher priority.
	 */
	if (http_proxy == NULL)
		http_proxy = getenv("http_proxy");

	if (http_proxy != NULL) {
		char *ptmp = http_proxy;
		char *proxy_port_s;

		if (strncasecmp(ptmp, "http://", 7) == 0)
			ptmp += 7;	/* skip the scheme prefix */

		proxy = strtok(ptmp, ":");
		proxy_port_s = strtok(NULL, "\0");
		if (proxy_port_s != NULL)
			proxy_port = strtol(proxy_port_s, NULL, 0);
		else
			proxy_port = 8080;
	}

	/* If objtype is not specified, default to CRL */
	if (oclass == 0) {
		oclass = PK_CRL_OBJ;
	}

	if ((rv = kmf_initialize(&kmfhandle, NULL, NULL)) != KMF_OK) {
		cryptoerror(LOG_STDERR, gettext("Error initializing KMF\n"));
		rv = PK_ERR_USAGE;
		goto end;
	}

	/* Now we are ready to download */
	if (oclass & PK_CRL_OBJ) {
		rv = kmf_download_crl(kmfhandle, url, proxy, proxy_port, 30,
		    fullpath, &format);
	} else if (oclass & PK_CERT_OBJ) {
		rv = kmf_download_cert(kmfhandle, url, proxy, proxy_port, 30,
		    fullpath, &format);
	}

	if (rv != KMF_OK) {
		switch (rv) {
		case KMF_ERR_BAD_URI:
			cryptoerror(LOG_STDERR,
			    gettext("Error in parsing URI\n"));
			rv = PK_ERR_USAGE;
			break;
		case KMF_ERR_OPEN_FILE:
			cryptoerror(LOG_STDERR,
			    gettext("Error in opening file\n"));
			rv = PK_ERR_USAGE;
			break;
		case KMF_ERR_WRITE_FILE:
			cryptoerror(LOG_STDERR,
			    gettext("Error in writing file\n"));
			rv = PK_ERR_USAGE;
			break;
		case KMF_ERR_BAD_CRLFILE:
			cryptoerror(LOG_STDERR, gettext("Not a CRL file\n"));
			rv = PK_ERR_USAGE;
			break;
		case KMF_ERR_BAD_CERTFILE:
			cryptoerror(LOG_STDERR,
			    gettext("Not a certificate file\n"));
			rv = PK_ERR_USAGE;
			break;
		case KMF_ERR_MEMORY:
			cryptoerror(LOG_STDERR,
			    gettext("Not enough memory\n"));
			rv = PK_ERR_SYSTEM;
			break;
		default:
			cryptoerror(LOG_STDERR,
			    gettext("Error in downloading the file.\n"));
			rv = PK_ERR_SYSTEM;
			break;
		}
		goto end;
	}

	/*
	 * If the file is successfully downloaded, we also check the date.
	 * If the downloaded file is outdated, give a warning.
	 */
	if (oclass & PK_CRL_OBJ) {
		ch_rv = kmf_check_crl_date(kmfhandle, fullpath);
	} else { /* certificate */
		ch_rv = kmf_read_input_file(kmfhandle, fullpath, &cert);
		if (ch_rv != KMF_OK)
			goto end;

		if (format == KMF_FORMAT_PEM) {
			int len;
			ch_rv = kmf_pem_to_der(cert.Data, cert.Length,
			    &cert_der.Data, &len);
			if (ch_rv != KMF_OK)
				goto end;
			cert_der.Length = (size_t)len;
		}

		ch_rv = kmf_check_cert_date(kmfhandle,
		    format == KMF_FORMAT_ASN1 ? &cert : &cert_der);
	}

end:
	if (ch_rv == KMF_ERR_VALIDITY_PERIOD) {
		cryptoerror(LOG_STDERR,
		    gettext("Warning: the downloaded file is expired.\n"));
	} else if (ch_rv != KMF_OK) {
		cryptoerror(LOG_STDERR,
		    gettext("Warning: failed to check the validity.\n"));
	}

	if (fullpath)
		free(fullpath);

	kmf_free_data(&cert);
	kmf_free_data(&cert_der);

	(void) kmf_finalize(kmfhandle);
	return (rv);
}
Beispiel #16
0
/****************************************************************************
 * Name: tash_cat
 *
 * Description:
 *   copies and concatenates file or redirect file to another file
 *
 * Usage:
 *   cat [OPTIONS] [source_file_path] [> or >>] [target_file_path]
 *   OPTIONS: '--help' - display the usage.
 ****************************************************************************/
static int tash_cat(int argc, char **args)
{
	char *src_fullpath = NULL;
	char *dest_fullpath = NULL;
	char fscmd_buffer[FSCMD_BUFFER_LEN];
	redirection_t direction;
	int fd;
	int destfd;
	int i;
	int flags;
	ssize_t ret = 0;

	direction.mode = FSCMD_NONE;
	direction.index = -1;
	for (i = 1; i < argc; i++) {
		if (strcmp(args[i], ">") == 0) {
			direction.mode = FSCMD_TRUNCATE;
			direction.index = i;
			break;
		} else if (strcmp(args[i], ">>") == 0) {
			direction.mode = FSCMD_APPEND;
			direction.index = i;
			break;
		}
	}

	if (argc < 2) {
		FSCMD_OUTPUT(MISSING_ARGS FSCMD_CAT_USAGE, args[0]);
		return ERROR;
	} else if (argc == 2) {
		if (!strncmp(args[1], "--help", strlen("--help") + 1)) {
			FSCMD_OUTPUT(FSCMD_CAT_USAGE);
			return OK;
		}
		/* Basic case, cat <filepath> */
		if (direction.mode != FSCMD_NONE) {
			FSCMD_OUTPUT(INVALID_ARGS FSCMD_CAT_USAGE, args[0]);
			return ERROR;
		}

		src_fullpath = get_fullpath(args[1]);
		if (!src_fullpath) {
			FSCMD_OUTPUT(OUT_OF_MEMORY, args[1]);
			return ERROR;
		}

		fd = open(src_fullpath, O_RDONLY);
		if (fd < 0) {
			FSCMD_OUTPUT(CMD_FAILED, "open", src_fullpath);
			goto error;
		}
		do {
			memset(fscmd_buffer, 0, FSCMD_BUFFER_LEN);
			ret = read(fd, fscmd_buffer, FSCMD_BUFFER_LEN - 1);
			if (ret > 0) {
				fscmd_buffer[ret] = '\0';
				FSCMD_OUTPUT("%s", fscmd_buffer);
			}
		} while (ret > 0);

		FSCMD_OUTPUT("\n");
		close(fd);
	} else if (argc == 4) {
		/* Below is redirection case */
		flags = O_WRONLY | O_CREAT;
		if (direction.mode == FSCMD_TRUNCATE) {
			flags |= O_TRUNC;
		} else {
			flags |= O_APPEND;
		}

		if (direction.index == 2) {
			/* copy contents from source file to target file
			 * cat <source filepath> <redirection> <target filepath> */
			if (strcmp(args[1], args[3]) == 0) {
				FSCMD_OUTPUT(INVALID_ARGS "Same File name", args[1]);
				return ERROR;
			}

			src_fullpath = get_fullpath(args[1]);
			if (!src_fullpath) {
				FSCMD_OUTPUT(OUT_OF_MEMORY, args[1]);
				return ERROR;
			}

			fd = open(src_fullpath, O_RDONLY);
			if (fd < 0) {
				FSCMD_OUTPUT(CMD_FAILED, "open", src_fullpath);
				goto error;
			}

			dest_fullpath = get_fullpath(args[3]);
			if (!dest_fullpath) {
				FSCMD_OUTPUT(OUT_OF_MEMORY, args[3]);
				close(fd);
				goto error;
			}

			destfd = open(dest_fullpath, flags);
			if (destfd < 0) {
				FSCMD_OUTPUT(CMD_FAILED, "open", dest_fullpath);
				close(fd);
				goto error;
			}
			do {
				memset(fscmd_buffer, 0, FSCMD_BUFFER_LEN);
				ret = read(fd, fscmd_buffer, FSCMD_BUFFER_LEN);
				if (ret > 0) {
					ret = write(destfd, fscmd_buffer, ret);
				}
			} while (ret > 0);

			close(fd);
			close(destfd);
		} else {
			FSCMD_OUTPUT(INVALID_ARGS " : [> or >>] [file] [contents]\n", args[0]);
			return ERROR;
		}
	} else {
		/* Wrong case */
		FSCMD_OUTPUT(INVALID_ARGS FSCMD_CAT_USAGE, args[0]);
		return ERROR;
	}
	return OK;
error:
	fscmd_free(src_fullpath);
	fscmd_free(dest_fullpath);
	return ERROR;
}
Beispiel #17
0
/****************************************************************************
 * Name: tash_echo
 *
 * Description:
 *   Display input text or Redirects to a target file
 *
 * Usage:
 *   echo [OPTIONS] [input_text] [> or >>] [target_file_path]
 *   OPTIONS: '-n' - do not output the trailing newline.
 *            '--help' - displays usage.
 ****************************************************************************/
static int tash_echo(int argc, char **args)
{
	char *dest_fullpath = NULL;
	redirection_t direction = { FSCMD_NONE, argc };
	char fscmd_buffer[FSCMD_BUFFER_LEN];
	int i;
	int fd = 1;
	int flags;
	int len = 0;
	int arg_len = 0;
	int n_opt = 1;
	int ret = ERROR;

	if (!strncmp(args[1], "--help", strlen("--help") + 1)) {
		FSCMD_OUTPUT(FSCMD_ECHO_USAGE);
		return OK;
	}

	if (!strncmp(args[1], "-n", 2)) {
		n_opt = 2;
	}

	for (i = n_opt; i < argc; i++) {
		if (strcmp(args[i], ">") == 0) {
			direction.mode = FSCMD_TRUNCATE;
			direction.index = i;
			break;
		} else if (strcmp(args[i], ">>") == 0) {
			direction.mode = FSCMD_APPEND;
			direction.index = i;
			break;
		}
	}

	if (direction.mode != FSCMD_NONE && direction.index == argc - 2) {
		/* Redirection case */
		flags = O_WRONLY | O_CREAT;
		if (direction.mode == FSCMD_TRUNCATE) {
			flags |= O_TRUNC;
		} else {
			flags |= O_APPEND;
		}

		/* copy contents to target file
		 * echo <input_text> <redirection> <filepath> */
		dest_fullpath = get_fullpath(args[argc - 1]);
		if (!dest_fullpath) {
			FSCMD_OUTPUT(OUT_OF_MEMORY, args[argc - 1]);
			return ret;
		}

		fd = open(dest_fullpath, flags);
		if (fd < 0) {
			FSCMD_OUTPUT(CMD_FAILED_ERRNO, "echo", "open", errno);
			goto error;
		}
	 } else if (direction.mode != FSCMD_NONE && direction.index != argc - 2) {
		FSCMD_OUTPUT(INVALID_ARGS FSCMD_ECHO_USAGE, args[0]);
		return ret;
	 }

	for (i = n_opt; i < direction.index; i++) {
		if (i != n_opt) {
			memcpy(fscmd_buffer + len, " ", 1);
			len += 1;
		}

		arg_len = strlen(args[i]);
		if ((len + arg_len) > FSCMD_BUFFER_LEN) {
			FSCMD_OUTPUT("%s : Too long input text\n", args[0]);
			goto error_with_close;
		}
		memcpy(fscmd_buffer + len, args[i], arg_len);
		len += arg_len;
	}

	if (1 == n_opt) {
		memcpy(fscmd_buffer + len, "\n", 1);
		len += 1;
	}

	if (write(fd, fscmd_buffer, len) < 0) {
		FSCMD_OUTPUT(CMD_FAILED_ERRNO, args[0], "write", errno);
		goto error_with_close;
	}

	ret = OK;

error_with_close:
	if (fd > 2) {
		close(fd);
	}
error:
	fscmd_free(dest_fullpath);
	return ret;
}
Beispiel #18
0
	ustring get_fullpath(const ustring &path)
	{
		return get_fullpath(path.c_str());
	}