recursive file search, C , linux hi guys this script recursively searches for files with a certain extension and possibly in a directory passed by the terminal ....(In case no directory has been passed, search from the current one) I believe it works correctly but I wanted to ask you if you noticed any flaws and report them to me or just tell me that everything is ok ...thanksss

 #include&lt;stdio.h&gt;
 #include&lt;sys/stat.h&gt;
 #include&lt;errno.h&gt;
 #include&lt;stdlib.h&gt; 
 #include&lt;dirent.h&gt;    
 #include&lt;stdarg.h&gt;
 #include&lt;limits.h&gt;
 #include&lt;string.h&gt;
 #include&lt;time.h&gt;



 char * scrivi(const char * a, char * B) {

 char *targetdir = malloc(2048);
 strcpy(targetdir,a);
 strcat(targetdir,"/");
 strcat(targetdir,B);
 return targetdir;
 } 



 void ricor1(const char estensione[],const char nomedirectory[]){

 struct stat attr;
 char dbuf[PATH_MAX+1];
 DIR * fh ;
 struct dirent *fdata;
 struct stat buf;

 if((fh=opendir(nomedirectory))==NULL){
 perror("ERRORE 1");
 exit(errno);
 }


 while((fdata = readdir (fh))!=NULL){
 if(strcmp(fdata-&gt;d_name,".")==0){
 continue;
 }

 if(strcmp(fdata-&gt;d_name,"..")==0){
 continue;
  }


 char *percorso;
 percorso = scrivi(nomedirectory,fdata-&gt;d_name);
 if (fdata-&gt;d_type==DT_DIR){

 ricor1(estensione,percorso);
  }
 if (fdata-&gt;d_type == DT_REG &amp;&amp; strstr(fdata-&gt;d_name, estensione)) {

realpath(percorso, dbuf);
printf("[%s]", dbuf);

stat(percorso, &amp;attr);

printf("%s\n", ctime(&amp;attr.st_mtime));

 }

free(percorso);
 }
closedir(fh);
 } 


int main(int argc, char *argv[]) {



if(argc==3){

printf("Checking existence directory.. \n");

DIR* dir=opendir(argv[2]);

if(dir){    
closedir(dir);        
ricor1(argv[1],argv[2]);

 } 

else if (ENOENT==errno){

printf("Directory doesn't exist\n");
  }

else{

printf("error"); 

     }   
 }


else if(argc==2){



ricor1(argv[1],"./");

  }
 }
... if you noticed any flaws ....


Problems with scrivi()

char * scrivi(const char * a, char * B) {

 char *targetdir = malloc(2048);
 strcpy(targetdir,a);
 strcat(targetdir,"/");
 strcat(targetdir,B);
 return targetdir;
 } 


Magic number

Why 2048?  Big enough - who knows?  Makes more sense to find the size needed and allocate rather than risk undefined behavior of a buffer overflow with strcpy(targetdir,a);

strcpy(), strcat(), strcat()

Walking down the string 3 times.  Bad enough to do twice.   (With a larger code re-write, we could avoid all repetitive walks down a, that is far below.)

char * B better as const char * b

Use const.

No error checking

With a recursion function, out-of-memory is a concern.

Alternative

char * scrivi(const char *a, const char *b) {
  size_t a_len = strlen(a);    
  size_t b_len = strlen(b);    
  char *targetdir = malloc(a_len + 1 + b_len + 1);

  if (targetdir) {
    memcpy(targetdir, a, a_len);
    targetdir[a_len] = '/';
    memcpy(targetdir + a_len + 1, b, b_len + 1);
  }
  return targetdir;
} 




Re-write trick

Rather than repetitive malloc()/free(), allocate once ever for a working file path buffer.

size_t file_path_size = PATH_MAX * 2;  // Let us be generous.
char file_path = mallloc(file_path_size); 


Before code calls ricor1() the first time, fill in the directory path and pass how much used, how much total.

strcpy(file_path, argv[2]);
ricor1(argv[1], file_path, strlen(argv[2]), file_path_size);


When forming the the full path, rather than percorso = scrivi(nomedirectory, fdata-&gt;d_name); with its allocations, write at the right place.

int length = snprintf(file_path + used, file_path_size - used, "/%s", fdata-&gt;d_name);


When recursing, append the sub-directory name and re-curse with an updated length

ricor1(estensione, file_path, used + length, file_path_size);


Include ample size error checking.

Consider code only ever needs   1 file_path[] at a time.