Example #1
0
static int chirp_fuse_access(const char *path, int flags)
{
	INT64_T result;
	char newpath[CHIRP_PATH_MAX];
	char host[CHIRP_PATH_MAX];
	parsepath(path, newpath, host);

	pthread_mutex_lock(&mutex);
	if (flags & X_OK) {
		struct chirp_stat buf;
		/* FUSE calls access(dir, X_OK) for chdir calls. For compatibility with older chirp servers, we
		 * check for list access rights on a directory by calling stat.
		 */
		if ((chirp_global_stat(host, newpath, &buf, time(0)+chirp_fuse_timeout) == 0) && S_ISDIR(buf.cst_mode)) {
			/* we've confirmed X_OK rights, now check others if they exist... */
			flags ^= X_OK;
			flags |= F_OK; /* make sure we have *some* flags; on GNU/Linux 0 is a valid value for flags (it is F_OK actually), others it may not be */
			result = chirp_global_access(host, newpath, flags, time(0) + chirp_fuse_timeout);
		} else {
			result = chirp_global_access(host, newpath, flags, time(0) + chirp_fuse_timeout);
		}
	} else {
		result = chirp_global_access(host, newpath, flags, time(0) + chirp_fuse_timeout);
	}
	pthread_mutex_unlock(&mutex);

	if(result < 0)
		return -errno;
	return 0;
}
Example #2
0
static int chirp_fuse_link(const char *from, const char *to)
{
	INT64_T result;
	char frompath[CHIRP_PATH_MAX], topath[CHIRP_PATH_MAX];
	char host[CHIRP_PATH_MAX];
	parsepath(from, frompath, host);
	parsepath(to, topath, host);

	pthread_mutex_lock(&mutex);
	result = chirp_global_link(host, frompath, topath, time(0) + chirp_fuse_timeout);
	pthread_mutex_unlock(&mutex);

	if(result < 0)
		return -errno;
	return 0;
}
Example #3
0
static int chirp_fuse_open(const char *path, struct fuse_file_info *fi)
{
	static int file_number_counter = 1;
	struct chirp_file *file;
	int mode = 0;

	char newpath[CHIRP_PATH_MAX];
	char host[CHIRP_PATH_MAX];

	parsepath(path, newpath, host);

	pthread_mutex_lock(&mutex);
	file = chirp_global_open(host, newpath, fi->flags, mode, time(0) + chirp_fuse_timeout);
	if(file) {
		int file_number = file_number_counter++;
		itable_insert(file_table, file_number, file);
		fi->fh = file_number;
	}

	pthread_mutex_unlock(&mutex);

	if(!file)
		return -errno;

	return 0;

}
Example #4
0
static int chirp_fuse_statfs(const char *path, struct statvfs *info)
#endif
{
	INT64_T result;
	char newpath[CHIRP_PATH_MAX];
	char host[CHIRP_PATH_MAX];
	parsepath(path, newpath, host);
	struct chirp_statfs cinfo;

	pthread_mutex_lock(&mutex);
	result = chirp_global_statfs(host, newpath, &cinfo, time(0) + chirp_fuse_timeout);
	pthread_mutex_unlock(&mutex);

	if(result < 0)
		return -errno;

	memset(info, 0, sizeof(*info));

#if FUSE_USE_VERSION==22
	info->f_type = cinfo.f_type;
#endif
	info->f_bsize = cinfo.f_bsize;
	info->f_blocks = cinfo.f_blocks;
	info->f_bfree = cinfo.f_bfree;
	info->f_bavail = cinfo.f_bavail;
	info->f_files = cinfo.f_files;
	info->f_ffree = cinfo.f_ffree;

	return 0;
}
Example #5
0
/* find a command on system PATH or return false 
 */
int findcommand(char *command) {

  int ix, numpath, found = 0;
  char *pathary[MAXARG + 1];
  char *pathptr = getenv("PATH");
  char wrkpth[MAXBUF];

  /* check for getenv() errors */
  if ( ( pathptr == NULL ) || (strlen(pathptr) <= 0) ) {
    fprintf(stderr, "Error retrieving system environment PATH.\n");
    return -1;
  }
  /* parse env PATH into array and seach for command on paths */
  if ((numpath = parsepath(pathary, pathptr)) != 0) {

    /* search each path in the array */
    while (ix < numpath) {
      sprintf(wrkpth, "%s/%s", pathary[ix], command);
      /* found or not */
      if ( access(wrkpth, X_OK) == 0 ) {
        found = 1;
        break;
      }
      else
        ix++;
    }

    if (!found)
      fprintf(stderr, "Command %s not found on system path.\n", command);
    else
      printf("Command %s found on: %s\n", command, pathary[ix]);
  }
  return found;
}
/* Function to Build a response */
int buildresponse(http_request_t *http_request,http_status_t *http_status,http_response_t *http_response)
{
    int file_fd,length;
    ssize_t numread;
    char readbuf[MEMORYSIZE],writebuf[MEMORYSIZE];	
    http_header_t http_response_header;
    int headerindex=0;
    int position;
    char *uripath;

    uripath=strdup(http_request->uri);

    getdatetime(http_response);
    headerindex++;

    strncpy(http_response->resource_path,http_request->uri,PATH_MAX);

    char content_type[50];
    memset(content_type,0,sizeof(content_type));
    if(uripath)
        parsepath(uripath,content_type);
    strncpy(http_response->headers[POSITION_SERVER].field_name,"Server",MAX_HEADER_NAME_LENGTH);
    strncpy(http_response->headers[POSITION_SERVER].field_value,"CSUC",MAX_HEADER_VALUE_LENGTH);
    headerindex++;

    http_response->status.code=http_status->code;
    http_response->status.reason=http_status->reason;

    http_response->major_version=http_request->major_version;
    http_response->minor_version=http_request->minor_version;
	
    strncpy(http_response->headers[POSITION_CONTENTTYPE].field_name,"Content-Type",MAX_HEADER_NAME_LENGTH);
    headerindex++;

    strncpy(http_response->headers[POSITION_CONTENTLENGTH].field_name,"Content-Length",MAX_HEADER_NAME_LENGTH);	
    char lengthbuffer[MEMORYSIZE];
    int writecheck;
    if(http_status->code!=HTTP_STATUS_LOOKUP[POSITION_OK].code)
    {
        writecheck=checkforerrorfiles(http_status,http_response);
        strncpy(http_response->headers[POSITION_CONTENTTYPE].field_value,".html",MAX_HEADER_VALUE_LENGTH);
    }     
    else 
    {
        strncpy(http_response->headers[POSITION_CONTENTTYPE].field_value,content_type,MAX_HEADER_VALUE_LENGTH);
	strncpy(http_response->headers[POSITION_CONTENTLENGTH].field_name,"Content-Length",MAX_HEADER_NAME_LENGTH);
	length=find_content_length(http_request->uri,http_status);
	sprintf(lengthbuffer,"%d",length);
	strncpy(http_response->headers[POSITION_CONTENTLENGTH].field_value,lengthbuffer,MAX_HEADER_VALUE_LENGTH);
    }
    headerindex++;
    http_response->header_count=headerindex;

    free(uripath);
    return;
}
Example #7
0
bool binspector_parser_t::is_pp_include()
{
    if (!is_keyword(key_include))
        return false;

    adobe::any_regular_t value;

    require_token(adobe::string_k, value);

    std::string value_str(value.cast<std::string>());

    // std::cerr << "Include file " << value_str << '\n';

    // do the parse; so far we don't support include directories; at this point
    // it'll get complicated when it does.
    //
    // we also need to track which files we include so we do not include them twice.

    boost::filesystem::path parsepath(include_directory_set_m[0] / value_str.c_str());

    // REVISIT (fbrereto) : A std::string to a c-string to a std::string to a... c'mon.
    if (!exists(parsepath))
        throw_exception(adobe::make_string("Could not find requested include file: ",
                                           value_str.c_str()).c_str());

    // check if file has already been parsed and added to the AST.
    if (adobe::find(included_file_set_m, parsepath) != included_file_set_m.end())
        return true;

    included_file_set_m.push_back(parsepath);

    boost::filesystem::ifstream            include_stream(parsepath);
    adobe::line_position_t::getline_proc_t getline(new adobe::line_position_t::getline_proc_impl_t(std::bind(&get_input_line, std::ref(include_stream), std::placeholders::_2)));
    adobe::line_position_t                 position(adobe::name_t(parsepath.string().c_str()), getline);

    try
    {
        binspector_parser_t(include_stream,
                            position,
                            include_directory_set_m,
                            set_structure_proc_m,
                            add_field_proc_m,
                            add_unnamed_field_proc_m,
                            add_typedef_proc_m,
                            included_file_set_m).parse();
    }
    catch (const adobe::stream_error_t& error)
    {
        throw std::runtime_error(adobe::format_stream_error(include_stream, error));
    }

    return true;
}
Example #8
0
static int chirp_fuse_truncate(const char *path, off_t size)
{
	INT64_T result;
	char newpath[CHIRP_PATH_MAX];
	char host[CHIRP_PATH_MAX];
	parsepath(path, newpath, host);

	pthread_mutex_lock(&mutex);
	result = chirp_global_truncate(host, newpath, size, time(0) + chirp_fuse_timeout);
	pthread_mutex_unlock(&mutex);

	if(result < 0)
		return -errno;
	return 0;
}
Example #9
0
static void
savebrush (GtkWidget *wg,
           gpointer   data)
{
  GtkWidget *dialog   = NULL;
  GList     *thispath = parsepath ();
  gchar     *path;

  if (! PPM_IS_INITED (&brushppm))
    {
      g_message ( _("Can only save drawables!"));
      return;
    }

  dialog =
    gtk_file_chooser_dialog_new (_("Save Brush"),
                                 GTK_WINDOW (gtk_widget_get_toplevel (wg)),
                                 GTK_FILE_CHOOSER_ACTION_SAVE,

                                 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
                                 GTK_STOCK_SAVE,   GTK_RESPONSE_OK,

                                 NULL);

  gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
                                           GTK_RESPONSE_OK,
                                           GTK_RESPONSE_CANCEL,
                                           -1);
  gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);

  gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog),
                                                  TRUE);

  path = g_build_filename ((gchar *)thispath->data, "Brushes", NULL);

  gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), path);

  g_free (path);

  g_signal_connect (dialog, "destroy",
                    G_CALLBACK (gtk_widget_destroyed),
                    &dialog);
  g_signal_connect (dialog, "response",
                    G_CALLBACK (savebrush_response),
                    NULL);

  gtk_widget_show (dialog);
}
Example #10
0
static int chirp_fuse_chown(const char *path, uid_t uid, gid_t gid)
{
	INT64_T result;
	char newpath[CHIRP_PATH_MAX];
	char host[CHIRP_PATH_MAX];
	parsepath(path, newpath, host);

	pthread_mutex_lock(&mutex);
	result = chirp_global_chown(host, newpath, uid, gid, time(0) + chirp_fuse_timeout);
	pthread_mutex_unlock(&mutex);

	if(result < 0)
		return -errno;

	return 0;
}
Example #11
0
static int chirp_fuse_utime(const char *path, struct utimbuf *buf)
{
	INT64_T result;
	char newpath[CHIRP_PATH_MAX];
	char host[CHIRP_PATH_MAX];
	parsepath(path, newpath, host);

	pthread_mutex_lock(&mutex);
	result = chirp_global_utime(host, newpath, buf->actime, buf->modtime, time(0) + chirp_fuse_timeout);
	pthread_mutex_unlock(&mutex);

	if(result < 0)
		return -errno;

	return 0;
}
Example #12
0
static int chirp_fuse_readlink(const char *path, char *buf, size_t size)
{
	INT64_T result;
	char newpath[CHIRP_PATH_MAX];
	char host[CHIRP_PATH_MAX];
	parsepath(path, newpath, host);

	pthread_mutex_lock(&mutex);
	result = chirp_global_readlink(host, newpath, buf, size, time(0) + chirp_fuse_timeout);
	pthread_mutex_unlock(&mutex);

	if(result < 0)
		return -errno;
	buf[result] = 0;

	return 0;
}
Example #13
0
static int chirp_fuse_getattr(const char *path, struct stat *info)
{
	INT64_T result;
	struct chirp_stat cinfo;
	char newpath[CHIRP_PATH_MAX];
	char host[CHIRP_PATH_MAX];

	parsepath(path, newpath, host);

	pthread_mutex_lock(&mutex);
	result = chirp_global_lstat(host, newpath, &cinfo, time(0) + chirp_fuse_timeout);
	pthread_mutex_unlock(&mutex);

	if(result < 0)
		return -errno;
	chirp_stat_to_fuse_stat(&cinfo, info);
	return 0;
}
Example #14
0
static int chirp_fuse_rmdir(const char *path)
{
	INT64_T result;
	char newpath[CHIRP_PATH_MAX];
	char host[CHIRP_PATH_MAX];
	parsepath(path, newpath, host);

	pthread_mutex_lock(&mutex);
	if(enable_small_file_optimizations) {
		result = chirp_global_rmall(host, newpath, time(0) + chirp_fuse_timeout);
	} else {
		result = chirp_global_rmdir(host, newpath, time(0) + chirp_fuse_timeout);
	}
	pthread_mutex_unlock(&mutex);

	if(result < 0)
		return -errno;
	return 0;
}
Example #15
0
static int chirp_fuse_symlink(const char *source, const char *target)
/*		source: relative filename
		target: full pathname
*/
{
	INT64_T result;
	char dest_path[CHIRP_PATH_MAX];
	char host[CHIRP_PATH_MAX];

	parsepath(target, dest_path, host);

	pthread_mutex_lock(&mutex);
	result = chirp_global_symlink(host, source, dest_path, time(0) + chirp_fuse_timeout);
	pthread_mutex_unlock(&mutex);

	if(result < 0)
		return -errno;
	return 0;
}
Example #16
0
void
rc_init(void) {
    int line, ignore, i;
    char buf[RCLEN + 2], *c;
    FILE *f;

    c = parsepath(RCPATH);
    if(!(f = fopen(c, "r")) && !(f = fopen(RCSAMPLE, "r")))
        eprintf(PROGRAM": "RCSAMPLE": No such file or directory\n");
    free(c);
    for(line = 1, ignore = 0; fgets(buf, RCLEN + 2, f); line++) {
        if(buf[strlen(buf) - 1] != '\n') {
            if(ignore != line)
                fprintf(stderr, PROGRAM": "RCPATH": line %d: "
                                "Exceed the %d chars limit.\n", line, RCLEN);
            ignore = line--;
            continue;
        }
        for(i = 0; buf[i] != '#' && buf[i] != '\n';)
            if(buf[++i] == '\'')
                while(buf[++i] != '\'');
        for(--i; i >= 0 && (buf[i] == ' ' || buf[i] == '\t'); i--);
        for(; ++i < (RCLEN + 1); (buf[i] = '\0'));
        if(ignore == line || !buf[0])
            continue;
        c = NULL;
        if((strstr(buf, "layout") && buf[strlen(buf) - 1] == ':') ||
           isspace(buf[0]))
            c = parselayout(buf);
        else
            c = parseline(buf);
        if(c)
            fprintf(stderr, PROGRAM": "RCPATH": line %d: %s\n", line, c);
    }
    fclose(f);
    data.tagmask = 0L;
    if(!var.tags)
        var.tags = 1;
    for(i = 0; i < (int)var.tags; i++)
        data.tagmask |= (1<<i);
}
Example #17
0
static int chirp_fuse_mknod(const char *path, mode_t mode, dev_t rdev)
{
	struct chirp_file *file;
	char newpath[CHIRP_PATH_MAX];
	char host[CHIRP_PATH_MAX];

	parsepath(path, newpath, host);

	pthread_mutex_lock(&mutex);
	file = chirp_global_open(host, newpath, O_CREAT|O_WRONLY, mode, time(0) + chirp_fuse_timeout);
	pthread_mutex_unlock(&mutex);

	if(!file)
		return -errno;

	pthread_mutex_lock(&mutex);
	chirp_global_close(file, time(0) + chirp_fuse_timeout);
	pthread_mutex_unlock(&mutex);

	return 0;
}
Example #18
0
File: utils.c Project: Minoos/gimp
void
readdirintolist_extended (char         *subdir,
                          GtkWidget    *view,
                          char         *selected,
                          gboolean      with_filename_column,
                          gchar      *(*get_object_name_cb) (gchar *dir,
                                                             gchar *filename,
                                                             void *context),
                          void * context)
{
  char *tmpdir;
  GList *thispath = parsepath ();

  while (thispath)
    {
      tmpdir = g_build_filename ((gchar *) thispath->data, subdir, NULL);
      readdirintolist_real (tmpdir, view, selected, with_filename_column,
                            get_object_name_cb, context);
      g_free (tmpdir);
      thispath = thispath->next;
    }
}
Example #19
0
/* find a command on system PATH or return false 
 */
