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; }
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); }
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; } }
/* * 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; }
/* * 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; }