static int handle_leaf(direntry_t *direntry, MainParam_t *mp,
		       lookupState_t *lookupState)
{
	Stream_t *MyFile=0;
	int ret;

	if(got_signal)
		return ERROR_ONE;
	if(lookupState) {
		/* we are looking for a "target" file */
		switch(lookupState->nbDirs) {
			case 0: /* no directory yet, open it */
				lookupState->Dir = OpenFileByDirentry(direntry);
				lookupState->nbDirs++;
				/* dump the container, we have
				 * better now */
				FREE(&lookupState->container);
				return 0;
			case 1: /* we have already a directory */
				FREE(&lookupState->Dir);
				fprintf(stderr,"Ambigous\n");
				return STOP_NOW | ERROR_ONE;
			default:
				return STOP_NOW | ERROR_ONE;
		}
	}

	mp->direntry = direntry;
	if(IS_DIR(direntry)) {
		if(mp->lookupflags & (DO_OPEN | DO_OPEN_DIRS))
			MyFile = mp->File = OpenFileByDirentry(direntry);
		ret = mp->dirCallback(direntry, mp);
	} else {
		if(mp->lookupflags & DO_OPEN)
			MyFile = mp->File = OpenFileByDirentry(direntry);
		ret = mp->callback(direntry, mp);
	}
	FREE(&MyFile);
	if(isUniqueTarget(mp->targetName))
		ret |= STOP_NOW;
	return ret;
}
Beispiel #2
0
static int del_file(direntry_t *entry, MainParam_t *mp)
{
	char shortname[13];
	direntry_t subEntry;
	Stream_t *SubDir;
	Arg_t *arg = (Arg_t *) mp->arg;
	MainParam_t sonmp;
	int ret;
	int r;	

	sonmp = *mp;
	sonmp.arg = mp->arg;

	r = 0;
	if (IS_DIR(entry)){
		/* a directory */		
		SubDir = OpenFileByDirentry(entry);
		initializeDirentry(&subEntry, SubDir);
		ret = 0;
		while((r=vfat_lookup(&subEntry, "*", 1,
				     ACCEPT_DIR | ACCEPT_PLAIN,
				     shortname, NULL)) == 0 ){
			if(shortname[0] != DELMARK &&
			   shortname[0] &&
			   shortname[0] != '.' ){
				if(arg->deltype != 2){
					fprintf(stderr,
						"Directory ");
					fprintPwd(stderr, entry,0);
					fprintf(stderr," non empty\n");
					ret = ERROR_ONE;
					break;
				}
				if(got_signal) {
					ret = ERROR_ONE;
					break;
				}
				ret = del_file(&subEntry, &sonmp);
				if( ret & ERROR_ONE)
					break;
				ret = 0;
			}
		}
		FREE(&SubDir);
		if (r == -2)
			return ERROR_ONE;
		if(ret)
			return ret;
	}
	return del_entry(entry, mp);
}
Beispiel #3
0
static Stream_t *subDir(Stream_t *parent, const char *filename)
{
	direntry_t entry;		
	initializeDirentry(&entry, parent);

	switch(vfat_lookup(&entry, filename, -1, ACCEPT_DIR, 0, 0)) {
	    case 0:
		return OpenFileByDirentry(&entry);
	    case -1:
		return NULL;
	    default: /* IO Error */
		return NULL;
	}
}
Beispiel #4
0
/*
 * Open the named file for read, create the cluster chain, return the
 * directory structure or NULL on error.
 */