int findcommand(char cpath[], char *command) {

  int ix = 0, 
      numpath = 0, 
      found = 0;
  char *pathary[MAXARG];

  char wrkpth[MAXBUF];
  char *pathptr = getenv("PATH");

  /* check for getenv() errors */
  if ( ( pathptr == NULL ) || (strlen(pathptr) <= 0) ) {
    fprintf(stderr, "Error retrieving system environment PATH.\n");
    return 0;
  }
  /* parse env PATH into array and seach for command on paths */
  if ((numpath = parsepath(pathary, pathptr)) == 0)
    return 0;

  /* search each path in the array */
  while (ix < numpath) {
    sprintf(wrkpth, "%s/%s", pathary[ix], command);
    /* found or not */
    if ( access(wrkpth, X_OK) == 0 ) {
      found = 1;
      break;
    }
    else
      ix++;
  }

  /* path found, return complete */
  if (found) {
    strcpy(cpath, wrkpth);
    return 1;
  }

  return 0;
}
Example #20
0
/*
 * For each library:
 * Search local directory and all directories in the search path
 *  until it is found or run out of directories
 */
FILE *SrchPth3(char *string, char *searchpath, char *mode)
{
    FILE *in;
    char *newpath = searchpath;

    /* If no path specified we search along the search path */
    if (string[0] != '\\' && string[1] != ':')
    {
        char buffer[200];
        while (newpath)
        {
            int n;;
            /* Create a file name along this path */
            newpath = parsepath(newpath, buffer);
            n = strlen(buffer);
            if (n && buffer[n - 1] != '\\' && buffer[n - 1] != '/')
                strcat(buffer, "\\");
            strcat(buffer, (char*)string);

            /* Check this path */
            in = fopen(buffer, mode);
            if (in !=  NULL)
            {
                strcpy(string, buffer);
                return (in);
            }
        }
    }
    else
    {
        in = fopen((char*)string, mode);
        if (in !=  NULL)
        {
            return (in);
        }
    }
    return (NULL);
}
Example #21
0
File: utils.c Project: Minoos/gimp
gchar *
findfile (const gchar *fn)
{
  GList *rcpath;
  GList *thispath;
  gchar *filename;

  g_return_val_if_fail (fn != NULL, NULL);

  rcpath = parsepath ();

  thispath = rcpath;

  while (thispath)
    {
      filename = g_build_filename (thispath->data, fn, NULL);
      if (g_file_test (filename, G_FILE_TEST_IS_REGULAR))
        return filename;
      g_free (filename);
      thispath = thispath->next;
    }
  return NULL;
}
Example #22
0
static int chirp_fuse_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi)
{
	char newpath[CHIRP_PATH_MAX];
	char host[CHIRP_PATH_MAX];
	int result;

	parsepath(path, newpath, host);

	pthread_mutex_lock(&mutex);

	longdir_buf = buf;
	longdir_filler = filler;

	result = chirp_global_getlongdir(host, newpath, longdir_callback, 0, time(0) + chirp_fuse_timeout);

	pthread_mutex_unlock(&mutex);

	if(result < 0)
		return -errno;
	return 0;

	return 0;
}
Example #23
0
static Pf *
orbdatabases2pf( Pf *pfanalyze ) 
{
	Pf	*pf;
	Pf	*pfdatabases;
	Pf	*pfdatabase;
	Pf	*pfclients;
	Pf	*pfclient;
	double	atime;
	Tbl	*client_keys;
	int	ikey;
	char	*client_key;
	char	*what;
	char	*serverhost;
	char	*clientid;
	char	*clientaddress;
	char	*serveraddress;
	char	*serverport;
	char	dbprogram[STRSZ];
	char	dbpath[STRSZ];
	char	dir[STRSZ];
	char	dfile[STRSZ];
	char	formal_name[STRSZ];
	int	formal_count = 0;
	char	*delim = ":";
	char	*hostdir;
	char	*serverhostcopy;
	char	*abspath;

	pf = pfnew( PFFILE );

	pfdatabases = pfnew( PFTBL );

	atime = pfget_time( pfanalyze, "client_when" );
	pfput_time( pf, "databases_when", atime );

	pfeval( pfanalyze, "server{address}", &serveraddress );
	pfeval( pfanalyze, "server{port}", &serverport );
	pfeval( pfanalyze, "server{host}", &serverhost );

	serverhostcopy = strdup( serverhost );
	strtok_r( serverhostcopy, delim, &hostdir );

	pfget( pfanalyze, "clients", (void **) &pfclients );

	client_keys = pfkeys( pfclients );

	for( ikey = 0; ikey < maxtbl( client_keys ); ikey++ ) {

		client_key = gettbl( client_keys, ikey );
		pfget( pfclients, client_key, (void **) &pfclient );

		what = pfget_string( pfclient, "what" );
		clientaddress = pfget_string( pfclient, "address" );
		clientid = pfget_string( pfclient, "clientid" );

		if( is_dbprogram( what, dbprogram, dbpath ) ) {

			pfdatabase = pfnew( PFARR );

			pfput_string( pfdatabase, "clientid", clientid );
			pfput_string( pfdatabase, "serveraddress", serveraddress );
			pfput_string( pfdatabase, "serverport", serverport );
			pfput_string( pfdatabase, "dbprogram", dbprogram );

			if( is_localhost( clientaddress ) ) {

				pfput_string( pfdatabase, "dbmachine", serveraddress );

				abspath = concatpaths( hostdir, dbpath, 0 );
				parsepath( abspath, dir, dfile, 0 );
				free( abspath );

			} else {

				pfput_string( pfdatabase, "dbmachine", clientaddress );

				abspath = concatpaths( "", dbpath, 0 );
				parsepath( abspath, dir, dfile, 0 );
				free( abspath );
			}

			pfput_string( pfdatabase, "dir", dir );
			pfput_string( pfdatabase, "dfile", dfile );

			sprintf( formal_name, "client%03d", ++formal_count );
			pfput( pfdatabases, formal_name, pfdatabase, PFPF );
		}
	}

	free( serverhostcopy );

	pfput( pf, "databases", pfdatabases, PFPF );

	return pf;
}
Example #24
0
int main(int argc, char *argv[])
{
    char fileName[256], oldwd[256], *command, *dimensions, *stringPtr;
    char prompt[512];
    char *inputText;
    NXname dataName;
    int status;

#if HAVE_LIBREADLINE
    rl_readline_name = "NXbrowse";
    rl_attempted_completion_function = nxbrowse_complete;
#if READLINE_VERSION >= 0x500
    rl_catch_signals = 0;
#else
#define rl_crlf() fprintf(rl_outstream, "\r\n");
#define rl_on_new_line() 1
#endif
    using_history();
#else
#define rl_crlf()
#define rl_on_new_line()
#define add_history(a)
#endif

    printf("NXBrowse %s Copyright (C) 2009-2014 NeXus Data Format\n",
           NEXUS_VERSION);
#if HAVE_LIBREADLINE
    printf
    ("Built with readline support - use <TAB> to complete commands and paths\n");
#endif				/* HAVE_LIBREADLINE */

    /* if there is a filename given on the command line use that,
          else ask for a filename */
    if (argc < 2) {
        printf("Give name of NeXus file : ");
        if (fgets(fileName, sizeof(fileName), stdin) == NULL) {
            printf("Failed to open %s\n", fileName);
            return NX_ERROR;
        }
        if ((stringPtr = strchr(fileName, '\n')) != NULL)
            *stringPtr = '\0';
    } else {
        strcpy(fileName, argv[1]);
    }
    strcpy(nxFile, fileName);

    /* Open input file and output global attributes */
    if (NXopen(fileName, NXACC_READ, &the_fileId) != NX_OK) {
        printf("NX_ERROR: Can't open %s\n", fileName);
        return NX_ERROR;
    }
    PrintAttributes(the_fileId);
    iByteAsChar = 0;	/* Display remaining NX_INT8 and NX_UINT8 variables as integers by default */
    /* Input commands until the EXIT command is given */
    strcpy(oldwd, "/");
    strcpy(path, "/");
    do {
        sprintf(prompt, "NX%s> ", path);
        if (getenv("NO_READLINE") != NULL) {
            inputText = my_readline(prompt);
        } else {
            inputText = readline(prompt);
        }
        if (inputText == NULL) {
            inputText = strdup("EXIT");
        }
        if (*inputText) {
            add_history(inputText);
        }
        command = strtok(inputText, " ");
        /* Check if a command has been given */
        if (command == NULL)
            command = " ";
        /* Convert it to upper case characters */
        ConvertUpperCase(command);

        if (StrEq(command, "PWD")) {
            fprintf(rl_outstream, "%s\n", path);
        }

        if (StrEq(command, "TEST")) {
            char a[256], b[256];
            stringPtr = strtok(NULL, " ");
            if (stringPtr != NULL) {
                parsepath(stringPtr, a, b);
                fprintf(rl_outstream," you entered >%s< - i think the full path is >%s< and the final component looks like this >%s<.\n", stringPtr, a, b);
            } else {
                fprintf(rl_outstream," you entered nothing\n");
            }
        }

        /* Command is to print a directory of the current group */
        if (StrEq(command, "DIR") || StrEq(command, "LS")) {
            stringPtr = strtok(NULL, " ");
            if (stringPtr != NULL) {
                char a[256], b[256];
                parsepath(stringPtr, a, b);
                strcat(a, "/");
                strcat(a, b);
                NXopengrouppath(the_fileId, a);
                NXBdir(the_fileId);
                NXopengrouppath(the_fileId, path);
            } else {
                NXBdir(the_fileId);
            }
        }

        /* Command is to open the specified group */
        if (StrEq(command, "OPEN") || StrEq(command, "CD")) {
            stringPtr = strtok(NULL, " ");
            if (stringPtr != NULL) {
                char a[256], b[256];

                if (StrEq(stringPtr, "-")) {
                    stringPtr = oldwd;
                }

                parsepath(stringPtr, a, b);
                strcat(a, "/");
                strcat(a, b);

                status = NXopengrouppath(the_fileId, a);

                if (status == NX_OK) {
                    strcpy(oldwd, path);
                    strcpy(path, a);
                } else {
                    fprintf(rl_outstream, "NX_ERROR: cannot change into %s\n", stringPtr);
                    NXopengrouppath(the_fileId, path); /* to be sure */
                }

            } else {
                fprintf(rl_outstream, "NX_ERROR: Specify a group\n");
            }
        }

        /* Command is to dump data values to a file */
        if (StrEq(command, "DUMP")) {
            stringPtr = strtok(NULL, " ");
            if (stringPtr != NULL) {
                strcpy(dataName, stringPtr);
                stringPtr = strtok(NULL, " ");
                if (stringPtr != NULL) {
                    strcpy(fileName, stringPtr);
                    status = NXBdump(the_fileId, dataName, fileName);
                } else {
                    fprintf(rl_outstream, "NX_ERROR: Specify a dump file name \n");
                }
            } else {
                fprintf(rl_outstream, "NX_ERROR: Specify a data item\n");
            }
        }
        /* Command is to print the values of the data */
        if (StrEq(command, "READ") || StrEq(command, "CAT")) {
            stringPtr = strtok(NULL, " [");
            if (stringPtr != NULL) {
                strcpy(dataName, stringPtr);
                dimensions = strtok(NULL, "[]");
                status =
                    NXBread(the_fileId, dataName, dimensions);
            } else {
                fprintf(rl_outstream,
                        "NX_ERROR: Specify a data item\n");
            }
        }
        /* Command is to close the current group */
        if (StrEq(command, "CLOSE")) {
            if (strlen(path) > 1) {
                if (NXclosegroup(the_fileId) == NX_OK) {
                    /* Remove the group from the prompt string */
                    strcpy(oldwd, path);
                    stringPtr = strrchr(path, '/');	/* position of last group delimiter */
                    if (stringPtr != NULL)
                        *stringPtr = '\0';	/* terminate the string there */
                }
            } else {
                fprintf(rl_outstream,
                        "NX_WARNING: Already at root level of file\n");
            }
        }
        /* Command is to print help information */
        if (StrEq(command, "HELP") || StrEq(command, "INFO")) {
            printf("NXbrowse commands : DIR\n");
            printf("                    LS\n");
            printf("                    OPEN <groupName>\n");
            printf("                    CD <groupName>\n");
            printf("                    READ <dataName>\n");
            printf("                    READ <dataName>[<dimension indices...>]\n");
            printf("                    DUMP <dataName> <fileName> \n");
            printf("                    CLOSE\n");
            printf("                    BYTEASCHAR\n");
            printf("                    HELP\n");
            printf("                    EXIT\n");
            printf("\n");
#if HAVE_LIBREADLINE
            printf("Pressing <TAB> after a command or partial nexus object name will complete\n");
            printf("possible names. For example:\n");
            printf("\n");
            printf("    cd ent<TAB KEY PRESSED>     # all items starting with ent are listed\n");
            printf("\n");
#endif
        }
        /* Command is to print byte as char information */
        if (StrEq(command, "BYTEASCHAR")) {
            if (iByteAsChar == 1)
                iByteAsChar = 0;
            else
                iByteAsChar = 1;
        }
        /* Command is to exit the program */
        if (StrEq(command, "EXIT") || StrEq(command, "QUIT")) {
            /* for (i = groupLevel; i > 0; i--) NXclosegroup (the_fileId); */
            NXclose(&the_fileId);
            return NX_OK;
        }
        status = NX_OK;
        free(inputText);
    } while (status == NX_OK);
    return NX_OK;
}
Example #25
0
/*
 * This function performs an analysis routine. The intput to this function 
 * is an SEXP object containing a list of input files, the name of the
 * function and the analysis options. 
 */
