SIGSEGV bei etwas größerem Projekt



  • Hallo Leute!

    Bin recht neu in C und habe ein paar Problemchen bei einem Tool, das ich mir für die Firma schreibe um mir das Leben etwas leichter zu machen.
    Das folgende Programm soll unter Suse 8.0 als Cron-Job laufen und nachts über ein paar "Transportverzeichnisse" hüpfen und mir Datenfiles ausgeben, die ich dann mit einem anderen Tool auswerte. Das Tool ist fast fertig, wer will kann es soweit verwenden.

    Nur leider hauts das Programm immer irgendwo raus.
    Meistens schlägt bei der Stelle mit dem Kommentar "PROBLEMATISCH" der Malloc fehl. Hat jemand ne Idee oder sieht nen großen Patzer?
    Vielen Dank schonmal für die Mühe, wenigstens bis hierhin zu lesen 😉

    Viele Grüße
    xodi

    #include <stdlib.h>
    #include <stdio.h>
    #include <time.h>
    #include <string.h>
    #include <sys/stat.h>
    #include <dirent.h>
    #include <limits.h>
    #include <sys/file.h>
    #include <ctype.h>
    #include <unistd.h>
    #include <pwd.h>
    #include <grp.h>
    
    // Constants and macros
    #define LINESIZE 300
    #define scopy(x)	strcpy(malloc(strlen(x)+1),(x))
    enum {FALSE=0, TRUE};
    
    // Commonly used structures
    struct _info {
      char *name, *lnk;
      u_char isdir  : 1;
      u_short mode;
      u_long size;
      time_t time;
    };
    
    // Small file-list to remember big files, old files and levels of dirs
    struct smlfilelist {
      char *filename, *date, *path;
      float size;
      int count;
      struct smlfilelist *previous, *next;
    };
    
    // Remember all transportdirectories from config
    struct trans {
      char *transdir, *transname;
      struct trans *next, *previous;
    };
    
    // Struc for all entries from configfile
    struct config {
      char *section, *key, *value;
      struct config *next, *previous;
    };
    
    // Prototypes
    float procdir(char *directory, char *tname, int *filestotal, u_long level);
    FILE *openfile(char *path_and_filename, char *mode);
    struct _info **read_dir(char *dir, int *n);
    char *getvalue(char *section, char *key), *getmywd(void);
    char *do_date(time_t t, char fmt);
    int getnexttransdir(char *dirret, char *transret), fetchvalues(struct trans *tbegin, struct config *cbegin, int argc, char **argv);
    void openerrfile(void), free_dir(struct _info **d), make_directories(void), insertbig(float size, char *date, char *path, char *filename);
    void insertlevel(float size, char *path, int count), insertold(float size, char *date, char *path, char *filename), printbig(char * tname, char *tdir);
    void printold(char * tname, char *tdir), printlevel(char * tname, char *tdir), printillegal(char * tname, char *tdir);
    void insertconfig(char *section, char *key, char *value), inserttrans(char *transname, char *transdir);
    void checklegal(char *tname, char *dname);
    void *xmalloc (size_t size);
    void *xrealloc (void *ptr, size_t size);
    
    // Global variables:
    int		dirs[4096];
    char	*ddi, *ddo, *ddb, *ddl, *curdir;
    float	totalleveltransdir;
    struct	smlfilelist *bbegin = NULL, *bend = NULL, *obegin = NULL, *oend = NULL, *lbegin = NULL, *lend = NULL, *ibegin = NULL, *iend = NULL;
    struct	config *cbegin = NULL, *cend = NULL;
    struct	trans *tbegin = NULL, *tend = NULL;
    
    int main(int argc, char **argv)
    {
    	int ftotal;
    	char *transdir, *transname;
    
    	// Initialize variables
    	transdir = malloc (200);
    	transname = malloc (80);
    
    	curdir = getmywd();					// Save current working directory
    	if(fetchvalues(tbegin, cbegin, argc, argv))		// Fetch transportdirectories from configfile
    	{
    		fprintf(stderr,"%s: [error opening configfile]\n",do_date(time((time_t *)NULL), TRUE));
    		exit(6);					// No configfile found
    	}
    	openerrfile();						// put stderr into the file defined in config
    	make_directories();					// Check / create Data-Directory structure
    
    	fprintf(stdout,"Begin: %s\n",do_date(time((time_t *)NULL), TRUE));	// Just to see how long it lasts
    
    	while(getnexttransdir(transdir, transname) == 1)	// Main loop that processes all transport directories given
    	{
    		totalleveltransdir = 0;
    		ftotal = 0;
    
    		if (chdir(transdir))		// then Error : wrong directory given in configfile or insufficient permissions
    		{
    			fprintf(stderr,"%s: [error opening dir: %s]\n",do_date(time((time_t *)NULL), TRUE), transdir);
    		}
    		else
    		{
    			// Fill internal structures with big files, old files and level of directories
    			procdir(transdir,transname,&ftotal,0);
    			// Put everything into internal structures
    			printbig(transname, transdir);
    			printold(transname, transdir);
    			printlevel(transname, transdir);
    			printillegal(transname, transdir);
    		}
    	}
    
    	chdir(curdir);	// Return to own directory
    	fclose(stderr);
    	fprintf(stdout,"End: %s\n",do_date(time((time_t *)NULL), TRUE));	// Huh, we are done.
    	return 0;
    }
    
    // This is the most important function of this program. It walks through all directories recursively and remembers all wanted files
    float procdir(char *directory, char *tname, int *filestotal, u_long level)
    {
      float thisdirsize = 0;
      struct _info **dir, **sav;
      struct stat sb;
      int n, thisdircount = *filestotal;
      char *path;
      path = malloc(1024);
      sav = dir = read_dir(directory,&n);
      if (!dir && n)
        return 0;
      if (!n)			// Then we found an empty directory
      {
    	insertlevel((float)(thisdirsize)/1048576, directory, *filestotal-thisdircount);
    	return 0;
      }
      dirs[level] = 1;
      if (!*(dir+1)) dirs[level] = 2;
    
      while(*dir)
      {
    	  if(!((*dir)->isdir || (*dir)->lnk))		// Add it to our sum-variables if it's a file
    	  {
    			totalleveltransdir += (float)(*dir)->size;
    			thisdirsize += (float)(*dir)->size;
    	  }
    	  if(strlen(directory) > 1023) path = realloc(path, strlen(directory)+1);
    	  sprintf(path,"%s",directory);
    
    	  if(((((float)(*dir)->size)/1048576) > (float)atoi(getvalue(tname, "bigsize")))
    	     && (!(*dir)->isdir) && (!(*dir)->lnk))		// Is it big? -> Remember it
    		  insertbig(((float)((*dir)->size)/1048576), do_date((*dir)->time, TRUE),directory, (*dir)->name);
    
    	  if((time((time_t *)NULL) - (atoi(getvalue(tname, "olddate"))*24*3600)) > (*dir)->time
    	     && (!(*dir)->isdir) && (!(*dir)->lnk))		// Is it old? -> Remember it
    		  insertold(((float)((*dir)->size)/1048576), do_date((*dir)->time, TRUE),directory, (*dir)->name);
    
          if ((*dir)->isdir)
    	  {
    		if (!(*dir)->lnk) 
    		  {
    			if((strlen(directory)+strlen((*dir)->name))  > 1022)
    				path = realloc(path, strlen(directory)+strlen((*dir)->name) + 2);
    			sprintf(path,"%s/%s",directory,(*dir)->name);
    			thisdirsize += procdir(path,tname,filestotal,level+1);
    		  }
          }
    	  else
    		  *filestotal += 1;
          dir++;
          if (!*(dir+1)) dirs[level] = 2;
      }
      // Remember the level of the directory
      insertlevel((float)(thisdirsize)/1048576, directory, *filestotal-thisdircount);
      dirs[level] = 0;
      free_dir(sav);
      free(path);
      return thisdirsize;
    }
    
    // This one turns stderr up to a file
    void openerrfile(void)
    {
    
        freopen(getvalue("global","errorlog"),"a", stderr);  //Append-Modus
        if (stderr == NULL)
    	{
    		fprintf(stdout,"invalid filename '%s'\n",getvalue("global","errorlog"));
    		exit(3);		// Error opening errorfile
    	}
    	return;
    }
    
    // This structure gets filled with all information about the directory given as parameter
    struct _info **read_dir(char *dir, int *n)
    {
      static char *path = NULL, *lbuf = NULL;
      static long pathsize = PATH_MAX+1, lbufsize = PATH_MAX+1;
      struct _info **dl;
      struct dirent *ent;
      struct stat lst,st;
      DIR *d;
      int ne, p = 0, len, rs;
    
      if (path == NULL) {
        path=malloc(pathsize);
        lbuf=malloc(lbufsize);
      }
    
      *n = 1;
      if ((d=opendir(dir)) == NULL) return NULL;
    
      dl = (struct _info **)malloc(sizeof(struct _info *) * (ne = 1000));
    
      while((ent = (struct dirent *)readdir(d))) {
        if (!strcmp("..",ent->d_name) || !strcmp(".",ent->d_name)) continue;
    
        if (strlen(dir)+strlen(ent->d_name)+2 > pathsize) path = realloc(path,pathsize=(strlen(dir)+strlen(ent->d_name)+4096));
        sprintf(path,"%s/%s",dir,ent->d_name);
        if (lstat(path,&lst) < 0) continue;
        if ((rs = stat(path,&st)) < 0) st.st_mode = 0;
    
        if (p == (ne-1))
    	{
    		dl = (struct _info **) xrealloc(dl,sizeof(struct _info) * (ne += 500));
    	}
    	// PROBLEMATISCH
        dl[p] = (struct _info *) malloc(sizeof(struct _info));
    
        dl[p]->name = scopy(ent->d_name);
        dl[p]->mode = lst.st_mode;
        dl[p]->size = lst.st_size;
        dl[p]->lnk = NULL;
    
        dl[p]->time = lst.st_mtime;
    
        if ((lst.st_mode & S_IFMT) == S_IFLNK) {
          if (lst.st_size+1 > lbufsize) lbuf = xrealloc(lbuf,lbufsize=(lst.st_size+8192));
          if ((len=readlink(path,lbuf,lbufsize-1)) < 0) {
    	dl[p]->lnk = scopy("[Error reading symbolic link information]");
    	dl[p++]->isdir = FALSE;
    	continue;
          } else {
    	lbuf[len] = 0;
    	dl[p]->lnk = scopy(lbuf);
          }
        }
    
        dl[p++]->isdir = ((st.st_mode & S_IFMT) == S_IFDIR);
      }
      closedir(d);
      *n = p;
      dl[p] = NULL;
      return dl;
    }
    
    // This one simply opens a file, but does it with error-handling
    FILE *openfile(char *path_and_filename, char *mode)
    {
    	FILE *filepointer;
    
        filepointer = fopen(path_and_filename,mode);
        if (filepointer == NULL)
    	{
    		fprintf(stderr,"%s: [Error opening file '%s' for %s]\n",
    			do_date(time((time_t *)NULL), TRUE), path_and_filename, mode);
    		exit(2);		// Error opening data- or configfile
    	}
    	return filepointer;
    }
    
    // Fetches a wanted configfilevalue from internal structure
    char *getvalue(char *section, char *key)
    {
    	char *buffer;
    	struct config *p = cbegin;
    	buffer = malloc(LINESIZE);
    	while(p)
    	{
    		if(strcmp(section, p->section) == 0 && strcmp(key, p->key) == 0)
    		{
    			return p->value;
    		}
    		p = p->next;
    	}
    	if (strcmp(section, "global") == 0) return "";
    	else return getvalue("global", key);
    }
    
    // Returns the own working directory, dynamically allocates the memory for buffer (hopefully)
    char *getmywd(void)
    {
      int size = 50;
      char *buffer;
      buffer = malloc (size);
    
      while (1)
        {
          char *value = getcwd (buffer, size);
          if (value != 0)
    	return buffer;
          size *= 2;
          free (buffer);
          buffer = (char *) malloc (size);
        }
    }
    
    // Cleans up the structure holding the directory information
    void free_dir(struct _info **d)
    {
      int i;
    
      for(i=0;d[i];i++) {
        free(d[i]->name);
        if (d[i]->lnk) free(d[i]->lnk);
        free(d[i]);
      }
      free(d);
    }
    
    // Returns the timestamp of a given time_t in a human-readable format.
    // YYYY-MM-DD, HH:MM:SS (ISO-Format) when fmt == TRUE, else YYYYMMDD
    char *do_date(time_t t, char fmt)
    {
      struct tm *filedate;
      static char buf[20];
    
      filedate = localtime(&t);
      if(fmt == TRUE)
    	strftime(buf,20,"%Y-%m-%d %H:%M:%S",filedate);
      else
    	strftime(buf,20,"%Y%m%d",filedate);
    
      return buf;
    }
    
    // changes the parameter dirret and transret with
    // the next name and directory of next transportdir
    int getnexttransdir(char *dirret, char *transret)
    {
    struct trans *t = tbegin;
    	if(tbegin)
    	{
    		strcpy(transret, tbegin->transname);
    		strcpy(dirret, tbegin->transdir);
    		free(tbegin->transname);
    		free(tbegin->transdir);
    		tbegin = tbegin->next;
    		free(t);
    		return TRUE;
    	}
    	else
    	{
    		strcpy(transret, "");
    		strcpy(dirret, "");
    		return FALSE;
    	}
    }
    
    // Create datadirectory-structure (Mode 755, drwxr-xr-x)
    void make_directories(void)
    {
        struct stat sb;
    	char *name, *buffer;
    
    	name = malloc(LINESIZE);
    	buffer = malloc(LINESIZE+10);
    
    	name = getvalue("global","datadir");
    	if(strncmp(&((name)[strlen(name)-1]), "/",1) != 0)
    		sprintf(name, "%s/",name);
    
        if (stat (name, &sb) == 0)
    	{
    		if(!S_ISDIR (sb.st_mode))
    		{
    			fprintf(stderr,"%s: [error creating datadirectory-structure: %s]\n",
    				do_date(time((time_t *)NULL), TRUE), getvalue("global","datadir"));
    			exit(1);	// Error : can't create datadir!
    		}
    	}
    	else
    	{	if (mkdir (name, 16877) < 0)
    		{
    			fprintf(stderr,"%s: [error creating datadirectory-structure: %s]\n",
    				do_date(time((time_t *)NULL), TRUE), getvalue("global","datadir"));
    			exit(1);	// Error : can't create datadir!
    		}
    	}
    
    	sprintf(buffer, "%sbigfiles/",name);
    	ddb = malloc (strlen(buffer)+1);
    	strcpy(ddb, buffer);
        if (stat (buffer, &sb) == 0)
    	{
    		if(!S_ISDIR (sb.st_mode))
    		{
    			fprintf(stderr,"%s: [error creating datadirectory-structure: %s]\n",
    				do_date(time((time_t *)NULL), TRUE), getvalue("global","datadir"));
    			exit(1);	// Error : can't create datadir!
    		}
    	}
    	else
    	{	if (mkdir (buffer, 16877) < 0)
    		{
    			fprintf(stderr,"%s: [error creating datadirectory-structure: %s]\n",
    				do_date(time((time_t *)NULL), TRUE), getvalue("global","datadir"));
    			exit(1);	// Error : can't create datadir!
    		}
    	}
        sprintf(buffer, "%slevel/",name);
    	ddl = malloc (strlen(buffer)+1);
    	strcpy(ddl, buffer);
        if (stat (buffer, &sb) == 0)
    	{
    		if(!S_ISDIR (sb.st_mode))
    		{
    			fprintf(stderr,"%s: [error creating datadirectory-structure: %s]\n",
    				do_date(time((time_t *)NULL), TRUE), getvalue("global","datadir"));
    			exit(1);	// Error : can't create datadir!
    		}
    	}
    	else
    	{	if (mkdir (buffer, 16877) < 0)
    		{
    			fprintf(stderr,"%s: [error creating datadirectory-structure: %s]\n",
    				do_date(time((time_t *)NULL), TRUE), getvalue("global","datadir"));
    			exit(1);	// Error : can't create datadir!
    		}
    	}
        sprintf(buffer, "%soldfiles/",name);
    	ddo = malloc (strlen(buffer)+1);
    	strcpy(ddo, buffer);
        if (stat (buffer, &sb) == 0)
    	{
    		if(!S_ISDIR (sb.st_mode))
    		{
    			fprintf(stderr,"%s: [error creating datadirectory-structure: %s]\n",
    				do_date(time((time_t *)NULL), TRUE), getvalue("global","datadir"));
    			exit(1);	// Error : can't create datadir!
    		}
    	}
    	else
    	{	if (mkdir (buffer, 16877) < 0)
    		{
    			fprintf(stderr,"%s: [error creating datadirectory-structure: %s]\n",
    				do_date(time((time_t *)NULL), TRUE), getvalue("global","datadir"));
    			exit(1);	// Error : can't create datadir!
    
    		}
    	}
        sprintf(buffer, "%sillegal/",name);
    	ddi = malloc (strlen(buffer)+1);
    	strcpy(ddi, buffer);
        if (stat (buffer, &sb) == 0)
    	{
    		if(!S_ISDIR (sb.st_mode))
    		{
    			fprintf(stderr,"%s: [error creating datadirectory-structure: %s]\n",
    				do_date(time((time_t *)NULL), TRUE), getvalue("global","datadir"));
    			exit(1);	// Error : can't create datadir!
    
    		}
    	}
    	else
    	{	if (mkdir (buffer, 16877) < 0)
    		{
    			fprintf(stderr,"%s: [error creating datadirectory-structure: %s]\n",
    				do_date(time((time_t *)NULL), TRUE), getvalue("global","datadir"));
    			exit(1);	// Error : can't create datadir!
    
    		}
    	}
    	free(name);
    	free(buffer);
    	return;
    }
    
    // Puts an entry ordered into the double linked list to remember big files
    void insertbig(float size, char *date, char *path, char *filename)
    {
    	struct smlfilelist *pb, *pb1;
    	if((pb =(struct smlfilelist *) malloc(sizeof(struct smlfilelist))) == NULL)
    	{
    		fprintf(stderr,"%s: Error allocating memory!\n", do_date(time((time_t *)NULL), TRUE));
    		exit(5);	// No more memory available, that's a real problem.
    	}
    	pb->size = size;
    	pb->date = scopy(date);
    	pb->path = scopy(path);
    	pb->filename = scopy(filename);
    
    	if(bbegin == NULL)
    	{
    		bbegin = bend = pb;
    		bbegin->next = NULL;
    		bbegin->previous = NULL;
    	}
    	else
    	{
    		if (pb->size < bbegin->size)
    		{
    			pb->next = bbegin;
    			pb->previous = NULL;
    			bbegin->previous = pb;
    			bbegin = pb;
    			bbegin->previous = NULL;
    		}
    		else
    		{
    			if(pb->size > bend->size)
    			{
    				pb->next = NULL;
    				bend->next = pb;
    				pb->previous = bend;
    				bend = pb;
    			}
    			else
    			{
    				pb1 = bbegin;
    				while(pb1->size < pb->size)
    					pb1=pb1->next;
    				pb1->previous->next = pb;
    				pb->previous = pb1->previous;
    				pb1->previous = pb;
    				pb->next = pb1;
    			}
    		}
    	}
    return;
    }
    
    // Puts an entry ordered into the double linked list to remember levels of single directories
    void insertlevel(float size, char *path, int count)
    {
    	struct smlfilelist *pl, *pl1;
    	if((pl =(struct smlfilelist *) malloc(sizeof(struct smlfilelist))) == NULL)
    	{
    		fprintf(stderr,"%s: Error allocating memory!\n", do_date(time((time_t *)NULL), TRUE));
    		exit(5);	// No more memory available, that's a real problem.
    	}
    	pl->size = size;
    	pl->path = scopy(path);
    	pl->count = count;
    	if(lbegin == NULL)
    	{
    		lbegin = lend = pl;
    		lbegin->next = NULL;
    		lbegin->previous = NULL;
    	}
    	else
    	{
    		if (strcmp(pl->path, lbegin->path) <= 0)
    		{
    			pl->next = lbegin;
    			pl->previous = NULL;
    			lbegin->previous = pl;
    			lbegin = pl;
    			lbegin->previous = NULL;
    		}
    		else
    		{
    			if(strcmp(pl->path, lend->path) > 0)
    			{
    				pl->next = NULL;
    				lend->next = pl;
    				pl->previous = lend;
    				lend = pl;
    			}
    			else
    			{
    				pl1 = lbegin;
    				while(strcmp(pl1->path, pl->path) <= 0)
    					pl1=pl1->next;
    				pl1->previous->next = pl;
    				pl->previous = pl1->previous;
    				pl1->previous = pl;
    				pl->next = pl1;
    			}
    		}
    	}
    	return;
    }
    
    // Puts an entry ordered into the double linked list to remember old files
    void insertold(float size, char *date, char *path, char *filename)
    {
    	struct smlfilelist *po, *po1;
    	if((po =(struct smlfilelist *) malloc(sizeof(struct smlfilelist))) == NULL)
    	{
    		fprintf(stderr,"%s: Error allocating memory!\n", do_date(time((time_t *)NULL), TRUE));
    		exit(5);	// No more memory available, that's a real problem.
    	}
    	po->size = size;
    	po->date = scopy(date);
    	po->path = scopy(path);
    	po->filename = scopy(filename);
    	if(obegin == NULL)
    	{
    		obegin = oend = po;
    		obegin->next = NULL;
    		obegin->previous = NULL;
    	}
    	else
    	{
    		// If smaller than anything in the list -> beginning
    		if ((strcmp(po->path, obegin->path) < 0) || (strcmp(po->path, obegin->path) == 0
    		    && po->size <= obegin->size))
    		{
    			po->next = obegin;
    			po->previous = NULL;
    			obegin->previous = po;
    			obegin = po;
    			obegin->previous = NULL;
    		}
    		else
    		{
    			if(strcmp(po->path,oend->path) > 0 || (strcmp(po->path, oend->path) == 0
    			   && po->size >= oend->size))
    			{
    				po->next = NULL;
    				oend->next = po;
    				po->previous = oend;
    				oend = po;
    			}
    			else
    			{
    				po1 = obegin;
    				while((strcmp(po1->path, po->path) < 0) || 
    				     (strcmp(po1->path, po->path) == 0 &&
    				     po1->size <= po->size) && po1)
    					po1=po1->next;
    
    				po1->previous->next = po;
    				po->previous = po1->previous;
    				po1->previous = po;
    				po->next = po1;
    			}
    		}
    	}
    return;
    }
    
    // Prints all entries from the double linked list that holds the big files
    void printbig(char * tname, char *tdir)
    {
    	char * buffer;
    	struct smlfilelist *p, *p1;
    	FILE *ddbp;
    	int i = 0;
    	buffer = malloc(LINESIZE);	
    	sprintf(buffer, "%s%s.big", ddb, tname);
    	ddbp = openfile(buffer, "w");
    	fprintf(ddbp, "# Big files ( > %s MB) from %s in %s (%s)\n# path;filename;timestamp;size(MB);\n",
    		getvalue(tname, "bigsize"), do_date((time((time_t *)NULL)), TRUE), tname, tdir);
    	p = bend;
    	while(p)
    	{
    		fprintf(ddbp, "%s;%s;%s;%.3f;\n", p->path, p->filename, p->date, p->size);
    		p1 = bend = p->previous;
    		free (p->date);
    		free (p->filename);
    		free (p->path);
    		free(p);
    		p=p1;
    	}
    
    	fclose(ddbp);
    	free(bbegin);
    	free(bend);
    	bbegin = bend = NULL;
    return;
    }
    
    // Prints all entries from the double linked list that holds the old files
    void printold(char * tname, char *tdir)
    {
    	char * buffer;
    	struct smlfilelist *p, *p1;
    	FILE *ddop;
    	int i = 0;
    	buffer = malloc(LINESIZE);
    	sprintf(buffer, "%s%s.old", ddo, tname);
    	ddop = openfile(buffer, "w");
    	fprintf(ddop, "# Old files (Content last modified before %s days) from %s in %s (%s)\n# path;filename;timestamp;size(MB);\n",
    		getvalue(tname, "olddate"), do_date((time((time_t *)NULL)), TRUE), tname, tdir);
    	p = oend;
    	while(p)
    	{
    		fprintf(ddop, "%s;%s;%s;%.3f;\n", p->path, p->filename, p->date, p->size);
    		p1 = oend = p->previous;
    		free (p->date);
    		free (p->filename);
    		free (p->path);
    		free(p);
    		p=p1;
    	}
    
    	fclose(ddop);
    	free(obegin);
    	free(oend);
    	obegin = oend = NULL;
    	return;
    }
    
    // Prints all entries from the double linked list that holds the levels of the directories
    void printlevel(char * tname, char *tdir)
    {
    	char * buffer;
    	struct smlfilelist *p, *p1;
    	int i = 1;
    	struct stat t;
    	FILE *ddlp;
    	buffer = malloc(LINESIZE);
    	sprintf(buffer, "%s%s.%s", ddl, tname, do_date(time((time_t *)NULL), FALSE));
    
    	while(stat(buffer,&t) >= 0)
    	{
    	sprintf(buffer, "%s%s.%s-%d", ddl, tname, do_date(time((time_t *)NULL), FALSE), i++);
    	}
    	ddlp = openfile(buffer, "w");
    	fprintf(ddlp, "# Level of transport directory \"%s\" (%s)\n# path;filecount;size (MB)\n", tname, tdir);
    	p = lbegin;
    	while(p)
    	{
    		fprintf(ddlp, "%s;%d;%.3f;\n", p->path, p->count, p->size);
    		p1 = lbegin = p->next;
    		free (p->path);
    		free(p);
    		p=p1;
    	}
    
    	fclose(ddlp);
    	free(lbegin);
    	free(lend);
    	lbegin = lend = NULL;
    return;
    }
    
    // This function opens the configfile (whether standard "./tfscheck.cfg"
    // or explicitely given through command-line argument
    int fetchvalues(struct trans *tbegin, struct config *cbegin, int argc, char **argv)
    {
    
    	char *configfilename,*line, *section, *key, *value;
    	char sec_is_ok = FALSE;
    	FILE *cfp;
    	line = malloc(LINESIZE);
    	key = malloc(LINESIZE);
    	value = malloc(LINESIZE);
    	section = malloc(LINESIZE);
    
    	if (argc > 1)
    	{
    
    		if (strcmp(argv[1], "-h") == 0 || 
    		    strcmp(argv[1], "-?") == 0 ||
    		    strcmp(argv[1], "/h") == 0 ||
    		    strcmp(argv[1], "/?") == 0 ||
    		    strcmp(argv[1], "--help") == 0 )
    		{
    			printf("Usage:\t%s : Scans Filesystem with default configuration file ('./tfscheck.cfg')\n", argv[0]);
    			printf("\t%s <configfile>: Scans Filesystem with <configfile>\n", argv[0]);
    			exit(0);		// Usage-message printed
    		}
    		configfilename = malloc(strlen(argv[1])+1);
    		strcpy(configfilename, argv[1]);
    	}
    	else
    	{
    		configfilename = malloc(LINESIZE);
    		sprintf(configfilename, "%s/tfscheck.cfg",curdir);
    	}
    	cfp = openfile(configfilename,"r");
    
    	while((fgets(line, LINESIZE, cfp)) != NULL)
    	{
    		if(line[0] != '#' && strlen(line) > 2)	// Skip blank lines and comments
    		{
    			if(line[0] == '[')						// We found a new section
    			{
    				strcpy(section,line);
    				strtok(section++, "[ ]");
    				sec_is_ok = TRUE;
    			}
    			else									// We found a new value
    			{
    				strcpy(value,line);
    				strcpy(key,line);
    				strtok(key, " =\r\n");
    				strtok(value, " =\r\n");
    				value = strtok(NULL, " =\r\n");
    				if(value[strlen(value)-1] == '/') value[strlen(value)-1] = '\0';
    				if (sec_is_ok == FALSE)
    				{
    					fprintf(stderr, "%s: [Error in configuration file - cannot associate parameter \"%s\" to a transport directory]",
    						do_date(time((time_t *)NULL), TRUE), key);
    					exit(4);
    				}
    				if (strncmp(key, "transdir", 8) == 0) inserttrans(section, value);
    				insertconfig(section, key, value);
    			}
    		}
    	}
    
    	fclose(cfp);
    	free(line);
    	free(key);
    	return 0;
    }
    
    // Insert the values from configfile into an internal structure
    void insertconfig(char *section, char *key, char *value)
    {
    	struct config *p, *p1;
    	if((p =(struct config *) malloc(sizeof(struct config))) == NULL)
    	{
    		fprintf(stderr,"%s: Error allocating memory!\n", do_date(time((time_t *)NULL), TRUE));
    		exit(5);	// No more memory available, that's a real problem.
    	}
    	p->section = scopy(section);
    	p->key = scopy(key);
    	p->value = scopy(value);
    
    	if(cbegin == NULL)
    	{
    		cbegin = cend = p;
    		cbegin->next = NULL;
    		cbegin->previous = NULL;
    	}
    	else
    	{
    
    				p->next = NULL;
    				cend->next = p;
    				p->previous = cend;
    				cend = p;
    	}
    return;
    }
    
    // Remember all "sections" from configfile
    void inserttrans(char *transname, char *transdir)
    {
    	struct trans *p, *p1;
    	if((p =(struct trans *) malloc(sizeof(struct trans))) == NULL)
    	{
    		fprintf(stderr,"%s: Error allocating memory!\n", do_date(time((time_t *)NULL), TRUE));
    		exit(5);	// No more memory available, that's a real problem.
    	}
    	p->transname = scopy(transname);
    	p->transdir = scopy(transdir);
    
    	if(tbegin == NULL)
    	{
    		tbegin = tend = p;
    		tbegin->next = NULL;
    		tbegin->previous = NULL;
    	}
    	else
    	{
    
    				p->next = NULL;
    				tend->next = p;
    				p->previous = tend;
    				tend = p;
    	}
    return;
    }
    
    // Prints all entries from the double linked list that holds the illegal directories
    void printillegal(char * tname, char *tdir)
    {
    	char * buffer;
    	struct smlfilelist *p, *p1;
    	FILE *ddip;
    	buffer = malloc(LINESIZE);
    	sprintf(buffer, "%s%s.illegal", ddi, tname);
    	ddip = openfile(buffer, "w");
    	fprintf(ddip, "# Illegal directories in %s (%s) from %s\n# path;timestamp;\n",
    		tname, tdir, do_date((time((time_t *)NULL)), TRUE));
    	p = iend;
    	while(p)
    	{
    		fprintf(ddip, "%s;%s;%s;%.3f;\n", p->path, p->filename, p->date, p->size);
    		p1 = iend = p->previous;
    		free (p->date);
    		free (p->path);
    		free(p);
    		p=p1;
    	}
    
    	fclose(ddip);
    	free(ibegin);
    	free(iend);
    	ibegin = iend = NULL;
    return;
    }
    
    // Get all "legal" directories for the given transportdirectory
    void checklegal(char *tname, char *dname)
    {
    	// Not printing anything yet !
    	// Still has to be implemented
    	char *buffer, *buffer2;
    	buffer = malloc(LINESIZE);
    	buffer2 = malloc(50);
    	strcpy(buffer, getvalue(tname, "legaldir"));
    	if(strcmp(getvalue("global", "legaldir"),getvalue(tname, "legaldir")) != 0)
    		sprintf(buffer, "%s;%s", buffer, getvalue("global", "legaldir"));
    
    	buffer2 = strtok(buffer, ";\r\n");
    	while(buffer2 != NULL)
    	{
    	buffer2 = strtok(NULL, ";\r\n");
    	}
    	free(buffer);
    	free(buffer2);
    	return;
    }
    
    /** Necessary only on systems without glibc **/
    void *xmalloc (size_t size)
    {
      register void *value = malloc (size);
      if (value == 0) {
        fprintf(stderr,"tree: virtual memory exhausted.\n");
        exit(1);
      }
      return value;
    }
    
    void *xrealloc (void *ptr, size_t size)
    {
      register void *value = realloc (ptr,size);
      if (value == 0) {
        fprintf(stderr,"tree: virtual memory exhausted.\n");
        exit(1);
      }
      return value;
    }
    

    und noch das Configfile "tfscheck.cfg":

    # Globale Sektion. Gültig, wenn in der Sektion für das jeweilige Transportverzeichnis nichts überschrieben wird.
    [global]
    
    # Datenablageverzeichnis
    # Hier speichert tfscheck die Datenfiles ab.
    
    # Datenverzeichnis, in das tfscheck seine Datenfiles ablegt.
    # In der root wird auch das Errorlog "tfscheck.err" abgelegt,
    # falls bei der Bearbeitung Fehler aufgetreten sind
    
    datadir = /home/dieter/tfscheck/data
    
    # Name des Error-Logfiles
    
    errorlog = tfscheck.err
    
    # Schwellwert in MB für Dateigröße, ab der sie als groß angesehen wird
    
    bigsize = 100
    
    # Maximales Alter einer Datei in Tagen bevor sie als alt angesehen wird.
    
    olddate = 90
    
    # "Legale" Unterverzeichnisse im Transportverzeichnis
    
    legaldir = EPS;bin;buffer;tmp
    
    # Auflistung der Transportverzeichnisse und spezielle Parametrierung
    
    [trans6]
    
    #transdir = /usr/sap/trans6/
    transdir = /home/dieter
    olddate = 2
    bigsize = 1
    
    [trans63]
    
    transdir = /bin
    legaldir = foo;bar
    olddate = 10
    bigsize = 20
    


  • Hallo? Sonst gehts dir aber noch gut?

    1. Du hast das Thema 4 mal im Forum erstellt
    2. Niemand wird sich so einen Sourcecode hier freiwillig anschauen
    3. Beschraenke dich beim Sourcecode auf die Problembereiche
    4. Wenn du soviel Sourcecode hast, poste es nach http://www.rafb.net/paste/
      und frag ob sich das mal jemand anschauen koennte, dann werden die meisten
      das auch machen

    mfg
    v R



  • Zum SIGSEGV...
    Kann es irgendwo passieren, dass du mal auf einen nicht oder nicht ausreichend gross allokierten Speicher zugreifst?

    Sind deine Variablen alle initialisiert? (Ich schaue mir jetzt nicht jede Zeile deines Quellcode an)

    Jetzt zum Quellcode...

    #define scopy(x)    strcpy(malloc(strlen(x)+1),(x))
    

    Warum verwendest du strcpy() und nicht strncpy() ?

    Wäre es nicht auch möglich (und vielleicht sinnvoller) statt deinem scopy() Makro den Befehl sprintf() oder besser noch snprintf() zu verwenden?

    Zum Beispiel statt

    dl[p]->name = scopy(ent->d_name);
    

    dann folgendes (kannst dir ja ein Makro drumrum stricken falls dir das zu viel Tipparbeit ist:

    snprintf( dl[p]->name, strlen(ent->d_name), "%s" , ent->d_name );
    
    // PROBLEMATISCH 
    dl[p] = (struct _info *) malloc(sizeof(struct _info));
    

    Wenn du deinen Quellcode nur in einem C Projekt (und nicht in einem C++ Projekt) verwendest, dann brauchst du den Rückgabewert von malloc() nicht zu casten.
    http://www-info2.informatik.uni-wuerzburg.de/dclc-faq/kap3.html#3.5
    http://www.eskimo.com/~scs/C-faq/q7.7.html

    dl[p]->name = scopy(ent->d_name);
    

    Kann es vorkommen, dass bei einem deiner vielen scopy() aufrufe irgendwann, irgendwo das an scopy() übergebene Argument mal Null wird? Wenn ja, wird strlen() das sicher nicht gerne mögen.



  • Hi,

    schau dir mal das Programm strace an, koennte dir evtl. bei der Fehler-
    suche helfen. Ansonsten halt mal debuggen (gdb).

    mfg
    v R



  • virtuell Realisticer schrieb:

    Ansonsten halt mal debuggen (gdb)

    Jo, gdbs "where" ist Dein Freund! 😉


Anmelden zum Antworten