예제 #1
0
파일: log.c 프로젝트: mcr/Openswan
/* attempt to arrange a writeable parent directory for <path>
 * Result indicates success.  Failure will be logged.
 *
 * NOTE: this routine must not call our own logging facilities to report
 * an error since those routines are not re-entrant and such a call
 * would be recursive.
 */
static bool
ensure_writeable_parent_directory(char *path)
{
    /* NOTE: a / in the first char of a path is not like any other.
     * That is why the strchr starts at path + 1.
     */
    char *e = strrchr(path + 1, '/');	/* end of directory prefix */
    bool happy = TRUE;

    if (e != NULL)
    {
	/* path has an explicit directory prefix: deal with it */

	/* Treat a run of slashes as one.
	 * Remember that a / in the first char is different.
	 */
	while (e > path+1 && e[-1] == '/')
	    e--;

	*e = '\0';	/* carve off dirname part of path */

	if (access(path, W_OK) == 0)
	{
	    /* mission accomplished, with no work */
	}
	else if (errno != ENOENT)
	{
	    /* cannot write to this directory for some reason
	     * other than a missing directory
	     */
	    syslog(LOG_CRIT, "can not write to %s: %s", path, strerror(errno));
	    happy = FALSE;
	}
	else
	{
	    /* missing directory: try to create one */
	    happy = ensure_writeable_parent_directory(path);
	    if (happy)
	    {
		if (mkdir(path, 0750) != 0)
		{
		    syslog(LOG_CRIT, "can not create dir %s: %s"
			, path, strerror(errno));
		    happy = FALSE;
		}
	    }
	}

	*e = '/';	/* restore path to original form */
    }
    return happy;
}
예제 #2
0
파일: log.c 프로젝트: dotmark/libreswan
/* open the per-peer log
 *
 * NOTE: this routine must not call our own logging facilities to report
 * an error since those routines are not re-entrant and such a call
 * would be recursive.
 */
static void open_peerlog(struct connection *c)
{
	/* syslog(LOG_INFO, "opening log file for conn %s", c->name); */

	if (c->log_file_name == NULL) {
		char peername[ADDRTOT_BUF], dname[ADDRTOT_BUF];
		int peernamelen, lf_len;

		addrtot(&c->spd.that.host_addr, 'Q', peername,
			sizeof(peername));
		peernamelen = strlen(peername);

		/* copy IP address, turning : and . into / */
		{
			char ch, *p, *q;

			p = peername;
			q = dname;
			do {
				ch = *p++;
				if (ch == '.' || ch == ':')
					ch = '/';
				*q++ = ch;
			} while (ch != '\0');
		}

		lf_len = peernamelen * 2 +
			 strlen(base_perpeer_logdir) +
			 sizeof("//.log") +
			 1;
		c->log_file_name =
			alloc_bytes(lf_len, "per-peer log file name");

#if 0
		fprintf(stderr, "base dir |%s| dname |%s| peername |%s|",
			base_perpeer_logdir, dname, peername);
#endif
		snprintf(c->log_file_name, lf_len, "%s/%s/%s.log",
			 base_perpeer_logdir, dname, peername);

		/* syslog(LOG_DEBUG, "conn %s logfile is %s", c->name, c->log_file_name); */
	}

	/* now open the file, creating directories if necessary */

	c->log_file_err = !ensure_writeable_parent_directory(c->log_file_name);
	if (c->log_file_err)
		return;

	c->log_file = fopen(c->log_file_name, "w");
	if (c->log_file == NULL) {
		if (c->log_file_err) {
			syslog(LOG_CRIT, "logging system can not open %s: %s",
			       c->log_file_name, strerror(errno));
			c->log_file_err = TRUE;
		}
		return;
	}

	/* look for a connection to close! */
	while (perpeer_count >= MAX_PEERLOG_COUNT) {
		/* can not be NULL because perpeer_count > 0 */
		passert(perpeer_list.cqh_last != (void *)&perpeer_list);

		perpeer_logclose(perpeer_list.cqh_last);
	}

	/* insert this into the list */
	CIRCLEQ_INSERT_HEAD(&perpeer_list, c, log_link);
	passert(c->log_file != NULL);
	perpeer_count++;
}