SEXP
performAssp(SEXP args)
{
    SEXP            el,
                    inputs,
                    res,
                    pBar = R_NilValue,
        utilsPackage,           /* to update the prograssbar */
        newVal;
    const char     *name;
    AOPTS           OPTS;
    AOPTS          *opt = &OPTS;
    W_OPT          *wrasspOptions;
    A_F_LIST       *anaFunc = funclist;
    int             tmp,
                    expExt = 0,
        toFile = 1,
        i = 0;
    char            ext[SUFF_MAX + 1] = "",
        *cPtr = NULL;
    W_GENDER       *gend = NULL;
    WFLIST         *wPtr = NULL;
    LP_TYPE        *lPtr = NULL;
    SPECT_TYPE     *sPtr = NULL;
    DOBJ           *inPtr,
                   *outPtr;
    char           *dPath,
                   *bPath,
                   *oExt,
                    outName[PATH_MAX + 1],
                   *outDir = NULL;

    args = CDR(args);           /* skip function name */

    /*
     * First element is input file name or vector of input file names 
     */
    inputs = CAR(args);
    args = CDR(args);

    /*
     * Second element must be assp function name
     * check for validity and pick the right function descriptor 
     */
    name = isNull(TAG(args)) ? "" : CHAR(PRINTNAME(TAG(args)));
    if (strcmp(name, "fname") != 0)
        error("Second argument must be named 'fname'");

    el = CAR(args);
    while (anaFunc->funcNum != AF_NONE) {
        if (strcmp(CHAR(STRING_ELT(el, 0)), anaFunc->fName) == 0)
            break;
        anaFunc++;
    }
    if (anaFunc->funcNum == AF_NONE)
        error("Invalid analysis function in performAssp.c");

    /*
     * generate the default settings for the analysis function
     */
    if ((anaFunc->setFunc) (opt) == -1)
        error("%d\t$%s\n", asspMsgNum, getAsspMsg(asspMsgNum));

    args = CDR(args);
    /*
     * the rest is options; each of them is checked against the option list of the analysis function
     */


    for (int i = 0; args != R_NilValue; i++, args = CDR(args)) {
        name = isNull(TAG(args)) ? "" : CHAR(PRINTNAME(TAG(args)));
        wrasspOptions = anaFunc->options;
        while (wrasspOptions->name != NULL) {
            if (strcmp(wrasspOptions->name, name) == 0)
                break;
            wrasspOptions++;
        }
        if (wrasspOptions->name == NULL)
            error("Invalid option %s for ASSP analysis %s.", name,
                  anaFunc->fName);

        el = CAR(args);
        switch (wrasspOptions->optNum) {
        case WO_BEGINTIME:
            opt->beginTime = REAL(el)[0];
            break;
        case WO_ENDTIME:
            opt->endTime = REAL(el)[0];
            break;
        case WO_CENTRETIME:
            if (INTEGER(el)[0]) {
                opt->options |= AOPT_USE_CTIME;
            } else {
                opt->options &= ~AOPT_USE_CTIME;
            }
            break;

        case WO_MSEFFLEN:
            if (INTEGER(el)[0]) {
                opt->options |= AOPT_EFFECTIVE;
                switch (anaFunc->funcNum) {
                case AF_SPECTRUM:
                    opt->options &= ~AOPT_USE_ENBW;
                    break;
                default:
                    /*
                     * do nothing
                     */
                    break;
                }
            } else {
                opt->options &= ~AOPT_EFFECTIVE;
                switch (anaFunc->funcNum) {
                case AF_FOREST:
                    opt->gender = 'u';
                    break;
                default:
                    break;
                }
            }
            break;
        case WO_MSSIZE:
            opt->msSize = REAL(el)[0];
            switch (anaFunc->funcNum) {
            case AF_FOREST:
                switch (opt->gender) {
                case 'f':
                    if (opt->msSize != FMT_DEF_EFFLENf)
                        opt->gender = 'u';
                    break;
                case 'm':
                    if (opt->msSize != FMT_DEF_EFFLENm)
                        opt->gender = 'u';
                    break;
                default:
                    break;
                }
                break;
            case AF_SPECTRUM:
                opt->options &= ~AOPT_USE_ENBW;
                break;
            default:
                /*
                 * do nothing
                 */
                break;
            }
            break;
        case WO_MSSHIFT:
            opt->msShift = REAL(el)[0];
            break;
        case WO_MSSMOOTH:
            opt->msSmooth = REAL(el)[0];
            break;
        case WO_BANDWIDTH:
            opt->bandwidth = REAL(el)[0];
            break;
        case WO_RESOLUTION:
            opt->resolution = REAL(el)[0];
            break;
        case WO_GAIN:
            opt->gain = REAL(el)[0];
            break;
        case WO_RANGE:
            opt->range = REAL(el)[0];
            break;
        case WO_PREEMPH:
            opt->preEmph = REAL(el)[0];
            break;
        case WO_FFTLEN:
            opt->FFTLen = INTEGER(el)[0];
            break;
        case WO_CHANNEL:
            opt->channel = INTEGER(el)[0];
            break;
        case WO_GENDER:
            /*
             * some things need to be set here:
             * for f0_ksv: maxf, minf
             * for f0_mhs: maxf, minf
             * for forest: eff. window length, nominal F1
             */
            gend = gender;
            while (gend->ident != NULL) {
                if (strncmp(gend->ident, CHAR(STRING_ELT(el, 0)), 1) == 0)
                    break;
                gend++;
            }
            if (gend->ident == NULL)
                error("Invalid gender specification %s.",
                      CHAR(STRING_ELT(el, 0)));

            switch (anaFunc->funcNum) {
            case AF_KSV_PITCH:
                tmp = setKSVgenderDefaults(opt, gend->code);
                break;
            case AF_MHS_PITCH:
                tmp = setMHSgenderDefaults(opt, gend->code);
                break;
            case AF_FOREST:
                if (gend->num == TG_UNKNOWN) {
                    opt->gender = tolower((int) gend->code);
                    tmp = 1;
                } else
                    tmp = setFMTgenderDefaults(opt, gend->code);
                break;
            default:
                tmp = 1;
                break;
            }
            if (tmp < 0)
                error("%s", applMessage);
            break;
        case WO_MHS_OPT_POWER:
            if (INTEGER(el)[0])
                opt->options |= MHS_OPT_POWER;
            else
                opt->options &= ~MHS_OPT_POWER;
            break;
        case WO_ORDER:
            tmp = opt->order;
            opt->order = INTEGER(el)[0];
            if (anaFunc->funcNum == AF_FOREST) {
                if ((opt->order % 2) != 0) {
                    opt->order = tmp;
                    error("Prediction order must be an even number.");
                } else {
                    opt->options |= FMT_OPT_LPO_FIXED;
                    opt->increment = 0;
                }
            }
            break;
        case WO_INCREMENT:
            opt->increment = INTEGER(el)[0];
            if (anaFunc->funcNum == AF_FOREST) {
                opt->options &= ~FMT_OPT_LPO_FIXED;
                opt->order = 0;
            }
            break;
        case WO_NUMLEVELS:
            opt->numLevels = INTEGER(el)[0];
            break;
        case WO_NUMFORMANTS:
            opt->numFormants = INTEGER(el)[0];
            break;
        case WO_PRECISION:
            opt->precision = INTEGER(el)[0];
            break;
        case WO_ACCURACY:
            opt->accuracy = INTEGER(el)[0];
            break;
        case WO_ALPHA:
            opt->alpha = REAL(el)[0];
            break;
        case WO_THRESHOLD:
            opt->threshold = REAL(el)[0];
            break;
        case WO_MAXF:
            opt->maxF = REAL(el)[0];
            switch (anaFunc->funcNum) {
            case AF_KSV_PITCH:
            case AF_MHS_PITCH:
                opt->gender = 'u';
                break;
            default:
                /*
                 * do nothing
                 */
                break;
            }
            break;
        case WO_MINF:
            opt->minF = REAL(el)[0];
            switch (anaFunc->funcNum) {
            case AF_KSV_PITCH:
            case AF_MHS_PITCH:
                opt->gender = 'u';
                break;
            default:
                /*
                 * do nothing
                 */
                break;
            }
            break;
        case WO_NOMF1:         /* e.g. for formant analysis */
            opt->nomF1 = REAL(el)[0];
            switch (anaFunc->funcNum) {
            case AF_FOREST:
                switch (opt->gender) {
                case 'f':
                    if (opt->nomF1 != FMT_DEF_NOMF1f)
                        opt->gender = 'u';
                    break;
                case 'm':
                    if (opt->nomF1 != FMT_DEF_NOMF1m)
                        opt->gender = 'u';
                    break;
                default:
                    break;
                }
                break;
            default:
                /*
                 * do nothing
                 */
                break;
            }
            break;
        case WO_INS_EST:
            if (INTEGER(el)[0])
                opt->options |= FMT_OPT_INS_ESTS;
            else
                opt->options &= ~FMT_OPT_INS_ESTS;
            break;
        case WO_VOIAC1PP:      /* VOICING thresholds */
            opt->voiAC1 = REAL(el)[0];
            break;
        case WO_VOIMAG:
            opt->voiMag = REAL(el)[0];
            break;
        case WO_VOIPROB:
            opt->voiProb = REAL(el)[0];
            break;
        case WO_VOIRMS:
            opt->voiRMS = REAL(el)[0];
            break;
        case WO_VOIZCR:
            opt->voiZCR = REAL(el)[0];
            break;
        case WO_HPCUTOFF:      /* filter parameters */
            opt->hpCutOff = REAL(el)[0];
            if (expExt == 0)
                tmp = getFILTtype(opt, anaFunc->defExt);
            break;
        case WO_LPCUTOFF:
            opt->lpCutOff = REAL(el)[0];
            if (expExt == 0)
                tmp = getFILTtype(opt, anaFunc->defExt);
            break;
        case WO_STOPDB:
            opt->stopDB = REAL(el)[0];
            if (expExt == 0)
                tmp = getFILTtype(opt, anaFunc->defExt);
            break;
        case WO_TBWIDTH:
            opt->tbWidth = REAL(el)[0];
            if (expExt == 0)
                tmp = getFILTtype(opt, anaFunc->defExt);
            break;
        case WO_USEIIR:
            if (INTEGER(el)[0])
                opt->options |= FILT_OPT_USE_IIR;
            else
                opt->options &= ~FILT_OPT_USE_IIR;
            if (expExt == 0)
                tmp = getFILTtype(opt, anaFunc->defExt);
            break;
        case WO_NUMIIRSECS:
            opt->order = INTEGER(el)[0];
            if (opt->order < 1) {
                error
                    ("Bad value for option -numIIRsections (%i), must be greater 0 (default 4).",
                     opt->order);
                opt->order = FILT_DEF_SECTS;
            }
            break;
        case WO_TYPE:          /* hold-all */
            switch (anaFunc->funcNum) {
            case AF_RFCANA:
                lPtr = lpType;
                while (lPtr->ident != NULL) {
                    if (strcmp(lPtr->ident, CHAR(STRING_ELT(el, 0))) == 0)
                        break;
                    lPtr++;
                }
                if (lPtr->ident == NULL)
                    error("Invalid LP Type: %s.", CHAR(STRING_ELT(el, 0)));
                strncpy(opt->type, lPtr->ident, strlen(lPtr->ident));
                if (expExt == 0)
                    strncpy(ext, lPtr->ext, strlen(lPtr->ext));
                break;
            case AF_SPECTRUM:
                sPtr = spectType;
                while (sPtr->ident != NULL) {
                    if (strcmp(sPtr->ident, CHAR(STRING_ELT(el, 0))) == 0)
                        break;
                    sPtr++;
                }
                if (sPtr->ident == NULL)
                    error("Invalid SP Type: %s.", CHAR(STRING_ELT(el, 0)));
                strncpy(opt->type, sPtr->ident, strlen(sPtr->ident));
                if (setSPECTdefaults(opt) < 0) {
                    error("%s", getAsspMsg(asspMsgNum));
                }
                strncpy(opt->type, sPtr->ident, strlen(sPtr->ident));
                switch (sPtr->type) {
                case DT_FTPOW:
                case DT_FTAMP:
                case DT_FTSQR:
                    setDFTdefaults(opt);
                    break;
                case DT_FTLPS:
                    setLPSdefaults(opt);
                    break;
                case DT_FTCSS:
                    setCSSdefaults(opt);
                    break;
                case DT_FTCEP:
                    setCEPdefaults(opt);
                    break;
                default:
                    setAsspMsg(AEG_ERR_BUG,
                               "setSPECTdefaults: invalid default type");
                    error("%s.", getAsspMsg(asspMsgNum));
                    break;
                }
                if (expExt == 0)
                    strncpy(ext, sPtr->ext, strlen(sPtr->ext));
                break;
            default:
                break;
            }
            break;
        case WO_WINFUNC:
            wPtr = wfShortList;
            while (wPtr->code != NULL) {
                if (strcmp(wPtr->code, CHAR(STRING_ELT(el, 0))) == 0)
                    break;
                wPtr++;
            }
            if (wPtr->code == NULL)
                error("Invalid window function code %s.",
                      CHAR(STRING_ELT(el, 0)));
            strncpy(opt->winFunc, wPtr->code, strlen(wPtr->code));
            break;
            /*
             * These are not in libassp but in wrassp
             */
        case WO_ENERGYNORM:
            if (INTEGER(el)[0])
                opt->options |= ACF_OPT_NORM;
            else
                opt->options &= ~ACF_OPT_NORM;
            break;
        case WO_LENGTHNORM:
            if (INTEGER(el)[0])
                opt->options |= ACF_OPT_MEAN;
            else
                opt->options &= ~ACF_OPT_MEAN;
            break;
        case WO_DIFF_OPT_BACKWARD:
            if (INTEGER(el)[0])
                opt->options |= DIFF_OPT_BACKWARD;
            else
                opt->options &= ~DIFF_OPT_BACKWARD;
            break;
        case WO_DIFF_OPT_CENTRAL:
            if (INTEGER(el)[0])
                opt->options |= DIFF_OPT_CENTRAL;
            else
                opt->options &= ~DIFF_OPT_CENTRAL;
            break;
        case WO_RMS_OPT_LINEAR:
            if (INTEGER(el)[0])
                opt->options |= RMS_OPT_LINEAR;
            else
                opt->options &= ~RMS_OPT_LINEAR;
            break;
        case WO_LPS_OPT_DEEMPH:
            if (INTEGER(el)[0])
                opt->options |= LPS_OPT_DEEMPH;
            else
                opt->options &= ~LPS_OPT_DEEMPH;
            break;
        case WO_OUTPUTEXT:
            if (TYPEOF(el) == NILSXP) {
                expExt = 0;
                break;
            }
            cPtr = strdup(CHAR(STRING_ELT(el, 0)));
            if (*cPtr != '.' && strlen(cPtr) != 0) {
                strncpy(ext, ".", strlen(".") + 1);
                strcat(ext, cPtr);
            } else {
                strncpy(ext, cPtr, strlen(cPtr) + 1);
            }
            free(cPtr);
            expExt = 1;
            switch (anaFunc->funcNum) {
            case AF_RFCANA:
                lPtr = lpType;
                while (lPtr->ident != NULL) {
                    if (strcmp(opt->type, lPtr->ident) == 0)
                        break;
                    lPtr++;
                }
                if (lPtr->ident == NULL)
                    error("Bad LP Type in memory (%s).", opt->type);
                if (strcmp(lPtr->ext, ext) == 0) {
                    expExt = 0;
                } else {
                    expExt = 1;
                }
                break;
            case AF_SPECTRUM:
                sPtr = spectType;
                while (sPtr->ident != NULL) {
                    if (strcmp(opt->type, sPtr->ident) == 0)
                        break;
                    sPtr++;
                }
                if (sPtr->ident == NULL)
                    error("Bad SP Type in memory (%s).", opt->type);
                if (strcmp(sPtr->ext, ext) == 0) {
                    expExt = 0;
                } else {
                    expExt = 1;

                }
                break;
            default:
                break;
            }
            break;
        case WO_TOFILE:
            toFile = INTEGER(el)[0] != 0;
            break;
        case WO_OUTPUTDIR:
            if (el == R_NilValue) {
                outDir = NULL;
                break;
            }
            outDir = strdup(CHAR(STRING_ELT(el, 0)));
            if (outDir[strlen(outDir) - 1] != DIR_SEP_CHR) {
                /* add trailing slash, but we need a bit more space first */
                char *tmp = malloc(strlen(outDir) + 2);
                strcpy(tmp, outDir);
                tmp = strcat(tmp, DIR_SEP_STR);
                free(outDir);
                outDir = tmp;
            }
            break;
        case WO_PBAR:
            pBar = el;
            break;
        default:
            break;
        }
    }

    /*
     * output extension might still be unset. For afdiff and for spectral 
     * analysis we need to take special care. In other cases it would be
     * weird to get here but we can safely use the default. 
     */
    if (strcmp(ext, "") == 0) {
        /*
         * could be explicitely set to ""
         */
        if (!expExt) {
            switch (anaFunc->funcNum) {
            case AF_AFDIFF:
                /*
                 * needs to be handled on a per file basis
                 */
                break;
            case AF_SPECTRUM:
                sPtr = spectType;
                while (sPtr->ident != NULL) {
                    if (strcmp(opt->type, sPtr->ident) == 0)
                        break;
                    sPtr++;
                }
                if (sPtr->ident == NULL)
                    error("Bad SP Type in memory (%s).", opt->type);
                strcpy(ext, sPtr->ext);
                break;
            default:
                strcpy(ext, anaFunc->defExt);
                break;
            }
        }
    }
    /*
     * do analysis
     */

    /*
     * hook into the progressbar if present 
     */
    if (pBar != R_NilValue) {
        PROTECT(newVal = allocVector(INTSXP, 1));
        PROTECT(utilsPackage = eval(lang2(install("getNamespace"),
                                          ScalarString(mkChar("utils"))),
                                    R_GlobalEnv));
        INTEGER(newVal)[0] = 0;
        eval(lang4(install("setTxtProgressBar"), pBar, newVal, R_NilValue),
             utilsPackage);
    }

    /*
     * in memory only works for single input, not for multiple input so,
     * if toFile is false but there are multiple inputs set toFile to true 
     */
    toFile = toFile || length(inputs) != 1;

    /*
     * iterate over input files 
     */
    for (i = 0; i < length(inputs); i++) {
        /*
         * get inpput name and open
         */
        name = strdup(CHAR(STRING_ELT(inputs, i)));
        inPtr = asspFOpen(strdup(name), AFO_READ, (DOBJ *) NULL);
        if (inPtr == NULL)
            error("%s (%s)", getAsspMsg(asspMsgNum), strdup(name));

        /*
         * run the function (as pointed to in the descriptor) to generate
         * the output object 
         */
        outPtr = (anaFunc->compProc) (inPtr, opt, (DOBJ *) NULL);
        if (outPtr == NULL) {
            asspFClose(inPtr, AFC_FREE);
            error("%s (%s)", getAsspMsg(asspMsgNum), strdup(name));
        }

        /*
         * input data object no longer needed 
         */
        asspFClose(inPtr, AFC_FREE);


        if (toFile) {
            /*
             * in toFile mode, all DOBJs are written to file we will later 
             * return the number of successful analyses 
             */

            /*
             * parse the input path to get directory (dPath), base file
             * name (bPath) and original extension (oExt) 
             */
            parsepath((char *) name, &dPath, &bPath, &oExt);
            /*
             * outName is the same except for extension unless outDir is
             * set 
             */
            strcpy(outName, "");
            if (outDir == NULL)
                strcat(outName, dPath);
            else
                strcat(outName, outDir);
            strcat(outName, bPath);
            /*
             * Extension may have to be set for afdiff but only if
             * extension is not set explicitely 
             */
            if (strcmp(ext, "") == 0 && !expExt) {
                switch (anaFunc->funcNum) {
                case AF_AFDIFF:
                    strcpy(ext, ".d");
                    oExt++;     /* skip period */
                    strcat(ext, oExt);
                    break;
                default:
                    error("Extension handling failed (performAssp).");
                    break;
                }
            }
            strcat(outName, ext);

            /*
             * out put name is complete, use it to open the file for the
             * output object, then write and close and free 
             */
            outPtr = asspFOpen(outName, AFO_WRITE, outPtr);
            if (outPtr == NULL) {
                asspFClose(outPtr, AFC_FREE);
                error("%s (%s)", getAsspMsg(asspMsgNum), strdup(outName));
            }
            if (asspFFlush(outPtr, 0) == -1) {
                asspFClose(outPtr, AFC_FREE);
                error("%s (%s)", getAsspMsg(asspMsgNum), strdup(outName));
            }
            asspFClose(outPtr, AFC_FREE);
        } else {
            res = dobj2AsspDataObj(outPtr);
            asspFClose(outPtr, AFC_FREE);
        }

        free((char *) name);

        /*
         * if a progress bar was passed over, increment its value
         */
        if (pBar != R_NilValue) {
            INTEGER(newVal)[0] = i + 1;
            eval(lang4
                 (install("setTxtProgressBar"), pBar, newVal, R_NilValue),
                 utilsPackage);
        }
    }
    free((void *) outDir);
    if (toFile) {
        /*
         * in toFile mode, the number of successful analyses is returned
         */
        PROTECT(res = allocVector(INTSXP, 1));
        INTEGER(res)[0] = i;
    }
    /*
     * for the progress bar, to SEXPs were protected
     */
    if (pBar != R_NilValue)
        UNPROTECT(2);

    /*
     * in toFile mode, the return value was protected
     */
    if (toFile)
        UNPROTECT(1);
    return res;
}
// read “size” bytes from the file after moving 
// “offset” through the file, use math to determine the block
static int tar_read(const char *path, char *buf, size_t size, off_t offset,
	struct fuse_file_info *fi)
{
	int errornumber = 0;

