#include "cvs.h"
#include "getline.h"
static char **ign_list;
static char **s_ign_list = NULL;
static int ign_count;
static int s_ign_count = 0;
static int ign_size;
static int ign_hold = -1;
const char *ign_default = ". .. core RCSLOG tags TAGS RCS SCCS .make.state\
.nse_depinfo #* .#* cvslog.* ,* CVS CVS.adm .del-* *.a *.olb *.o *.obj\
*.so *.Z *~ *.old *.elc *.ln *.bak *.BAK *.orig *.rej *.exe _$* *$";
#define IGN_GROW 16
int ign_inhibit_server;
void
ign_setup ()
{
char *home_dir;
char *tmp;
ign_inhibit_server = 0;
tmp = xstrdup (ign_default);
ign_add (tmp, 0);
free (tmp);
#ifdef CLIENT_SUPPORT
if (!client_active)
#endif
{
char *file = xmalloc (strlen (CVSroot_directory) + sizeof (CVSROOTADM)
+ sizeof (CVSROOTADM_IGNORE) + 10);
(void) sprintf (file, "%s/%s/%s", CVSroot_directory,
CVSROOTADM, CVSROOTADM_IGNORE);
ign_add_file (file, 0);
free (file);
}
home_dir = get_homedir ();
if (home_dir)
{
char *file = xmalloc (strlen (home_dir) + sizeof (CVSDOTIGNORE) + 10);
(void) sprintf (file, "%s/%s", home_dir, CVSDOTIGNORE);
ign_add_file (file, 0);
free (file);
}
ign_add (getenv (IGNORE_ENV), 0);
}
void
ign_add_file (file, hold)
char *file;
int hold;
{
FILE *fp;
char *line = NULL;
size_t line_allocated = 0;
if (s_ign_list != NULL)
{
int i;
for (i = 0; i < s_ign_count; i++)
ign_list[i] = s_ign_list[i];
ign_count = s_ign_count;
ign_list[ign_count] = NULL;
s_ign_count = 0;
free (s_ign_list);
s_ign_list = NULL;
}
if (hold)
{
if (ign_hold >= 0)
{
int i;
for (i = ign_hold; i < ign_count; i++)
free (ign_list[i]);
ign_count = ign_hold;
ign_list[ign_count] = NULL;
}
else
{
ign_hold = ign_count;
}
}
fp = CVS_FOPEN (file, "r");
if (fp == NULL)
{
if (! existence_error (errno))
error (0, errno, "cannot open %s", file);
return;
}
while (getline (&line, &line_allocated, fp) >= 0)
ign_add (line, hold);
if (ferror (fp))
error (0, errno, "cannot read %s", file);
if (fclose (fp) < 0)
error (0, errno, "cannot close %s", file);
free (line);
}
void
ign_add (ign, hold)
char *ign;
int hold;
{
if (!ign || !*ign)
return;
for (; *ign; ign++)
{
char *mark;
char save;
if (isspace (*ign))
continue;
if ((!*(ign+1) || isspace (*(ign+1))) && (*ign == '!' || *ign == '*'))
{
if (!hold)
{
int i;
for (i = 0; i < ign_count; i++)
free (ign_list[i]);
ign_count = 0;
ign_list[0] = NULL;
if (*ign == '!')
{
ign_inhibit_server = 1;
continue;
}
}
else if (*ign == '!')
{
int i;
if (ign_hold >= 0)
{
for (i = ign_hold; i < ign_count; i++)
free (ign_list[i]);
ign_hold = -1;
}
s_ign_list = (char **) xmalloc (ign_count * sizeof (char *));
for (i = 0; i < ign_count; i++)
s_ign_list[i] = ign_list[i];
s_ign_count = ign_count;
ign_count = 0;
ign_list[0] = NULL;
continue;
}
}
if (ign_count >= ign_size)
{
ign_size += IGN_GROW;
ign_list = (char **) xrealloc ((char *) ign_list,
(ign_size + 1) * sizeof (char *));
}
for (mark = ign; *mark && !isspace (*mark); mark++)
;
save = *mark;
*mark = '\0';
ign_list[ign_count++] = xstrdup (ign);
ign_list[ign_count] = NULL;
*mark = save;
if (save)
ign = mark;
else
ign = mark - 1;
}
}
int ign_case;
int
ign_name (name)
char *name;
{
char **cpp = ign_list;
if (cpp == NULL)
return (0);
if (ign_case)
{
char *name_lower;
char *pat_lower;
char *p;
name_lower = xstrdup (name);
for (p = name_lower; *p != '\0'; ++p)
*p = tolower (*p);
while (*cpp)
{
pat_lower = xstrdup (*cpp++);
for (p = pat_lower; *p != '\0'; ++p)
*p = tolower (*p);
if (CVS_FNMATCH (pat_lower, name_lower, 0) == 0)
goto matched;
free (pat_lower);
}
free (name_lower);
return 0;
matched:
free (name_lower);
free (pat_lower);
return 1;
}
else
{
while (*cpp)
if (CVS_FNMATCH (*cpp++, name, 0) == 0)
return 1;
return 0;
}
}
static char **dir_ign_list = NULL;
static int dir_ign_max = 0;
static int dir_ign_current = 0;
void
ign_dir_add (name)
char *name;
{
if (dir_ign_current <= dir_ign_max)
{
dir_ign_max += IGN_GROW;
dir_ign_list =
(char **) xrealloc (dir_ign_list,
(dir_ign_max + 1) * sizeof (char *));
}
dir_ign_list[dir_ign_current] = name;
dir_ign_current += 1 ;
}
int
ignore_directory (name)
char *name;
{
int i;
if (!dir_ign_list)
return 0;
i = dir_ign_current;
while (i--)
{
if (strncmp (name, dir_ign_list[i], strlen (dir_ign_list[i])) == 0)
return 1;
}
return 0;
}
void
ignore_files (ilist, entries, update_dir, proc)
List *ilist;
List *entries;
char *update_dir;
Ignore_proc proc;
{
int subdirs;
DIR *dirp;
struct dirent *dp;
struct stat sb;
char *file;
char *xdir;
if (entries == NULL)
subdirs = 0;
else
{
struct stickydirtag *sdtp;
sdtp = (struct stickydirtag *) entries->list->data;
subdirs = sdtp == NULL || sdtp->subdirs;
}
if (strcmp (update_dir, ".") == 0)
xdir = "";
else
xdir = update_dir;
dirp = CVS_OPENDIR (".");
if (dirp == NULL)
return;
ign_add_file (CVSDOTIGNORE, 1);
wrap_add_file (CVSDOTWRAPPER, 1);
while ((dp = readdir (dirp)) != NULL)
{
file = dp->d_name;
if (strcmp (file, ".") == 0 || strcmp (file, "..") == 0)
continue;
if (findnode_fn (ilist, file) != NULL)
continue;
if (subdirs)
{
Node *node;
node = findnode_fn (entries, file);
if (node != NULL
&& ((Entnode *) node->data)->type == ENT_SUBDIR)
{
char *p;
int dir;
p = xmalloc (strlen (file) + sizeof CVSADM + 10);
sprintf (p, "%s/%s", file, CVSADM);
dir = isdir (p);
free (p);
if (dir)
continue;
}
}
if (ign_name (file))
continue;
if (
#ifdef DT_DIR
dp->d_type != DT_UNKNOWN ||
#endif
lstat(file, &sb) != -1)
{
if (
#ifdef DT_DIR
dp->d_type == DT_DIR || dp->d_type == DT_UNKNOWN &&
#endif
S_ISDIR(sb.st_mode))
{
if (! subdirs)
{
char *temp;
temp = xmalloc (strlen (file) + sizeof (CVSADM) + 10);
(void) sprintf (temp, "%s/%s", file, CVSADM);
if (isdir (temp))
{
free (temp);
continue;
}
free (temp);
}
}
#ifdef S_ISLNK
else if (
#ifdef DT_DIR
dp->d_type == DT_LNK || dp->d_type == DT_UNKNOWN &&
#endif
S_ISLNK(sb.st_mode))
{
continue;
}
#endif
}
(*proc) (file, xdir);
}
(void) closedir (dirp);
}