Ejemplo n.º 1
0
int fdset_new_fill(FDSet **_s) {
        DIR *d;
        struct dirent *de;
        int r = 0;
        FDSet *s;

        assert(_s);

        /* Creates an fdset and fills in all currently open file
         * descriptors. */

        d = opendir("/proc/self/fd");
        if (!d)
                return -errno;

        s = fdset_new();
        if (!s) {
                r = -ENOMEM;
                goto finish;
        }

        while ((de = readdir(d))) {
                int fd = -1;

                if (ignore_file(de->d_name))
                        continue;

                r = safe_atoi(de->d_name, &fd);
                if (r < 0)
                        goto finish;

                if (fd < 3)
                        continue;

                if (fd == dirfd(d))
                        continue;

                r = fdset_put(s, fd);
                if (r < 0)
                        goto finish;
        }

        r = 0;
        *_s = s;
        s = NULL;

finish:
        closedir(d);

        /* We won't close the fds here! */
        if (s)
                set_free(MAKE_SET(s));

        return r;
}
Ejemplo n.º 2
0
static int add_locales_from_libdir (Set *locales) {
        _cleanup_closedir_ DIR *dir;
        struct dirent *entry;
        int r;

        dir = opendir("/usr/lib/locale");
        if (!dir) {
                log_error("Failed to open locale directory: %m");
                return -errno;
        }

        errno = 0;
        while ((entry = readdir(dir))) {
                char *z;

                if (entry->d_type != DT_DIR)
                        continue;

                if (ignore_file(entry->d_name))
                        continue;

                z = strdup(entry->d_name);
                if (!z)
                        return log_oom();

                r = set_consume(locales, z);
                if (r < 0 && r != -EEXIST) {
                        log_error("Failed to add locale: %s", strerror(-r));
                        return r;
                }

                errno = 0;
        }

        if (errno > 0) {
                log_error("Failed to read locale directory: %m");
                return -errno;
        }

        return 0;
}
Ejemplo n.º 3
0
int main(int argc, char **argv)
{
	int i, c, ret = 0;
	int n_files;
	unsigned long n_units = DEFAULT_N_LINES;
	char forever = 0, mode = M_LINES;
	char **filenames;
	//struct file_struct *files = NULL;
	int event_cnt = 1;

  /* Set up logging */
	openlog("AUDITD_BRO", 0, LOG_USER);

	au = auparse_init(AUSOURCE_FEED, 0);
	auparse_add_callback(au, auparse_callback, &event_cnt, NULL);

	if (au == NULL) {
		printf("Error - %s\n", strerror(errno));
		return 1;
	}

	while ((c = getopt_long(argc, argv, "c:n:fvVh", long_opts, NULL)) != -1) {
		switch (c) {
		case 'c':
			mode = M_BYTES;
			/* fall through */
		case 'n':
			if (*optarg == '+') {
				from_begin = 1;
				optarg++;
			} else if (*optarg == '-')
				optarg++;

			if (!is_digit(*optarg)) {
				fprintf(stderr, "Error: Invalid number of units: %s\n", optarg);
				exit(EXIT_FAILURE);
			}
			n_units = strtoul(optarg, NULL, 0);
			break;
                case 'f':
			forever = 1;
			break;
		case 'v':
			verbose = 1;
			break;
		case 'V':
			fprintf(stdout, "%s %s\n", PROGRAM_NAME, VERSION);
			exit(EXIT_SUCCESS);
		case 'h':
			usage(EXIT_SUCCESS);
		default:
			usage(EXIT_FAILURE);
		}
	}

	/* Do we have some files to read from? */
	if (optind < argc) {
		n_files = argc - optind;
		filenames = argv + optind;
	} else {
		/* It must be stdin then */
		static char *dummy_stdin = "-";
		n_files = 1;
		filenames = &dummy_stdin;

		/* POSIX says that -f is ignored if no file operand is
		   specified and standard input is a pipe. */
		if (forever) {
			struct stat finfo;
			int rc = fstat(STDIN_FILENO, &finfo);

			if (unlikely(rc == -1)) {
				fprintf(stderr, "Error: Could not stat stdin (%s)\n", strerror(errno));
				exit(EXIT_FAILURE);
			}

			if (rc == 0 && IS_PIPELIKE(finfo.st_mode))
				forever = 0;
		}
	} // end stdin

	files = emalloc(n_files * sizeof(struct file_struct));

	for (i = 0; i < n_files; i++) {
		files[i].name = filenames[i];
		setup_file(&files[i]);
		ret = tail_file(&files[i], n_units, mode, forever);
		if (ret < 0)
			ignore_file(&files[i]);
	}

	if (forever)
		ret = watch_files(files, n_files);

	free(files);

	auparse_flush_feed(au);
	auparse_destroy(au);
	closelog();

	return ret;
}
Ejemplo n.º 4
0
static int watch_files(struct file_struct *_files, int n_files)
{
	int ifd, i;
	char buf[n_files * INOTIFY_BUFLEN];

	ifd = inotify_init();
	if (errno == ENOSYS) {
		fprintf(stderr, "Error: inotify is not supported by the kernel you're currently running.\n");
		exit(EXIT_FAILURE);
	} else if (unlikely(ifd < 0)) {
		fprintf(stderr, "Error: Could not initialize inotify (%s)\n", strerror(errno));
		exit(EXIT_FAILURE);
	}

	for (i = 0; i < n_files; i++) {
		if (!_files[i].ignore) {
			_files[i].i_watch = inotify_add_watch(ifd, _files[i].name,
						IN_MODIFY|IN_DELETE_SELF|IN_MOVE_SELF|IN_UNMOUNT);

			if (_files[i].i_watch < 0) {
				fprintf(stderr, "Error: Could not create inotify watch on file '%s' (%s)\n",
						_files[i].name, strerror(errno));
				ignore_file(&_files[i]);
			}
		}
	}

	while (n_ignored < n_files) {
		ssize_t len;
		int ev_idx = 0;

		len = read(ifd, buf, (n_files * INOTIFY_BUFLEN));
		if (unlikely(len < 0)) {
			/* Some signal, likely ^Z/fg's STOP and CONT interrupted the inotify read, retry */
			if (errno == EINTR || errno == EAGAIN)
				continue;
			else {
				fprintf(stderr, "Error: Could not read inotify events (%s)\n", strerror(errno));
				exit(EXIT_FAILURE);
			}
		}

		while (ev_idx < len) {
			struct inotify_event *inev;
			struct file_struct *f = NULL;

			inev = (struct inotify_event *) &buf[ev_idx];

			/* Which file has produced the event? */
			for (i = 0; i < n_files; i++) {
				if (!_files[i].ignore
						&& _files[i].fd >= 0
						&& _files[i].i_watch == inev->wd) {
					f = &_files[i];
					break;
				}
			}

			if (unlikely(!f))
				break;

			if (handle_inotify_event(inev, f) < 0)
				break;

			ev_idx += sizeof(struct inotify_event) + inev->len;
		}
	}

	close(ifd);
	return -1;
}
Ejemplo n.º 5
0
static int handle_inotify_event(struct inotify_event *inev, struct file_struct *f)
{
	int ret = 0;

	if (inev->mask & IN_MODIFY) {
		char *fbuf;
		ssize_t rc;
		struct stat finfo;

		if (verbose)
			write_header(f->name);

		/* Seek to old file size */
		if (lseek(f->fd, f->size, SEEK_SET) == (off_t) -1) {
			fprintf(stderr, "Error: Could not seek in file '%s' (%s)\n", f->name, strerror(errno));
			ret = -1;
			goto ignore;
		}

		fbuf = emalloc(f->blksize);

		while ((rc = read(f->fd, fbuf, f->blksize)) != 0) {
			auparse_feed(au,fbuf, rc);
			}

		if (fstat(f->fd, &finfo) < 0) {
			fprintf(stderr, "Error: Could not stat file '%s' (%s)\n", f->name, strerror(errno));
			ret = -1;
			free(fbuf);
			goto ignore;
		}

		f->size = finfo.st_size;

		free(fbuf);
		return ret;
	} else if (inev->mask & IN_DELETE_SELF) {
		fprintf(stderr, "File '%s' deleted.\n", f->name);
	} else if (inev->mask & IN_MOVE_SELF) {
		fprintf(stderr, "File '%s' moved.\n", f->name);

		// SCOTT
		close(f->fd);

		free(files);
		struct file_struct *new_files = NULL;
		new_files = emalloc( sizeof(struct file_struct) );
		new_files[0].name = "/var/log/audit/audit.log";
		setup_file(&new_files[0]);

	    // Take a sec here to let the new file get
		//  set up by the OS - there are problems with this
		//  asking just a bit too soon.
		sleep(1);
		tail_file(new_files, DEFAULT_N_LINES, M_LINES, 1);
		watch_files(new_files, 1);
		return 0;
	} else if (inev->mask & IN_UNMOUNT) {
		fprintf(stderr, "Device containing file '%s' unmounted.\n", f->name);
	}

ignore:
	ignore_file(f);
	return ret;
}
Ejemplo n.º 6
0
static int tail_file(struct file_struct *f, unsigned long n_units, char mode, char forever)
{
	ssize_t bytes_read = 0;
	off_t offset = 0;
	char *buf;
	struct stat finfo;

	if (strcmp(f->name, "-") == 0)
		f->fd = STDIN_FILENO;
	else {
		f->fd = open(f->name, O_RDONLY);
		if (unlikely(f->fd < 0)) {
			fprintf(stderr, "Error: Could not open file '%s' (%s)\n", f->name, strerror(errno));
			ignore_file(f);
			return -1;
		}
	}

	if (fstat(f->fd, &finfo) < 0) {
		fprintf(stderr, "Error: Could not stat file '%s' (%s)\n", f->name, strerror(errno));
		ignore_file(f);
		return -1;
	}

	if (!IS_TAILABLE(finfo.st_mode)) {
		fprintf(stderr, "Error: '%s' of unsupported file type (%s)\n", f->name, strerror(errno));
		ignore_file(f);
		return -1;
	}

	/* Cannot seek on these */
	if (IS_PIPELIKE(finfo.st_mode) || f->fd == STDIN_FILENO)
		return tail_pipe(f);

	f->size = finfo.st_size;
	f->blksize = finfo.st_blksize;	/* TODO: Can this value be 0? */

	if (mode == M_LINES)
		offset = lines_to_offset(f, n_units);
	else
		offset = bytes_to_offset(f, n_units);

	/* We only get negative offsets on errors */
	if (unlikely(offset < 0)) {
		ignore_file(f);
		return -1;
	}

	if (verbose)
		write_header(f->name);

	if (lseek(f->fd, offset, SEEK_SET) == (off_t) -1) {
		fprintf(stderr, "Error: Could not seek in file '%s' (%s)\n", f->name, strerror(errno));
		return -1;
	}

	buf = emalloc(f->blksize);

	while ((bytes_read = read(f->fd, buf, f->blksize)) > 0) {
		auparse_feed(au,buf, bytes_read);
		}

	if (!forever) {
		if (close(f->fd) < 0) {
			fprintf(stderr, "Error: Could not close file '%s' (%s)\n", f->name, strerror(errno));
			free(buf);
			return -1;
		}
	} /* Let the fd open otherwise, we'll need it */

	free(buf);
	return 0;
}
Ejemplo n.º 7
0
static CamelFolderInfo *
scan_dir (CamelStore *store,
          GHashTable *visited,
          CamelFolderInfo *parent,
          const gchar *root,
          const gchar *name,
          guint32 flags,
          GError **error)
{
	CamelFolderInfo *folders, *tail, *fi;
	GHashTable *folder_hash;
	const gchar *dent;
	GDir *dir;

	tail = folders = NULL;

	if (!(dir = g_dir_open (root, 0, NULL)))
		return NULL;

	folder_hash = g_hash_table_new (g_str_hash, g_str_equal);

	/* FIXME: it would be better if we queue'd up the recursive
	 * scans till the end so that we can limit the number of
	 * directory descriptors open at any given time... */

	while ((dent = g_dir_read_name (dir))) {
		gchar *short_name, *full_name, *path, *ext;
		struct stat st;

		if (dent[0] == '.')
			continue;

		if (ignore_file (dent, FALSE))
			continue;

		path = g_strdup_printf ("%s/%s", root, dent);
		if (g_stat (path, &st) == -1) {
			g_free (path);
			continue;
		}
#ifndef G_OS_WIN32
		if (S_ISDIR (st.st_mode)) {
			struct _inode in = { st.st_dev, st.st_ino };

			if (g_hash_table_lookup (visited, &in)) {
				g_free (path);
				continue;
			}
		}
#endif
		short_name = g_strdup (dent);
		if ((ext = strrchr (short_name, '.')) && !strcmp (ext, ".sbd"))
			*ext = '\0';

		if (name != NULL)
			full_name = g_strdup_printf ("%s/%s", name, short_name);
		else
			full_name = g_strdup (short_name);

		if ((fi = g_hash_table_lookup (folder_hash, short_name)) != NULL) {
			g_free (short_name);
			g_free (full_name);

			if (S_ISDIR (st.st_mode)) {
				fi->flags = (fi->flags & ~CAMEL_FOLDER_NOCHILDREN) | CAMEL_FOLDER_CHILDREN;
			} else {
				fi->flags &= ~CAMEL_FOLDER_NOSELECT;
			}
		} else {
			fi = camel_folder_info_new ();
			fi->parent = parent;

			fi->full_name = full_name;
			fi->display_name = short_name;
			fi->unread = -1;
			fi->total = -1;

			if (S_ISDIR (st.st_mode))
				fi->flags = CAMEL_FOLDER_NOSELECT;
			else
				fi->flags = CAMEL_FOLDER_NOCHILDREN;

			if (tail == NULL)
				folders = fi;
			else
				tail->next = fi;

			tail = fi;

			g_hash_table_insert (folder_hash, fi->display_name, fi);
		}

		if (!S_ISDIR (st.st_mode)) {
			fill_fi (store, fi, flags);
		} else if ((flags & CAMEL_STORE_FOLDER_INFO_RECURSIVE)) {
			struct _inode in = { st.st_dev, st.st_ino };

			if (g_hash_table_lookup (visited, &in) == NULL) {
#ifndef G_OS_WIN32
				struct _inode *inew = g_new (struct _inode, 1);

				*inew = in;
				g_hash_table_insert (visited, inew, inew);
#endif
				if ((fi->child = scan_dir (store, visited, fi, path, fi->full_name, flags, error)))
					fi->flags |= CAMEL_FOLDER_CHILDREN;
				else
					fi->flags = (fi->flags & ~CAMEL_FOLDER_CHILDREN) | CAMEL_FOLDER_NOCHILDREN;
			}
		}

		g_free (path);
	}

	g_dir_close (dir);

	g_hash_table_destroy (folder_hash);

	return folders;
}