int makeit(char *dosname,
	    char *longname,
	    void *arg0,
	    direntry_t *targetEntry)
{
	Stream_t *Target;
	CreateArg_t *arg = (CreateArg_t *) arg0;
	int fat;
	direntry_t subEntry;	

	/* will it fit? At least one cluster must be free */
	if (!getfreeMinClusters(targetEntry->Dir, 1))
		return -1;
	
	mk_entry(dosname, ATTR_DIR, 1, 0, arg->mtime, &targetEntry->dir);
	Target = OpenFileByDirentry(targetEntry);
	if(!Target){
		fprintf(stderr,"Could not open Target\n");
		return -1;
	}

	/* this allocates the first cluster for our directory */

	initializeDirentry(&subEntry, Target);

	subEntry.entry = 1;
	GET_DATA(targetEntry->Dir, 0, 0, 0, &fat);
	if (fat == fat32RootCluster(targetEntry->Dir)) {
	    fat = 0;
	}
	mk_entry("..         ", ATTR_DIR, fat, 0, arg->mtime, &subEntry.dir);
	dir_write(&subEntry);

	FLUSH((Stream_t *) Target);
	subEntry.entry = 0;
	GET_DATA(Target, 0, 0, 0, &fat);
	mk_entry(".          ", ATTR_DIR, fat, 0, arg->mtime, &subEntry.dir);
	dir_write(&subEntry);

	mk_entry(dosname, ATTR_DIR | arg->attr, fat, 0, arg->mtime, 
		 &targetEntry->dir);
	arg->NewDir = Target;
	return 0;
}
static int _dos_loop(Stream_t *Dir, MainParam_t *mp, const char *filename)
{	
	Stream_t *MyFile=0;
	direntry_t entry;
	int ret;
	int r;
	
	ret = 0;
	r=0;
	initializeDirentry(&entry, Dir);
	while(!got_signal &&
	      (r=vfat_lookup(&entry, filename, -1,
			     mp->lookupflags, mp->shortname, 
			     mp->longname)) == 0 ){
		mp->File = NULL;
		if(!checkForDot(mp->lookupflags,entry.name)) {
			MyFile = 0;
			if((mp->lookupflags & DO_OPEN) ||
			   (IS_DIR(&entry) && 
			    (mp->lookupflags & DO_OPEN_DIRS))) {
				MyFile = mp->File = OpenFileByDirentry(&entry);
			}
			if(got_signal)
				break;
			mp->direntry = &entry;
			if(IS_DIR(&entry))
				ret |= mp->dirCallback(&entry,mp);
			else
				ret |= mp->callback(&entry, mp);
			FREE(&MyFile);
		}
		if (fat_error(Dir))
			ret |= ERROR_ONE;
		if(mp->fast_quit && (ret & ERROR_ONE))
			break;
	}
	if (r == -2)
	    return ERROR_ONE;
	if(got_signal)
		ret |= ERROR_ONE;
	return ret;
}
Beispiel #6
0
/*
 * Open the named file for read, create the cluster chain, return the
 * directory structure or NULL on error.
 */