	// connect to database, begin a transaction
	MYSQL *con = mysql_init(NULL);
	//read options from file
	mysql_options(con, MYSQL_READ_DEFAULT_FILE, SQLCONFILE); //SQLCONFILE defined in sqloptions.h
	mysql_options(con, MYSQL_READ_DEFAULT_GROUP, SQLGROUP);

	if(!mysql_real_connect(con, NULL, NULL, NULL, NULL, 0, NULL, 0)) {
		//exit, connection failed
		mysql_close(con);
		errornumber = -EIO;
		return errornumber;
	}

	char* archivename = NULL;
	char* within_tar_path = NULL;
	char* within_tar_filename = NULL;
	char* file_ext = NULL;
	parsepath(path, &archivename, &within_tar_path, &within_tar_filename, &file_ext);
	char insQuery[1000];

	// read specific variables
	char path_to_archive[5000]; //stored path to the real location of the archive
	struct blockmap* block_offsets = (struct blockmap*) malloc(sizeof(struct blockmap));
	block_offsets->blocklocations = NULL; // map of blocks in archive
	off_t real_offset; // offset of file within block + offset from beginning of file
	size_t real_size; // the real amount to read min("size" , "filesize - offset")
	

	// path is "/"
	if(archivename == NULL) {
		errornumber = -EACCES;
	}
	// path is "/TarArchive.tar" or "/TarArchive.tar.bz2" or "/TarArchive.tar.xz"
	else if(within_tar_path == NULL) {
		long long int archiveid = 0 + fi->fh; //get archive id from file_info
		sprintf(insQuery, "SELECT ArchivePath, Timestamp from ArchiveList WHERE ArchiveID = %lld", archiveid);
		if(mysql_query(con, insQuery)) {
			//query error
			errornumber = -EIO;
		}
		else {
			MYSQL_RES* result = mysql_store_result(con);
			if(result == NULL) {
				errornumber = -EIO;
			}
			else {
				if(mysql_num_rows(result) == 0) {
					//file does not exist, set not found error
					errornumber = -ENOENT;
				}
				else {
					MYSQL_ROW row = mysql_fetch_row(result);
					struct stat statbuff;
					if(lstat(row[0], &statbuff) == -1) {
						errornumber = -errno;
					}
					//check timestamp
					else {
						char* mod_time = ctime(&(statbuff.st_mtime));
						if(strcmp(row[1], mod_time) != 0) {
							errornumber = -ENOENT;
						}
						// open and read file
						else {
							int fi_des = open(row[0], O_RDONLY);
							if (fi_des == -1)
								errornumber = -errno;
							else {
								if (pread(fi_des, buf, size, offset) == -1) errornumber = -errno;
								close(fi_des);
							}
						}
					}
				}
				mysql_free_result(result);
			}
		}
	}
	// path is /TarArchive.tar/more
	else {
		/* Get Archive's real path ********************************************/
		sprintf(insQuery, "SELECT ArchivePath, Timestamp from ArchiveList WHERE ArchiveName = '%s'", archivename);
		if(mysql_query(con, insQuery)) {
			//query error
			errornumber = -EIO;
		}
		else {
			MYSQL_RES* result = mysql_store_result(con);
			if(result == NULL) {
				errornumber = -EIO;
			}
			else {
				if(mysql_num_rows(result) == 0) {
					//file does not exist, set not found error
					errornumber = -ENOENT;
				}
				else {
					MYSQL_ROW row = mysql_fetch_row(result);
					struct stat statbuff;
					if(lstat(row[0], &statbuff) == -1) {
						errornumber = -errno;
					}
					//check timestamp
					else {
						char* mod_time = ctime(&(statbuff.st_mtime));
						if(strcmp(row[1], mod_time) != 0) {
							errornumber = -ENOENT;
						}
						// copy filepath to easy location
						else {
							strcpy(path_to_archive, row[0]);
						}
					}
				}
				mysql_free_result(result);
			}
		}

		/* Load Blockmap ******************************************************/
		if(errornumber == 0) {
			int needBlockmap = 0;
			//no file extension
			if(file_ext == NULL) errornumber = -ENOENT;
			//.tar
			else if(strcmp(".tar", file_ext) == 0) {
				needBlockmap = 0;
			}
			//.bz2 //TODO add other forms of bz2 extention
			else if(strcmp(".bz2", file_ext) == 0) {
				needBlockmap = 1;
				sprintf(insQuery, "SELECT Blocknumber, BlockOffset, BlockSize from Bzip2_blocks WHERE ArchiveName = '%s'", archivename);
			}
			//.xz or .txz
			else if(strcmp(".xz", file_ext) == 0 || strcmp(".txz", file_ext) == 0) {
				needBlockmap = 1;
				sprintf(insQuery, "SELECT Blocknumber, BlockOffset, BlockSize from CompXZ_blocks WHERE ArchiveName = '%s'", archivename);
			}
			//unrecognized file extension
			else errornumber = -ENOENT;
	
			//if no error and we need a blockmap send query and use result
			if(errornumber == 0 && needBlockmap == 1) {
				if(mysql_query(con, insQuery)) {
					//query error
					errornumber = -EIO;
				}
				else {
					MYSQL_RES* result = mysql_store_result(con);
					if(result == NULL) {
						errornumber = -EIO;
					}
					else {
						int number_of_results = mysql_num_rows(result);
						if(number_of_results == 0) {
							//no results
							errornumber = -ENOENT;
						}
						else {
							MYSQL_ROW row;
							//while there are rows to be fetched
							block_offsets->blocklocations = (struct blocklocation*) malloc(sizeof(struct blocklocation) * (number_of_results + 10)); //slightly too large to be safe
							block_offsets->maxsize = (number_of_results + 10);
							while((row = mysql_fetch_row(result))) {
								long int this_block_num = strtol(row[0], NULL, 10);
								unsigned long long this_pos = strtoull(row[1], NULL, 10);
								unsigned long long this_unC_size = strtoull(row[2], NULL, 10);
								((block_offsets->blocklocations)[this_block_num]).position = this_pos;
								((block_offsets->blocklocations)[this_block_num]).uncompressedSize = this_unC_size;
							}
						}
						mysql_free_result(result);
					}
				}
			}
		}

		/************** get info about file you want to extract and do the read *******/
		if(errornumber == 0) {
			long long int files_id = 0 + fi->fh; //get archive id from file_info
			//no file extension
			if(file_ext == NULL) errornumber = -ENOENT;
			//.tar
			else if(strcmp(".tar", file_ext) == 0) {
				sprintf(insQuery, "SELECT GBoffset, BYTEoffset, MemberLength from UncompTar WHERE FileID = %lld", files_id);
				if(mysql_query(con, insQuery)) {
					//query error
					errornumber = -EIO;
				}
				else {
					MYSQL_RES* result = mysql_store_result(con);
					if(result == NULL) {
						errornumber = -EIO;
					}
					else {
						if(mysql_num_rows(result) == 0) {
							//no results
							errornumber = -ENOENT;
						}
						else {
							MYSQL_ROW row;
							row = mysql_fetch_row(result);
							unsigned long long length_of_file = strtoull(row[2], NULL, 10);
							//check if offset puts us outside file range
							if(offset >= length_of_file) errornumber = -ENXIO;
							else {
								//calculate real offset in tarfile
								real_offset = (strtoull(row[0], NULL, 10) * BYTES_IN_GB) + strtoull(row[1], NULL, 10) + offset;
								//calculate real size to be read
								real_size = length_of_file - offset;
								if(size < real_size) {
									real_size = size;
								}
								
								int fi_des = open(path_to_archive, O_RDONLY);
								if (fi_des == -1)
									errornumber = -errno;
								else {
									unsigned long long Re = pread(fi_des, buf, real_size, real_offset);
									if (Re == -1) errornumber = -errno;
									else errornumber = Re;
									
									close(fi_des);
								}
							}
						}
						mysql_free_result(result);
					}
				}
			}
			//TODO.bz2 //TODO add other forms of bz2 extention
			else if(strcmp(".bz2", file_ext) == 0 || strcmp(".xz", file_ext) == 0 || strcmp(".txz", file_ext) == 0) {
				int fileflag;
				if(strcmp(".bz2", file_ext) == 0) {
					sprintf(insQuery, "SELECT Blocknumber, InsideOffset, MemberLength from Bzip2_files WHERE FileID = %lld", files_id);
					fileflag = BZ2FLAG;
				}
				else {
					sprintf(insQuery, "SELECT Blocknumber, InsideOffset, MemberLength from CompXZ WHERE FileID = %lld", files_id);
					fileflag = XZFLAG;
				}
				if(mysql_query(con, insQuery)) {
					//query error
					errornumber = -EIO;
				}
				else {
					MYSQL_RES* result = mysql_store_result(con);
					if(result == NULL) {
						errornumber = -EIO;
					}
					else {
						if(mysql_num_rows(result) == 0) {
							//no results
							errornumber = -ENOENT;
						}
						else {
							MYSQL_ROW row;
							row = mysql_fetch_row(result);
							unsigned long long length_of_file = strtoull(row[2], NULL, 10);
							//check if offset puts us outside file range
							if(offset >= length_of_file) errornumber = -ENXIO;
							else {
								//find real block and real offset
								long long blocknumber = strtoll(row[0], NULL, 10);
								unsigned long long real_offset = 0 + strtoull(row[1], NULL, 10);
								unsigned long long data_remaining = ((block_offsets->blocklocations)[blocknumber]).uncompressedSize - real_offset;
								
								//calculate real size to be read
								real_size = length_of_file - offset;
								if(size < real_size) {
									real_size = size;
								}

								//move real_offset foward by "offset"
								unsigned long long remaining_seek = 0 + offset;
								printf("remaining_seek: %llu\n", remaining_seek);
								printf("blocknumber: %lld\n", blocknumber);
								while(remaining_seek > data_remaining) {
									blocknumber++;
									remaining_seek = remaining_seek - data_remaining;
									data_remaining = ((block_offsets->blocklocations)[blocknumber]).uncompressedSize;
									real_offset = 0;
								}
								if(remaining_seek != 0) {
									real_offset = 0 + remaining_seek;
								}

								//blocknumber and real_offset now point to the offset within the file desired by read
								unsigned long long bn = 0+blocknumber;
								unsigned long long ro = 0+real_offset;
								unsigned long long rs = 0+real_size;
								printf("block %llu, offset %llu, size %llu\n", bn, ro, rs);
								errornumber = read_compressed(path_to_archive, fileflag, blocknumber, real_offset, real_size, buf, block_offsets);
							}
						}
						mysql_free_result(result);
					}
				}
			}
			//unrecognized file extension
			else errornumber = -ENOENT;
		}
		
	}
	//free possible mallocs and mysql connection
	mysql_close(con);
	if(archivename != NULL) free(archivename);
	if(within_tar_path != NULL) free(within_tar_path);
	if(within_tar_filename != NULL) free(within_tar_filename);
	if(block_offsets->blocklocations != NULL) free(block_offsets->blocklocations);
	if(block_offsets != NULL) free(block_offsets);

