int process_sub(FILE *data_file, FILE *struct_file) { FIND_T fInfo; FIND_RET_T fret; int filesProcessed = 0; if (processSubs) { /* process subs recursively */ size_t sublen = strlen(curSubdir); size_t freelen = sizeof(curSubdir) - sublen - 1; LWIP_ASSERT("sublen < sizeof(curSubdir)", sublen < sizeof(curSubdir)); fret = FINDFIRST_DIR("*", &fInfo); if (FINDFIRST_SUCCEEDED(fret)) { do { const char *curName = FIND_T_FILENAME(fInfo); if ((curName[0] == '.') || (strcmp(curName, "CVS") == 0)) { continue; } if (!FIND_T_IS_DIR(fInfo)) { continue; } if (freelen > 0) { CHDIR(curName); strncat(curSubdir, "/", freelen); strncat(curSubdir, curName, freelen - 1); curSubdir[sizeof(curSubdir) - 1] = 0; printf("processing subdirectory %s/..." NEWLINE, curSubdir); filesProcessed += process_sub(data_file, struct_file); CHDIR(".."); curSubdir[sublen] = 0; } else { printf("WARNING: cannot process sub due to path length restrictions: \"%s/%s\"\n", curSubdir, curName); } } while (FINDNEXT_SUCCEEDED(FINDNEXT(fret, &fInfo))); } } fret = FINDFIRST_FILE("*.*", &fInfo); if (FINDFIRST_SUCCEEDED(fret)) { /* at least one file in directory */ do { if (FIND_T_IS_FILE(fInfo)) { const char *curName = FIND_T_FILENAME(fInfo); printf("processing %s/%s..." NEWLINE, curSubdir, curName); if (process_file(data_file, struct_file, curName) < 0) { printf(NEWLINE "Error... aborting" NEWLINE); return -1; } filesProcessed++; } } while (FINDNEXT_SUCCEEDED(FINDNEXT(fret, &fInfo))); } return filesProcessed; }
int process_sub(FILE *data_file, FILE *struct_file) { FIND_T fInfo; FIND_RET_T fret; int filesProcessed = 0; char oldSubdir[MAX_PATH_LEN]; if (processSubs) { /* process subs recursively */ strcpy(oldSubdir, curSubdir); fret = FINDFIRST_DIR("*", &fInfo); if (FINDFIRST_SUCCEEDED(fret)) { do { const char *curName = FIND_T_FILENAME(fInfo); if (curName == NULL) continue; if (curName[0] == '.') continue; if (strcmp(curName, "CVS") == 0) continue; if (!FIND_T_IS_DIR(fInfo)) continue; CHDIR(curName); strcat(curSubdir, "/"); strcat(curSubdir, curName); printf(NEWLINE "processing subdirectory %s/..." NEWLINE, curSubdir); filesProcessed += process_sub(data_file, struct_file); CHDIR(".."); strcpy(curSubdir, oldSubdir); } while (FINDNEXT_SUCCEEDED(FINDNEXT(fret, &fInfo))); } } fret = FINDFIRST_FILE("*.*", &fInfo); if (FINDFIRST_SUCCEEDED(fret)) { /* at least one file in directory */ do { if (FIND_T_IS_FILE(fInfo)) { const char *curName = FIND_T_FILENAME(fInfo); printf("processing %s/%s..." NEWLINE, curSubdir, curName); if (process_file(data_file, struct_file, curName) < 0) { printf(NEWLINE "Error... aborting" NEWLINE); return -1; } filesProcessed++; } } while (FINDNEXT_SUCCEEDED(FINDNEXT(fret, &fInfo))); } return filesProcessed; }
void complete_filename(char *str, unsigned charcount) { /* variables found within code */ struct ffblk file; #undef ffblk int found_dot = 0; int curplace = 0; int start; int count; int perfectmatch = 1; int makelower; char path[128]; char fname[14]; char maxmatch[13] = ""; char directory[128]; assert(str); /* expand current file name */ count = charcount - 1; if (count < 0) makelower = count = 0; else { /* if last character is lower case, then make lookup lower case. */ makelower = islower(str[count]); } while (count > 0 && str[count] != ' ') /* find front of word */ count--; if (str[count] == ' ') /* if not at beginning, go forward 1 */ count++; start = count; /* extract directory from word */ strcpy(directory, &str[start]); curplace = strlen(directory) - 1; while (curplace >= 0 && directory[curplace] != '\\' && directory[curplace] != ':') { directory[curplace] = 0; curplace--; } strcpy(path, &str[start]); /* look for a . in the filename */ for (count = strlen(directory); path[count] != 0; count++) if (path[count] == '.') { found_dot = 1; break; } if (found_dot) strcat(path, "*"); else strcat(path, "*.*"); curplace = 0; /* current fname */ #ifdef FEATURE_LONG_FILENAMES if( lfncomplete ? lfnfindfirst( path, &file, FILE_SEARCH_MODE ) == 0 : findfirst( path, ( struct ffblk * )&file, FILE_SEARCH_MODE ) == 0 ) #else if (FINDFIRST(path, &file, FILE_SEARCH_MODE) == 0) #endif { /* find anything */ do { if (file.ff_name[0] == '.' && (!file.ff_name[1] || (file.ff_name[1] == '.' && !file.ff_name[2]))) /* ignore . and .. */ continue; strcpy(fname, file.ff_name); if (makelower) strlwr(fname); if (file.ff_attrib == FA_DIREC) strcat(fname, "\\"); else strcat(fname, " "); if (!maxmatch[0] && perfectmatch) strcpy(maxmatch, fname); else { for (count = 0; maxmatch[count] && fname[count]; count++) if (maxmatch[count] != fname[count]) { perfectmatch = 0; maxmatch[count] = 0; break; } } } #ifdef FEATURE_LONG_FILENAMES while( lfncomplete ? lfnfindnext( &file ) == 0 : findnext( ( struct ffblk * )&file ) == 0 ); #else while (FINDNEXT(&file) == 0); #endif FINDSTOP(&file); strcpy(&str[start], directory); strcat(&str[start], maxmatch); if (!perfectmatch) beep(); } else /* no match found */ beep(); }
char *readbatchline(int *eflag, char *textline, int size) { /* * Read and return the next executable line from the current batch file * * If no batch file is current or no further executable lines are found * return NULL. * * Here we also look out for FOR bcontext structures which trigger the * FOR expansion code. * * Set eflag to 0 if line is not to be echoed else 1 */ char *first; char *ip; if (bc == 0) /* No batch */ return 0; dprintf(("readbatchline ()\n")); assert(textline); assert(size > 1); assert(eflag); ip = ""; /* make sure ip != NULL in the first iteration of the loop */ while (bc) { first = 0; /* by default return "no file" */ if (bc->forvar) /* If its a FOR context... */ { int forvarlen; char *fv1, *sp, /* pointer to prototype command */ *dp, /* Place to expand protoype */ *fv; /* Next list element */ if (chkCBreak(BREAK_FORCMD) || bc->shiftlevel > bc->numParams) /* End of list or User break so... */ { exit_batch(); /* just exit this context */ continue; } fv1 = fv = getArgCur(0); if (bc->ffind) { /* First already done fo do next */ if(FINDNEXT(bc->ffind) != 0) { /* no next file */ free(bc->ffind); /* free the buffer */ bc->ffind = 0; bc->shiftlevel++; /* On to next list element */ continue; } fv = bc->ffind->ff_name; } else { if (strpbrk(fv, "?*") == 0) { /* element is not wild file */ bc->shiftlevel++; /* No -> use it and shift list */ fv1 = ""; /* No additional info */ } else /* Wild file spec, find first (or next) file name */ { /* For first find, allocate a find first block */ if ((bc->ffind = (struct ffblk *)malloc(sizeof(struct ffblk))) == 0) { error_out_of_memory(); exit_batch(); /* kill this FOR context */ break; } if(FINDFIRST(fv, bc->ffind, FA_NORMAL) == 0) { /* found a file */ *dfnfilename(fv) = '\0'; /* extract path */ fv = bc->ffind->ff_name; } else { /* if not found use the string itself */ #if 0 /* To use the pattern is not compatible with MS COMMAND */ ++bc->shiftlevel; fv1 = ""; /* No additional info */ #else free(bc->ffind); /* free the buffer */ bc->ffind = 0; bc->shiftlevel++; /* On to next list element */ continue; #endif } } } /* At this point, fv points to parameter string */ /* fv1 is the string usually set to the path to the found file, otherwise it points to "" */ sp = bc->forproto; /* pointer to prototype command */ dp = textline; /* Place to expand protoype */ assert(sp); assert(bc->forvar); forvarlen = strlen(bc->forvar); while (*sp) { if (memcmp(sp, bc->forvar, forvarlen) == 0) dp = stpcpy(stpcpy(dp, fv1), fv), sp += forvarlen; else *dp++ = *sp++; /* Else just copy */ } *dp = '\0'; assert(dp - textline <= size); *eflag = echo; first = textline; break; } if (!bc->bfile) { /* modifyable batchfiles */ if ((bc->bfile = fopen(bc->bfnam, "rt")) == 0) { error_bfile_vanished(bc->bfnam); exit_batch(); continue; } bc->bclose = 1; if (bc->brewind) { bc->brewind = 0; /* fopen() position at start of file */ bc->blinecnt = 0; } else if (fsetpos(bc->bfile, &bc->bpos)) { /* end of file reached */ /* so says MS COMMAND */ exit_batch(); continue; } } else if(bc->brewind) { rewind(bc->bfile); bc->brewind = 0; bc->blinecnt = 0; } assert(ip != 0); ++bc->blinecnt; if (chkCBreak(BREAK_BATCHFILE) /* User break */ || fgets(textline, size, bc->bfile) == 0 /* End of file.... */ || (ip = textlineEnd(textline, size)) == 0) /* line too long */ { if (!ip) error_long_batchline(bc->bfnam, bc->blinecnt); exit_batch(); continue; } /* Strip leading spaces and trailing space/control chars */ rtrimsp(textline); first = ltrimcl(textline); assert(first); /* ignore empty lines */ if (!*first) continue; if (*first == ':') { /* if a label is searched for test if we reached it */ if(bc->blabel) { /* label: the 1st word immediately following the colon ':' */ for(ip = ++first; isgraph(*ip); ++ip) ; *ip = '\0'; if (stricmp(first, bc->blabel) == 0) { /* OK found */ free(bc->blabel); bc->blabel = 0; } } continue; /* ignore label */ } if (bc->blabel) continue; /* we search for a label! */ if (*first == '@') /* don't echo this line */ { first = ltrimcl(first + 1); *eflag = 0; } else *eflag = echo; break; } if (bc && bc->bclose) { /* modifyable batchfiles - ska */ fgetpos(bc->bfile, &bc->bpos); fclose(bc->bfile); bc->bfile = 0; bc->bclose = 0; } return first; }
int cmd_del(char *rest) { int ec = E_None; /* exit code */ int i; unsigned count = 0; struct ffblk f; /* Make fullname somewhat larger to ensure that appending a matched name, one backslash and one hope. */ char fullname[MAXPATH + sizeof(f.ff_name) + 2], *p, *q; int len; char **arg; int argc, optc; /* initialize options */ optP = 0; if((arg = scanCmdline(rest, opt_del, 0, &argc, &optc)) == 0) return E_Other; if(!argc) { error_req_param_missing(); ec = E_Useage; } else { i = 0; do { assert(arg[i]); /* Get the pattern fully-qualified */ /* Note: An absolute path always contains: A:\\ --> It's always three bytes long at minimum and always contains a backslash */ p = dfnexpand(arg[i], 0); assert(strlen(p) >= 3); if ((len = strlen(p)) >= MAXPATH) { error_filename_too_long(p); free(p); ec = E_Other; goto errRet; } strcpy(fullname, p); /* Operating over a local buffer simplifies the process; rather than keep the pattern within dynamic memory */ free(p); p = fullname + len; /* check if it is a directory */ if(dfnstat(fullname) & DFN_DIRECTORY) { if (p[-1] != '\\') *p++ = '\\'; } if (p[-1] == '\\') /* delete a whole directory */ p = stpcpy(p, "*.*"); /* p := address to copy the filename to to form the fully-qualified filename */ /* There is at least one backslash within fullname, because of dfnexpand() */ while (*--p != '\\') ; ++p; /* make sure user is sure if all files are to be * deleted */ if (!optP && *p == '*' && ((q = strchr(p, '.')) == 0 || q[1] == '*')) { displayString(TEXT_MSG_DELETE_ALL); if (vcgetcstr("YN\n\r") != 'Y') { ec = E_Other; goto errRet; } } if (FINDFIRST(fullname, &f, FA_ARCH)) { error_sfile_not_found(fullname); } else do { strcpy(p, f.ff_name); /* Make the full path */ if (optP) { printf("%s, Delete(Y/N)?", fullname); switch (vcgetcstr("YN\n\r")) { case '\3': /* ^Break pressed */ ec = E_CBreak; goto errRet; case 'Y': break; /* yes, delete */ default: continue; /* no, don't delete */ } } else if (cbreak) { /* is also probed for in vcgetstr() */ ec = E_CBreak; goto errRet; } #ifdef NODEL /* define NODEL if you want to debug */ puts(fullname); #else if (unlink(fullname) != 0) { perror(fullname); /* notify the user */ } else ++count; #endif } while (FINDNEXT(&f) == 0); } while(++i < argc); } errRet: if(echo) { dispCount(count, "no file", "one file", "%u files"); puts(" removed."); } freep(arg); return ec; }
int copy(char *dst, char *pattern, struct CopySource *src , int openMode) { char mode[3], *p; struct ffblk ff; struct CopySource *h; char *rDest, *rSrc; FILE *fin, *fout; int rc, asc; char *buf; size_t len; assert(dst); assert(pattern); assert(src); if(FINDFIRST(pattern, &ff, FA_RDONLY | FA_ARCH) != 0) { error_sfile_not_found(pattern); return 0; } mode[2] = '\0'; do { if((rDest = fillFnam(dst, ff.ff_name)) == 0) return 0; h = src; do { /* to prevent to open a source file for writing, e.g. for COPY *.c *.? */ if((rSrc = fillFnam(h->fnam, ff.ff_name)) == 0) { free(rDest); return 0; } rc = samefile(rDest, rSrc); free(rSrc); if(rc < 0) { error_out_of_memory(); free(rDest); return 0; } else if(rc) { error_selfcopy(rDest); free(rDest); return 0; } } while((h = h->app) != 0); if(interactive_command /* Suppress prompt if in batch file */ && openMode != 'a' && !optY && (fout = fopen(rDest, "rb")) != 0) { int destIsDevice = isadev(fileno(fout)); fclose(fout); if(!destIsDevice) { /* Devices do always exist */ switch(userprompt(PROMPT_OVERWRITE_FILE, rDest)) { default: /* Error */ case 4: /* Quit */ free(rDest); return 0; case 3: /* All */ optY = 1; case 1: /* Yes */ break; case 2: /* No */ free(rDest); continue; } } } if(cbreak) { free(rDest); return 0; } mode[0] = openMode; mode[1] = 'b'; if((fout = fdevopen(rDest, mode)) == 0) { error_open_file(rDest); free(rDest); return 0; } mode[0] = 'r'; h = src; do { if((rSrc = fillFnam(h->fnam, ff.ff_name)) == 0) { fclose(fout); free(rDest); return 0; } mode[1] = (asc = h->flags & ASCII) != 0? 't': 'b'; reOpenIn: if((fin = fdevopen(rSrc, mode)) == 0) { error_open_file(rSrc); fclose(fout); free(rSrc); free(rDest); return 0; } if(isadev(fileno(fin)) && mode[1] != 't' && (h->flags & BINARY) == 0) { /* character devices are opened in textmode by default */ fclose(fin); mode[1] = 't'; goto reOpenIn; } dispCopy(rSrc, rDest, openMode == 'a' || h != src); if(cbreak) { fclose(fin); fclose(fout); free(rSrc); free(rDest); return 0; } /* Now copy the file */ rc = 1; if(mode[1] != 't') { /* binary file */ if(Fcopy(fout, fin) != 0) { if(ferror(fin)) { error_read_file(rSrc); } else if(ferror(fout)) { error_write_file(rDest); } else error_copy(); rc = 0; } } else { /* text file, manually transform '\n' */ if(Fmaxbuf((byte**)&buf, &len) == 0) { if(len > INT_MAX) len = INT_MAX; while(fgets(buf, len, fin)) { p = strchr(buf, '\0'); if(*--p == '\n') { *p = '\0'; fputs(buf, fout); putc('\r', fout); putc('\n', fout); } else fputs(buf, fout); } free(buf); } else { error_out_of_memory(); rc = 0; } } if(rc) if(ferror(fin)) { error_read_file(rSrc); rc = 0; } else if(ferror(fout)) { error_write_file(rDest); rc = 0; } if(cbreak) rc = 0; fclose(fin); free(rSrc); if(!rc) { fclose(fout); free(rDest); return 0; } } while((h = h->app) != 0); if(asc) { /* append the ^Z as we copied in ASCII mode */ putc(0x1a, fout); } rc = ferror(fout); fclose(fout); if(rc) { error_write_file(rDest); free(rDest); return 0; } free(rDest); } while(FINDNEXT(&ff) == 0); return 1; }
void complete_filename(char *str, unsigned charcount) { // variables found within code struct ffblk file; int found_dot = 0; int curplace = 0; int start; int count; int perfectmatch = 1; int makelower; char path[128]; char fname[14]; char maxmatch[13] = ""; char directory[128]; assert(str); // expand current file name count = charcount - 1; if (count < 0) makelower = count = 0; else { // if last character is lower case, then make lookup lower case. makelower = islower(str[count]); } while (count > 0 && str[count] != ' ') // find front of word count--; if (str[count] == ' ') // if not at beginning, go forward 1 count++; start = count; // extract directory from word strcpy(directory, &str[start]); curplace = strlen(directory) - 1; while (curplace >= 0 && directory[curplace] != '\\' && directory[curplace] != ':') { directory[curplace] = 0; curplace--; } strcpy(path, &str[start]); // look for a . in the filename for (count = strlen(directory); path[count] != 0; count++) if (path[count] == '.') { found_dot = 1; break; } if (found_dot) strcat(path, "*"); else strcat(path, "*.*"); curplace = 0; // current fname if (FINDFIRST(path, &file, FILE_SEARCH_MODE) == 0) { // find anything do { if (file.ff_name[0] == '.') // ignore . and .. continue; strcpy(fname, file.ff_name); if (makelower) strlwr(fname); if (file.ff_attrib == FA_DIREC) strcat(fname, "\\"); else strcat(fname, " "); if (!maxmatch[0] && perfectmatch) strcpy(maxmatch, fname); else { for (count = 0; maxmatch[count] && fname[count]; count++) if (maxmatch[count] != fname[count]) { perfectmatch = 0; maxmatch[count] = 0; break; } } } while (FINDNEXT(&file) == 0); strcpy(&str[start], directory); strcat(&str[start], maxmatch); if (!perfectmatch) beep(); } else /* no match found */ beep(); }
/* * dir_list * * list the files in the directory */ int dir_list(int pathlen , char *pattern , unsigned long *dcnt , unsigned long *fcnt , unsigned long *bcnt ) { struct ffblk file; unsigned long bytecount = 0; unsigned long filecount = 0; unsigned long dircount = 0; int time; int count; unsigned mode = FA_RDONLY | FA_ARCH | FA_DIREC; int rv = E_None; assert(path); assert(pattern); assert(pathlen >= 2); /* at least root */ /* if the user wants all files listed */ if (optA) mode |= FA_HIDDEN | FA_SYSTEM; /* Search for matching entries */ path[pathlen - 1] = '\\'; strcpy(&path[pathlen], pattern); if (FINDFIRST(path, &file, mode) == 0) { /* moved down here because if we are recursively searching and * don't find any files, we don't want just to print * Directory of C:\SOMEDIR * with nothing else */ if (!optB) { rv = flush_nl(); if(rv == E_None) { /* path without superflous '\' at its end */ if(pathlen == 3) /* root directory */ path[pathlen] = '\0'; /* path := path w/o filename */ else path[pathlen - 1] = '\0'; /* /// Changed to exactly match DOS's formatting. - Ron Cemer */ printf("%sDirectory of %s\n", (optS ? "" : " "), path); if((rv = incline()) == E_None) { putchar('\n'); rv = incline(); } } } /* For counting columns of output */ count = WIDE_COLUMNS; /* if optB && optS the path with trailing backslash is needed, also for optS below do {} while */ strcpy(&path[pathlen - 1], "\\"); if(rv == E_None) do { assert(strlen(file.ff_name) < 13); if (cbreak) rv = E_CBreak; else { if (optL) strlwr(file.ff_name); if (optW) { char buffer[sizeof(file.ff_name) + 3]; if (file.ff_attrib & FA_DIREC) { sprintf(buffer, "[%s]", file.ff_name); dircount++; } else { strcpy(buffer, file.ff_name); filecount++; bytecount += file.ff_fsize; } printf("%-15s", buffer); if (!--count) { /* outputted 5 columns */ putchar('\n'); rv = incline(); count = WIDE_COLUMNS; } } else if (optB) { if (strcmp(file.ff_name, ".") == 0 || strcmp(file.ff_name, "..") == 0) continue; if (optS) fputs(path, stdout); printf("%-13s\n", file.ff_name); if (file.ff_attrib & FA_DIREC) dircount++; else { filecount++; bytecount += file.ff_fsize; } rv = incline(); } else { char buffer[sizeof(long) * 4 + 2], *ext; if (file.ff_name[0] == '.') printf("%-13s", file.ff_name); else { ext = strrchr(file.ff_name, '.'); if (!ext) ext = ""; else *ext++ = '\0'; printf("%-8s %-3s ", file.ff_name, ext); } if (file.ff_attrib & FA_DIREC) { printf("%-14s", " <DIR>"); dircount++; } else { convert(file.ff_fsize, buffer); printf(" %10s ", buffer); bytecount += file.ff_fsize; filecount++; } printf(" %.2d-%.2d-%02d", ((file.ff_fdate >> 5) & 0x000f), (file.ff_fdate & 0x001f), ((file.ff_fdate >> 9) + 80) % 100); time = file.ff_ftime >> 5 >> 6; printf(" %2d:%.2u%c\n", (time == 0 ? 12 : (time <= 12 ? time : time - 12)), ((file.ff_ftime >> 5) & 0x003f), (time <= 11 ? 'a' : 'p')); rv = incline(); } } } while (rv == E_None && FINDNEXT(&file) == 0); } if (rv == E_None && optW && (count != 0)) { putchar('\n'); rv = incline(); } if (rv == E_None) if(filecount || dircount) { /* The code that was here is now in print_summary */ rv = print_summary(filecount, bytecount); } else if(!optS) { error_file_not_found(); rv = E_Other; } if(rv == E_None /* no error */ && optS) { /* do recursively */ /* already set for optB && optS before do {} while above path[pathlen - 1] = '\\'; */ strcpy(&path[pathlen], "*.*"); if (FINDFIRST(path, &file, mode) == 0) do { if((file.ff_attrib & FA_DIREC) != 0 /* is directory */ && strcmp(file.ff_name, ".") != 0 /* not cur dir */ && strcmp(file.ff_name, "..") != 0) { /* not parent dir */ if (optL) strlwr(file.ff_name); strcpy(&path[pathlen], file.ff_name); rv = dir_list(pathlen + strlen(file.ff_name) + 1, pattern , &dircount, &filecount, &bytecount ); } } while (rv == E_None && FINDNEXT(&file) == 0); } *dcnt += dircount; *fcnt += filecount; *bcnt += bytecount; return rv; }