static int writeit(char *dosname,
		   char *longname,
		   void *arg0,
		   direntry_t *entry)
{
	Stream_t *Target;
	time_t now;
	int type, fat, ret;
	time_t date;
	mt_size_t filesize, newsize;
	Arg_t *arg = (Arg_t *) arg0;



	if (arg->mp.File->Class->get_data(arg->mp.File,
									  & date, &filesize, &type, 0) < 0 ){
		fprintf(stderr, "Can't stat source file\n");
		return -1;
	}

	if (type){
		if (arg->verbose)
			fprintf(stderr, "\"%s\" is a directory\n", longname);
		return -1;
	}

	/*if (!arg->single || arg->recursive)*/
	if(arg->verbose)
		fprintf(stderr,"Copying %s\n", longname);
	if(got_signal)
		return -1;

	/* will it fit? */
	if (!getfreeMinBytes(arg->mp.targetDir, filesize))
		return -1;
	
	/* preserve mod time? */
	if (arg->preserveTime)
		now = date;
	else
		getTimeNow(&now);

	mk_entry(dosname, arg->attr, 1, 0, now, &entry->dir);

	Target = OpenFileByDirentry(entry);
	if(!Target){
		fprintf(stderr,"Could not open Target\n");
		exit(1);
	}
	if (arg->needfilter & arg->textmode)
		Target = open_filter(Target);



	ret = copyfile(arg->mp.File, Target);
	GET_DATA(Target, 0, &newsize, 0, &fat);
	FREE(&Target);
	if (arg->needfilter & arg->textmode)
	    newsize++; /* ugly hack: we gathered the size before the Ctrl-Z
			* was written.  Increment it manually */
	if(ret < 0 ){
		fat_free(arg->mp.targetDir, fat);
		return -1;
	} else {
		mk_entry(dosname, arg->attr, fat, truncBytes32(newsize),
				 now, &entry->dir);
		return 0;
	}
}
static int recurs_dos_loop(MainParam_t *mp, const char *filename0, 
			   const char *filename1,
			   lookupState_t *lookupState)
{
	/* Dir is de-allocated by the same entity which allocated it */
	const char *ptr;
	direntry_t entry;
	int length;
	int lookupflags;
	int ret;
	int have_one;
	int doing_mcwd;
	int r;

	while(1) {
		/* strip dots and // */
		if(!strncmp(filename0,"./", 2)) {
			filename0 += 2;
			continue;
		}
		if(!strcmp(filename0,".") && filename1) {
			filename0 ++;
			continue;
		}
		if(filename0[0] == '/') {
			filename0++;
			continue;
		}
		if(!filename0[0]) {
			if(!filename1)
				break;
			filename0 = filename1;
			filename1 = 0;
			continue;
		}
		break;
	}

	if(!strncmp(filename0,"../", 3) || 
	   (!strcmp(filename0, "..") && filename1)) {
		/* up one level */
		mp->File = getDirentry(mp->File)->Dir;
		return recurs_dos_loop(mp, filename0+2, filename1, lookupState);
	}

	doing_mcwd = !!filename1;

	ptr = strchr(filename0, '/');
	if(!ptr) {			
		length = strlen(filename0);		
		ptr = filename1;
		filename1 = 0;
	} else {
		length = ptr - filename0;
		ptr++;
	}
	if(!ptr) {
		if(mp->lookupflags & OPEN_PARENT) {
			mp->targetName = filename0;
			ret = handle_leaf(getDirentry(mp->File), mp, 
					  lookupState);
			mp->targetName = 0;
			return ret;
		}
		
		if(!strcmp(filename0, ".") || !filename0[0]) {
			return handle_leaf(getDirentry(mp->File), 
					   mp, lookupState);
		}

		if(!strcmp(filename0, "..")) {
			return handle_leaf(getParent(getDirentry(mp->File)), mp,
					   lookupState);
		}

		lookupflags = mp->lookupflags;
		
		if(lookupState) {
			lookupState->filename = filename0;
			if(lookupState->nbContainers + lookupState->nbDirs > 0){
				/* we have already one target, don't bother 
				 * with this one. */
				FREE(&lookupState->container);
			} else {
				/* no match yet.  Remember this container for 
				 * later use */
				lookupState->container = COPY(mp->File);
			}
			lookupState->nbContainers++;
		}
	} else
		lookupflags = ACCEPT_DIR | DO_OPEN | NO_DOTS;

	ret = 0;
	r = 0;
	have_one = 0;
	initializeDirentry(&entry, mp->File);
	while(!(ret & STOP_NOW) &&
	      !got_signal &&
	      (r=vfat_lookup(&entry, filename0, length,
			     lookupflags | NO_MSG, 
			     mp->shortname, mp->longname)) == 0 ){
		if(checkForDot(lookupflags, entry.name))
			/* while following the path, ignore the
			 * special entries if they were not
			 * explicitly given */
			continue;
		have_one = 1;
		if(ptr) {
			Stream_t *SubDir;
			SubDir = mp->File = OpenFileByDirentry(&entry);
			ret |= recurs_dos_loop(mp, ptr, filename1, lookupState);
			FREE(&SubDir);
		} else {
			ret |= handle_leaf(&entry, mp, lookupState);
			if(isUniqueTarget(mp->targetName))
				return ret | STOP_NOW;
		}
		if(doing_mcwd)
			break;
	}
	if (r == -2)
		return ERROR_ONE;
	if(got_signal)
		return ret | ERROR_ONE;
	if(doing_mcwd & !have_one)
		return NO_CWD;
	return ret;
}