	return errornumber;
}
// Fill stbuf structure similar to the lstat() function, some comes from lstat of the archive file, others come from database
static int tar_getattr(const char *path, struct stat *stbuf)
{	
	int errornumber = 0;

	// connect to database, begin a transaction
	MYSQL *con = mysql_init(NULL);
	//read options from file
	mysql_options(con, MYSQL_READ_DEFAULT_FILE, SQLCONFILE); //SQLCONFILE defined in sqloptions.h
	mysql_options(con, MYSQL_READ_DEFAULT_GROUP, SQLGROUP);

	if(!mysql_real_connect(con, NULL, NULL, NULL, NULL, 0, NULL, 0)) {
		//exit, connection failed
		mysql_close(con);
		errornumber = -EIO;
		return errornumber;
	}

	char* archivename = NULL;
	char* within_tar_path = NULL;
	char* within_tar_filename = NULL;
	char* file_ext = NULL;
	parsepath(path, &archivename, &within_tar_path, &within_tar_filename, &file_ext);
	char insQuery[1000];

	// path is "/"
	if(archivename == NULL) {
		memcpy(stbuf, &topdir, sizeof(topdir));
	}
	// path is "/TarArchive.tar" or "/TarArchive.tar.bz2" or "/TarArchive.tar.xz"
	else if(within_tar_path == NULL) {
		sprintf(insQuery, "SELECT ArchivePath, Timestamp from ArchiveList WHERE ArchiveName = '%s'", archivename);
		if(mysql_query(con, insQuery)) {
			//query error
			errornumber = -EIO;
		}
		else {
			MYSQL_RES* result = mysql_store_result(con);
			if(result == NULL) {
				errornumber = -EIO;
			}
			else {
				if(mysql_num_rows(result) == 0) {
					//file does not exist, set not found error
					errornumber = -ENOENT;
				}
				else {
					MYSQL_ROW row = mysql_fetch_row(result);
					if(lstat(row[0], stbuf) == -1) {
						errornumber = -errno;
					}
					//check timestamp
					else {
						char* mod_time = ctime(&(stbuf->st_mtime));
						if(strcmp(row[1], mod_time) != 0) {
							errornumber = -ENOENT;
						}
						//set to appear as directory
						stbuf->st_mode = topdir.st_mode; //directory w/ usual permissions
					}
				}
				mysql_free_result(result);
			}
		}
	}
	// path is /TarArchive.tar/more
	else {
		/* Seperate mysql queries for different filetypes */
		//no file extension
		if(file_ext == NULL) errornumber = -ENOENT;
		//.tar
		else if(strcmp(".tar", file_ext) == 0) {
			sprintf(insQuery, "SELECT MemberLength, Mode, Uid, Gid, Dirflag, LinkFlag from UncompTar WHERE ArchiveName = '%s' AND MemberPath = '%s' AND MemberName = '%s'", archivename, within_tar_path, within_tar_filename);
		}
		//.bz2 //TODO add other forms of bz2 extention
		else if(strcmp(".bz2", file_ext) == 0) {
			sprintf(insQuery, "SELECT MemberLength, Mode, Uid, Gid, Dirflag, LinkFlag from Bzip2_files WHERE ArchiveName = '%s' AND MemberPath = '%s' AND MemberName = '%s'", archivename, within_tar_path, within_tar_filename);
		}
		//.xz or .txz
		else if(strcmp(".xz", file_ext) == 0 || strcmp(".txz", file_ext) == 0) {
			sprintf(insQuery, "SELECT MemberLength, Mode, Uid, Gid, Dirflag, LinkFlag from CompXZ WHERE ArchiveName = '%s' AND MemberPath = '%s' AND MemberName = '%s'", archivename, within_tar_path, within_tar_filename);
		}
		//unrecognized file extension
		else errornumber = -ENOENT;

		//if no error send query and use result
		if(errornumber == 0) {
			if(mysql_query(con, insQuery)) {
				//query error
				errornumber = -EIO;
			}
			else {
				MYSQL_RES* result = mysql_store_result(con);
				if(result == NULL) {
					errornumber = -EIO;
				}
				else {
					if(mysql_num_rows(result) == 0) {
						//file does not exist, set not found error
						errornumber = -ENOENT;
					}
					else {
						MYSQL_ROW row = mysql_fetch_row(result);
						memcpy(stbuf, &topdir, sizeof(topdir));
						//stbuf->st_dev = same as topdir
						stbuf->st_ino = 999; //big useless number
						if(strncmp(row[5], "1", 1) == 0 || strncmp(row[5], "2", 1) == 0) {
							stbuf->st_mode = 0 + strtol(row[1], NULL, 10) + S_IFLNK;
						}
						else if(strcmp(row[4], "N") == 0) {
							stbuf->st_mode = 0 + strtol(row[1], NULL, 10) + S_IFREG;
						}
						else {
							stbuf->st_mode = 0 + strtol(row[1], NULL, 10) + S_IFDIR;
						}
						stbuf->st_nlink = 0;
						stbuf->st_uid = 0 + strtol(row[2], NULL, 10);
						stbuf->st_gid = 0 + strtol(row[3], NULL, 10);
						//stbuf->st_rdev = same as topdir
						stbuf->st_size = 0 + strtoll(row[0], NULL, 10);
						//stbuf->st_blksize = same as topdir
						stbuf->st_blocks = 0; //just set blocks to 0
						//access, modification, and stat times come from topdir
					}
					mysql_free_result(result);
				}
			}
		}
	}
	//free possible mallocs and mysql connection
	mysql_close(con);
	if(archivename != NULL) free(archivename);
	if(within_tar_path != NULL) free(within_tar_path);
	if(within_tar_filename != NULL) free(within_tar_filename);

	return errornumber;
}
//takes a symbolic link and puts its referenced path in buf
static int tar_readlink(const char *path, char *buf, size_t size)
{
	int errornumber = 0;

	// connect to database, begin a transaction
	MYSQL *con = mysql_init(NULL);
	//read options from file
	mysql_options(con, MYSQL_READ_DEFAULT_FILE, SQLCONFILE); //SQLCONFILE defined in sqloptions.h
	mysql_options(con, MYSQL_READ_DEFAULT_GROUP, SQLGROUP);

	if(!mysql_real_connect(con, NULL, NULL, NULL, NULL, 0, NULL, 0)) {
		//exit, connection failed
		mysql_close(con);
		errornumber = -EIO;
		return errornumber;
	}

	char* archivename = NULL;
	char* within_tar_path = NULL;
	char* within_tar_filename = NULL;
	char* file_ext = NULL;
	parsepath(path, &archivename, &within_tar_path, &within_tar_filename, &file_ext);
	char insQuery[1000];

	// path is "/"
	if(archivename == NULL) {
		errornumber = -EINVAL;
	}
	// path is "/TarArchive.tar" or "/TarArchive.tar.bz2" or "/TarArchive.tar.xz"
	else if(within_tar_path == NULL) {
		errornumber = -EINVAL;
	}
	// path is /TarArchive.tar/more
	else {
		/* Seperate mysql queries for different filetypes */
		//no file extension
		if(file_ext == NULL) errornumber = -ENOENT;
		//.tar
		else if(strcmp(".tar", file_ext) == 0) {
			sprintf(insQuery, "SELECT LinkFlag, LinkTarget from UncompTar WHERE ArchiveName = '%s' AND MemberPath = '%s' AND MemberName = '%s'", archivename, within_tar_path, within_tar_filename);
		}
		//.bz2 //TODO add other forms of bz2 extention
		else if(strcmp(".bz2", file_ext) == 0) {
			sprintf(insQuery, "SELECT LinkFlag, LinkTarget from Bzip2_files WHERE ArchiveName = '%s' AND MemberPath = '%s' AND MemberName = '%s'", archivename, within_tar_path, within_tar_filename);
		}
		//.xz or .txz
		else if(strcmp(".xz", file_ext) == 0 || strcmp(".txz", file_ext) == 0) {
			sprintf(insQuery, "SELECT LinkFlag, LinkTarget from CompXZ WHERE ArchiveName = '%s' AND MemberPath = '%s' AND MemberName = '%s'", archivename, within_tar_path, within_tar_filename);
		}
		//unrecognized file extension
		else errornumber = -ENOENT;

		//if no error send query and use result
		if(errornumber == 0) {
			if(mysql_query(con, insQuery)) {
				//query error
				errornumber = -EIO;
			}
			else {
				MYSQL_RES* result = mysql_store_result(con);
				if(result == NULL) {
					errornumber = -EIO;
				}
				else {
					if(mysql_num_rows(result) == 0) {
						//file does not exist, set not found error
						errornumber = -ENOENT;
					}
					else {
						MYSQL_ROW row = mysql_fetch_row(result);
						//check if its a hardlink "1" or softlink "2"
						if(strncmp(row[0], "2", 1) == 0) {
							strncpy(buf, row[1], (size-1));
							buf[(size-1)] = '\0';
						}
						else if(strncmp(row[0], "1", 1) == 0) {
							char linkstring[5000];
							char converted_linkstring[8000] = "";
							sprintf(linkstring, "%s/%s", archivename, row[1]);
							int dots = 0;
							int i;
							for(i=0;i<strlen(path);i++) {
								if(path[i] == '/') dots++;
							}

							for(i=1;i<dots;i++) {
								strcat(converted_linkstring, "../");
							}
							strcat(converted_linkstring, linkstring);
							strncpy(buf, converted_linkstring, (size-1));
							buf[(size-1)] = '\0';
						}
						else {
							errornumber = -EINVAL;
						}
					}
					mysql_free_result(result);
				}
			}
		}
	}
	//free possible mallocs and mysql connection
	mysql_close(con);
	if(archivename != NULL) free(archivename);
	if(within_tar_path != NULL) free(within_tar_path);
	if(within_tar_filename != NULL) free(within_tar_filename);

	return errornumber;
}
// -extra slashes are omitted (ex. "/home/" becomes "/home"
static int tar_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
	off_t offset, struct fuse_file_info *fi)
{
	//printf("\nDEBUG READDIR: entered - %s\n", path);
	int errornumber = 0;

	// connect to database, begin a transaction
	MYSQL *con = mysql_init(NULL);
	//read options from file
	mysql_options(con, MYSQL_READ_DEFAULT_FILE, SQLCONFILE); //SQLCONFILE defined in sqloptions.h
	mysql_options(con, MYSQL_READ_DEFAULT_GROUP, SQLGROUP);

	if(!mysql_real_connect(con, NULL, NULL, NULL, NULL, 0, NULL, 0)) {
		//exit, connection failed
		mysql_close(con);
		errornumber = -EIO;
		return errornumber;
	}

	char* archivename = NULL;
	char* within_tar_path = NULL;
	char* within_tar_filename = NULL;
	char* file_ext = NULL;
	parsepath(path, &archivename, &within_tar_path, &within_tar_filename, &file_ext);
	char insQuery[1000];

	// path is "/"
	if(archivename == NULL) {
		sprintf(insQuery, "SELECT ArchiveName, ArchivePath, Timestamp from ArchiveList");
		if(mysql_query(con, insQuery)) {
			//query error
			errornumber = -EIO;
		}
		else {
			MYSQL_RES* result = mysql_store_result(con);
			if(result == NULL) {
				errornumber = -EIO;
			}
			else {
				if(mysql_num_rows(result) == 0) {
					//no results
					errornumber = 0;
				}
				else {
					//while there are rows to be fetched
					MYSQL_ROW row;
					while((row = mysql_fetch_row(result))) {
						//get the real stats of the file
						struct stat st;
						memset(&st, 0, sizeof(st));
						if(lstat(row[1], &st) == 0) {
							//redefine as directory and pass to filler
							st.st_mode = topdir.st_mode; //directory w/ usual permissions;
							//check timestamp
							char* mod_time = ctime(&(st.st_mtime));
							if(strcmp(row[2], mod_time) == 0) {
								if (filler(buf, row[0], &st, 0)) break;
							}
						}
					}
				}
				mysql_free_result(result);
			}
		}
	}
	// path is "/TarArchive.tar" or "/TarArchive.tar.bz2" or "/TarArchive.tar.xz"
	else if(within_tar_path == NULL) {
		//printf("DEBUG READDIR: readdir on archive.tar\n");
		/* Seperate mysql queries for different filetypes */
		//no file extension
		if(file_ext == NULL) errornumber = -ENOENT;
		//.tar
		else if(strcmp(".tar", file_ext) == 0) {
			sprintf(insQuery, "SELECT DirFlag, MemberLength, MemberName, Mode, Uid, Gid, LinkFlag from UncompTar WHERE ArchiveName = '%s' AND MemberPath = '/'", archivename);
		}
		//.bz2 //TODO add other forms of bz2 extention
		else if(strcmp(".bz2", file_ext) == 0) {
			sprintf(insQuery, "SELECT DirFlag, MemberLength, MemberName, Mode, Uid, Gid, LinkFlag from Bzip2_files WHERE ArchiveName = '%s' AND MemberPath = '/'", archivename);
		}
		//.xz or .txz
		else if(strcmp(".xz", file_ext) == 0 || strcmp(".txz", file_ext) == 0) {
			sprintf(insQuery, "SELECT DirFlag, MemberLength, MemberName, Mode, Uid, Gid, LinkFlag from CompXZ WHERE ArchiveName = '%s' AND MemberPath = '/'", archivename);
		}
		//unrecognized file extension
		else errornumber = -ENOENT;

		//if no error send query and use result
		if(errornumber == 0) {
			//printf("DEBUG READDIR: sending query %s\n", insQuery);
			if(mysql_query(con, insQuery)) {
				//query error
				errornumber = -EIO;
			}
			else {
				MYSQL_RES* result = mysql_store_result(con);
				if(result == NULL) {
					errornumber = -EIO;
				}
				else {
					if(mysql_num_rows(result) == 0) {
						//printf("DEBUG READDIR: NO RESULTS\n");
						//no results
						errornumber = 0;
					}
					else {
						//while there are rows to be fetched
						MYSQL_ROW row;
						while((row = mysql_fetch_row(result))) {
							//get the real stats of the file
							struct stat st;
							memcpy(&st, &topdir, sizeof(topdir));
							//st.st_dev = same as topdir
							st.st_ino = 999; //big useless number
							if(strncmp(row[6], "1", 1) == 0 || strncmp(row[6], "2", 1) == 0) {
								st.st_mode = 0 + strtol(row[3], NULL, 10) + S_IFLNK;
							}
							else if(strcmp(row[0], "N") == 0) {
								st.st_mode = 0 + strtol(row[3], NULL, 10) + S_IFREG;
							}
							else {
								st.st_mode = 0 + strtol(row[3], NULL, 10) + S_IFDIR;
							}
							st.st_nlink = 0;
							st.st_uid = 0 + strtoll(row[4], NULL, 10);
							st.st_gid = 0 + strtoll(row[5], NULL, 10);
							//st.st_rdev = same as topdir
							st.st_size = 0 + strtoll(row[1], NULL, 10);
							//st->st_blksize = same as topdir
							st.st_blocks = 0; //just set blocks to 0
							//access, modification, and stat times come from topdir
							if (filler(buf, row[2], &st, 0)) break;
						}
					}
					mysql_free_result(result);
				}
			}
		}
	}
	// path is /TarArchive.tar/more
	else {
		/* Seperate mysql queries for different filetypes */
		//printf("DEBUG READDIR: readdir on archive.tar/more\n");
		//no file extension
		if(file_ext == NULL) errornumber = -ENOENT;
		//.tar
		else if(strcmp(".tar", file_ext) == 0) {
			sprintf(insQuery, "SELECT DirFlag, MemberLength, MemberName, Mode, Uid, Gid, LinkFlag from UncompTar WHERE ArchiveName = '%s' AND MemberPath = '%s%s/'", archivename, within_tar_path, within_tar_filename);
		}
		//.bz2 //TODO add other forms of bz2 extention
		else if(strcmp(".bz2", file_ext) == 0) {
			sprintf(insQuery, "SELECT DirFlag, MemberLength, MemberName, Mode, Uid, Gid, LinkFlag from Bzip2_files WHERE ArchiveName = '%s' AND MemberPath = '%s%s/'", archivename, within_tar_path, within_tar_filename);
		}
		//.xz or .txz
		else if(strcmp(".xz", file_ext) == 0 || strcmp(".txz", file_ext) == 0) {
			sprintf(insQuery, "SELECT DirFlag, MemberLength, MemberName, Mode, Uid, Gid, LinkFlag from CompXZ WHERE ArchiveName = '%s' AND MemberPath = '%s%s/'", archivename, within_tar_path, within_tar_filename);
		}
		//unrecognized file extension
		else errornumber = -ENOENT;

		//if no error send query and use result
		if(errornumber == 0) {
			//printf("DEBUG READDIR: sending query %s\n", insQuery);
			if(mysql_query(con, insQuery)) {
				//query error
				errornumber = -EIO;
			}
			else {
				MYSQL_RES* result = mysql_store_result(con);
				if(result == NULL) {
					errornumber = -EIO;
				}
				else {
					if(mysql_num_rows(result) == 0) {
						//printf("DEBUG READDIR: NO RESULTS\n");
						//no results
						errornumber = 0;
					}
					else {
						//while there are rows to be fetched
						MYSQL_ROW row;
						while((row = mysql_fetch_row(result))) {
							//get the real stats of the file
							struct stat st;
							memcpy(&st, &topdir, sizeof(topdir));
							//st.st_dev = same as topdir
							st.st_ino = 999; //big useless number
							if(strncmp(row[6], "1", 1) == 0 || strncmp(row[6], "2", 1) == 0) {
								st.st_mode = 0 + strtol(row[3], NULL, 10) + S_IFLNK;
							}
							else if(strcmp(row[0], "N") == 0) {
								st.st_mode = 0 + strtol(row[3], NULL, 10) + S_IFREG;
							}
							else {
								st.st_mode = 0 + strtol(row[3], NULL, 10) + S_IFDIR;
							}
							st.st_nlink = 0;
							st.st_uid = 0 + strtoll(row[4], NULL, 10);
							st.st_gid = 0 + strtoll(row[5], NULL, 10);
							//st.st_rdev = same as topdir
							st.st_size = 0 + strtoll(row[1], NULL, 10);
							//st.st_blksize = same as topdir
							st.st_blocks = 0; //just set blocks to 0
							//access, modification, and stat times come from topdir
							if (filler(buf, row[2], &st, 0)) break;
						}
					}
					mysql_free_result(result);
				}
			}
		}
	}
	//free possible mallocs and mysql connection
	mysql_close(con);
	if(archivename != NULL) free(archivename);
	if(within_tar_path != NULL) free(within_tar_path);
	if(within_tar_filename != NULL) free(within_tar_filename);

	return errornumber;
}
// if file exists:
//   if fi->flags != RD_ONLY return (-1 * EACCES);
//   else return 0;
// else return (-1 * ENOENT);
static int tar_open(const char *path, struct fuse_file_info *fi)
{
	int errornumber = 0;

	// connect to database, begin a transaction
	MYSQL *con = mysql_init(NULL);
	//read options from file
	mysql_options(con, MYSQL_READ_DEFAULT_FILE, SQLCONFILE); //SQLCONFILE defined in sqloptions.h
	mysql_options(con, MYSQL_READ_DEFAULT_GROUP, SQLGROUP);

	if(!mysql_real_connect(con, NULL, NULL, NULL, NULL, 0, NULL, 0)) {
		//exit, connection failed
		mysql_close(con);
		errornumber = -EIO;
		return errornumber;
	}

	char* archivename = NULL;
	char* within_tar_path = NULL;
	char* within_tar_filename = NULL;
	char* file_ext = NULL;
	parsepath(path, &archivename, &within_tar_path, &within_tar_filename, &file_ext);
	char insQuery[1000];

	// path is "/"
	if(archivename == NULL) {
		errornumber = -EACCES;
	}
	// path is "/TarArchive.tar" or "/TarArchive.tar.bz2" or "/TarArchive.tar.xz"
	else if(within_tar_path == NULL) {
		sprintf(insQuery, "SELECT ArchivePath, Timestamp, ArchiveID from ArchiveList WHERE ArchiveName = '%s'", archivename);
		if(mysql_query(con, insQuery)) {
			//query error
			errornumber = -EIO;
		}
		else {
			MYSQL_RES* result = mysql_store_result(con);
			if(result == NULL) {
				errornumber = -EIO;
			}
			else {
				if(mysql_num_rows(result) == 0) {
					//file does not exist, set not found error
					errornumber = -ENOENT;
				}
				else {
					MYSQL_ROW row = mysql_fetch_row(result);
					struct stat statbuff;
					if(lstat(row[0], &statbuff) == -1) {
						errornumber = -errno;
					}
					//check timestamp
					else {
						char* mod_time = ctime(&(statbuff.st_mtime));
						if(strcmp(row[1], mod_time) != 0) {
							errornumber = -ENOENT;
						}
						//check fi->flags for read only
						else if((fi->flags & O_ACCMODE) != O_RDONLY) {
							errornumber = -EACCES;
						}
						else fi->fh = 0 + strtoll(row[2], NULL, 10);
					}
				}
				mysql_free_result(result);
			}
		}
	}
	// path is /TarArchive.tar/more
	else {
		/* Seperate mysql queries for different filetypes */
		//no file extension
		if(file_ext == NULL) errornumber = -ENOENT;
		//.tar
		else if(strcmp(".tar", file_ext) == 0) {
			sprintf(insQuery, "SELECT DirFlag, FileID from UncompTar WHERE ArchiveName = '%s' AND MemberPath = '%s' AND MemberName = '%s'", archivename, within_tar_path, within_tar_filename);
		}
		//.bz2 //TODO add other forms of bz2 extention
		else if(strcmp(".bz2", file_ext) == 0) {
			sprintf(insQuery, "SELECT DirFlag, FileID from Bzip2_files WHERE ArchiveName = '%s' AND MemberPath = '%s' AND MemberName = '%s'", archivename, within_tar_path, within_tar_filename);
		}
		//.xz or .txz
		else if(strcmp(".xz", file_ext) == 0 || strcmp(".txz", file_ext) == 0) {
			sprintf(insQuery, "SELECT DirFlag, FileID from CompXZ WHERE ArchiveName = '%s' AND MemberPath = '%s' AND MemberName = '%s'", archivename, within_tar_path, within_tar_filename);
		}
		//unrecognized file extension
		else errornumber = -ENOENT;

		//if no error send query and use result
		if(errornumber == 0) {
			if(mysql_query(con, insQuery)) {
				//query error
				errornumber = -EIO;
			}
			else {
				MYSQL_RES* result = mysql_store_result(con);
				if(result == NULL) {
					errornumber = -EIO;
				}
				else {
					if(mysql_num_rows(result) == 0) {
						//file does not exist, set not found error
						errornumber = -ENOENT;
					}
					else {
						MYSQL_ROW row = mysql_fetch_row(result);
						if(strcmp(row[0], "Y") == 0) {
							//directory, not allowed to open
							errornumber = -EACCES;
						}
						else {
							//file, only reading allowed
							if((fi->flags & O_ACCMODE) != O_RDONLY) {
								printf("DEBUG, not read only\n");
								errornumber = -EACCES;
							}
							//set file handle to ID
							else {
								fi->fh = 0 + strtoll(row[1], NULL, 10);
							}
						}
					}
					mysql_free_result(result);
				}
			}
		}
	}
	//free possible mallocs and mysql connection
	mysql_close(con);
	if(archivename != NULL) free(archivename);
	if(within_tar_path != NULL) free(within_tar_path);
	if(within_tar_filename != NULL) free(within_tar_filename);

	return errornumber;
}