コード例 #1
0
ファイル: log_info.c プロジェクト: BackupTheBerlios/samqfs
/*
 * get the status of all log and trace files in the SAM-FS configuration
 * This includes the Solaris system log, SAM system log, archiver logs,
 * device logs, releaser logs, stager logs, recycler logs, and daemon trace
 * status
 *
 * Return a list of formatted strings
 *
 * name=name,
 * type=Log/Trace,
 * state=on/off,
 * path=filename,
 * flags=flags,
 * size=size,
 * modtime=last modified time (num of seconds since 1970)
 */
int
get_logntrace(
	ctx_t *ctx, /* ARGSUSED */
	sqm_lst_t **lst	/* return - list of formatted strings */
)
{
	char *info = NULL;
	sqm_lst_t *lst_log = NULL;

	if (ISNULL(lst) || ((*lst = lst_create()) == NULL)) {
		return (-1);
	}

	if (get_daemontrace_info(&lst_log) == 0) {
		lst_concat(*lst, lst_log);
	}
	if (get_samlog_lst(&lst_log) == 0) {
		lst_concat(*lst, lst_log);
	}
	if (get_filestat(
	    SYSTEMLOG, SE_SOLARIS_SYSTEM_LOG_DESC, &info) == 0) {
		lst_append(*lst, info);
	}

	/* If QFS only install, do not display archive related logs */
	if (get_samfs_type(NULL) != QFS) {

		if (get_devlog_info(&lst_log) == 0) {
			lst_concat(*lst, lst_log);
		}
		if (get_recyclelog_info(&info) == 0) {
			lst_append(*lst, info);
		}
		if (get_archivelog_info(&lst_log) == 0) {
			lst_concat(*lst, lst_log);
		}
		if (get_releaselog_info(&lst_log) == 0) {
			lst_concat(*lst, lst_log);
		}
		if (get_stagelog_info(&info) == 0) {
			lst_append(*lst, info);
		}
		/*
		 * For now api_version 1.3.2, the restore log is hardcoded to
		 * RESTORELOG = /var/opt/SUNWsamfs/restore.log
		 */
		if (get_filestat(
		    RESTORELOG, SE_RESTORE_LOG_DESC, &info) == 0) {
			lst_append(*lst, info);
		}
	}
	return (0);

}
コード例 #2
0
ファイル: jni_util.c プロジェクト: BackupTheBerlios/samqfs
/*
 * convert a java array of className objects to a sqm_lst_t list.
 * each element is converted from Java to C using j2c function.
 */
sqm_lst_t *
jarray2lst(JNIEnv *env,
    jobjectArray jarr,
    char *className,
    void * (*j2c)(JNIEnv *, jobject)) {

	sqm_lst_t *lst;
	int idx, n;

	if (NULL == jarr) {
		PTRACE(1, "jni:NULL array passed to jarray2lst()");
		return (NULL);
	}
	n = (int)(*env)->GetArrayLength(env, jarr);
	PTRACE(2, "jni:jarray2lst(jarr[%d],%s)", n, className);
	lst = lst_create();

	for (idx = 0; idx < n; idx++)
		if (-1 == lst_append(lst,
		    j2c(env, (*env)->GetObjectArrayElement(env, jarr, idx)))) {
			lst_free(lst);
			lst = NULL;
			break;
		}

	PTRACE(2, "jni:jarray2lst() done");
	return (lst);
}
コード例 #3
0
ファイル: jni_util.c プロジェクト: BackupTheBerlios/samqfs
/*
 * convert a jintArray to a C list of int
 */
sqm_lst_t *
jintArray2lst(JNIEnv *env,
    jintArray jintArr) {

	sqm_lst_t *lst;
	int idx, len, *i;
	jint *p;

	if (NULL == jintArr) {
		PTRACE(1, "jni:NULL array passed to jintArray2lst()");
		return (NULL);
	}
	len = (int)(*env)->GetArrayLength(env, jintArr);
	p = (jint *) malloc(len * sizeof (jint));
	PTRACE(2, "jni:jintArray2lst(jintArr[%d])", len);
	lst = lst_create();

	(*env)->GetIntArrayRegion(env, jintArr, 0, len, p);

	for (idx = 0; idx < len; idx++) {
		i = (int *)malloc(sizeof (int));
		*i = (int)p[idx];
		if (-1 == lst_append(lst, i)) {
			lst_free(lst);
			lst = NULL;
			break;
		}
	}
	free(p);

	PTRACE(2, "jni:jintArray2lst() done");
	return (lst);

}
コード例 #4
0
ファイル: file_util.c プロジェクト: BackupTheBerlios/samqfs
/* Get details about a file. */
int
get_file_details(
	ctx_t *c,		/* ARGSUSED */
	char *fsname,
	sqm_lst_t *files,
	sqm_lst_t **status)
{
	int rval, mntfd;
	node_t *fil;
	char mountpt[MAXPATHLEN+1];
	char details[MAXPATHLEN+1];
	struct stat64 sout;
	char *filstat;

	if (strlen(fsname) != 0) {
		rval = getfsmountpt(fsname, mountpt, sizeof (mountpt));
		if (rval != 0) {
			return (rval);
		}
	} else {
		/* No FS specified, use root */
		strlcpy(mountpt, "/", sizeof (mountpt));
	}

	mntfd = open64(mountpt, O_RDONLY);
	if (mntfd < 0)
		return (samrerr(SE_NOT_A_DIR, mountpt));

	*status = lst_create();	/* Return results in this list */
	if (*status == NULL) {
		close(mntfd);
		return (-1);	/* If allocation failed, samerr is set */
	}

	fil = files->head;	/* Walk through list of files */
	while (fil != NULL) {

		memset(&sout, 0, sizeof (sout));
		rval = fstatat64(mntfd, fil->data, &sout, 0);
		if (rval) {
			filstat = copystr(""); /* File doesn't exist */
		} else {
			snprintf(
			    details, sizeof (details),
			    "size=%lld,created=%lu,modified=%lu",
			    sout.st_size, sout.st_ctim.tv_sec,
			    sout.st_mtim.tv_sec);
			filstat = copystr(details);
		}

		lst_append(*status, filstat);

		fil = fil->next; /* And check next file */
	}

	close(mntfd);
	return (0);
}
コード例 #5
0
ファイル: log_info.c プロジェクト: BackupTheBerlios/samqfs
/*
 * get trace information of all SAM-daemon trace files
 *
 * Returns a list of formatted strings
 *
 * name=name,
 * procname=process name,
 * type=Log/Trace,
 * state=on/off,
 * path=filename,
 * flags=flags,
 * size=size,
 * modtime=last modified time (num of seconds since 1970)
 *
 */
int
get_daemontrace_info(sqm_lst_t **lst_trace) {

	char buffer[BUFSIZ] = {0};
	int tid = 0;
	int chars = 0;
	struct stat statbuf;
	struct TraceCtlBin *tb = NULL;

	/*
	 * 1) Trace files
	 * attach to TraceCtl.bin.
	 * get the state(on/off), path, size and last modified time
	 */

	*lst_trace = lst_create();

	tb = MapFileAttach(TRACECTL_BIN, TRACECTL_MAGIC, O_RDONLY);
	for (tid = 1 /* starts with 1 */; (tb != NULL && tid < TI_MAX); tid++) {
		struct TraceCtlEntry *tc;
		tc = &tb->entry[tid];

		chars = snprintf(buffer, sizeof (buffer),
			"%s=%s, %s=%s, %s=%s",
			KEY_NAME, GetCustMsg(traceNames[tid].captionId),
			KEY_PROCNAME, traceNames[tid].processName,
			KEY_TYPE, GetCustMsg(SE_TYPE_TRACE));

		ADD_DELIM(chars, buffer);
		chars += snprintf(buffer + chars, sizeof (buffer) - chars,
			"%s=%s",
			KEY_STATE, (*tc->TrFname == '\0') ?
			STATE_OFF : STATE_ON);

		if (*tc->TrFname != '\0') {
			ADD_DELIM(chars, buffer);
			chars += snprintf(buffer + chars,
			sizeof (buffer) - chars,
				"%s=%s, %s=%s",
				KEY_PATH, tc->TrFname,
				KEY_FLAGS, TraceGetOptions(tc, NULL, 0));

			/* to get the modification time, stat the file */
			if (stat(tc->TrFname, &statbuf) == 0) {
				ADD_DELIM(chars, buffer);
				chars += snprintf(buffer + chars,
					sizeof (buffer) - chars,
					"%s=%ld, %s=%lu",
					KEY_SIZE, statbuf.st_size,
					KEY_MODTIME, statbuf.st_mtime);
			}
		}
		lst_append(*lst_trace, strdup(buffer));
	}
	return (0);
}
コード例 #6
0
int ConnectorAccept (ident_t ident, s_info * sub, c_tree * ct)
{
  Node newNode;
  GIV ans;

  ans.Ident = ident;
  ans.Reliability =
    GetItemInfo (ident, &ans.Value, &ans.ELRange, &ans.EHRange);
  SetGIV (&newNode, &ans);
  SetInfo (&newNode, sub);
  lst_append (ct, &newNode);
  return 1;
}
コード例 #7
0
ファイル: job_control.c プロジェクト: BackupTheBerlios/samqfs
int
list_activities(
	ctx_t *c,		/* ARGSUSED */
	int maxentries,		/* Maximum number of strings to return */
	char *rest,		/* fnmatch pattern to exclude returns */
	sqm_lst_t **activities)	/* Returned list of descriptor strings */
{
	samrthread_t *ptr;
	char *bufptr;
	int rval;
	sqm_lst_t *l;
	char restrictions[MAXPATHLEN];


	/* Fully wild-card selector */
	if (rest != NULL)
		snprintf(restrictions, MAXPATHLEN, "*%s*", rest);
	else
		strlcpy(restrictions, "*", MAXPATHLEN);

	*activities = lst_create();
	pthread_mutex_lock(samrlock); /* ++ LOCK samrtlist */

	ptr = samrtlist;
	while ((ptr != NULL) && ((*activities)->length < maxentries)) {
		rval = ptr->details(ptr, &bufptr); /* Ask about a task */
		if (rval == 0) {
			if (fnmatch(restrictions, bufptr, 0))
				free(bufptr); /* Doesn't match */
			else
				lst_append(*activities, bufptr);
		}
		ptr = ptr->next;
	}
	pthread_mutex_unlock(samrlock); /* ++ UNLOCK samrtlist */

	/* get and append process jobs that match the restrictions */
	if (get_process_jobs(NULL, rest, &l) != 0) {
		return (-1);
	} else if (l->length != 0) {
		if (lst_concat(*activities, l) != 0) {
			return (-1);
		}
	}

	return (0);
}
コード例 #8
0
/*
 *  Message handler for ReadCfg module.
 */
static void
read_cfg_msg(
char *msg,	/* error message */
int lineno,	/* line number of error */
char *line)	/* text of line in diskvols.conf */
{

	parsing_error_t *err;

	if (line != NULL) {

		if (msg != NULL) {
			/*
			 * Error message.
			 */
			Trace(TR_OPRMSG, "diskvols.conf error %d: %s %s",
			    lineno, line, msg);
			err = (parsing_error_t *)malloc(
			    sizeof (parsing_error_t));
			strlcpy(err->input, line, sizeof (err->input));
			strlcpy(err->msg, msg, sizeof (err->msg));
			err->line_num = lineno;
			err->error_type = ERROR;
			err->severity = 1;
			lst_append(error_list, err);
		}
	} else if (lineno == 0) {
		Trace(TR_OPRMSG, "diskvols.conf file is empty");
		empty_cmd_file = B_TRUE;
	} else if (lineno < 0) {

		/*
		 * Missing command file is not an error.
		 */
		if (errno == ENOENT) {
			no_cmd_file = B_TRUE;
			*open_error = '\0';
		} else {
			no_cmd_file = B_FALSE;
			snprintf(open_error, sizeof (open_error), msg);
			Trace(TR_OPRMSG, "diskvols.conf open error %s",
			    open_error);
		}
	}

}
コード例 #9
0
/*
 *	Process clients.
 */
static void
procClients(void)
{

	char *cl;

	Trace(TR_OPRMSG, "processing client %s", Str(dir_name));

	cl = (char *)mallocer(sizeof (host_t));
	if (cl == NULL) {
		ReadCfgError(samerrno);
	}
	snprintf(cl, sizeof (host_t), dir_name);
	if (lst_append(dv_cfg->client_list, cl) != 0) {
		free(cl);
		ReadCfgError(samerrno);
	}

	Trace(TR_OPRMSG, "processed client");
}
コード例 #10
0
ファイル: file_util.c プロジェクト: BackupTheBerlios/samqfs
int
get_file_status(
	ctx_t *c,		/* ARGSUSED */
	sqm_lst_t *filepaths,
	sqm_lst_t **filestatus)
{
	int rval = 0;
	int filestat;
	node_t *node;
	struct stat64 sout;	/* Buffer to receive file status */


	*filestatus = lst_create(); /* Return results in this list */
	if (*filestatus == NULL)
		return (-1);	/* samerr is already set */

	node = filepaths->head;
	while (node != NULL) {
		if (stat64(node->data, &sout)) { /* Ask about a file */
			filestat = SAMR_MISSING; /* File doesn't even exist */
		} else if ((sout.st_mode & S_IFMT) == S_IFDIR) {
			filestat = SAMR_DIRFILE; /* This is a directory */
		} else if ((sout.st_mode & S_IFMT) == S_IFREG) {
			if (sout.st_size && (sout.st_blocks == 0))
				filestat = SAMR_RELFILE; /* File not on disk */
			else
				filestat = SAMR_REGFILE; /* Is file, on disk */
		} else {
			filestat = SAMR_NOTFILE; /* Neither file nor dir. */
		}
		rval = lst_append(*filestatus, copyint(filestat));
		if (rval)
			break;
		node = node->next;
	}
	if (rval)
		lst_free_deep(*filestatus);
	return (rval);
}
コード例 #11
0
ファイル: releaser.c プロジェクト: BackupTheBerlios/samqfs
/*
 * functions to get a fs list which is doing release job.
 * the list is a list of structure release_fs_t;
 */
int
get_releasing_fs_list(
ctx_t *ctx,			/* ARGSUSED */
sqm_lst_t **releasing_fs_list)	/* a list of release_fs_t, */
				/* must be freed by caller */
{
	int numfs;		/* Number of filesystems */
	struct sam_fs_info   *finfo = NULL;
	struct sam_fs_status *fsarray;
	release_fs_t *rel_fs;
	int 	i;

	Trace(TR_MISC, "getting releasing file system");
	if ((numfs = GetFsStatus(&fsarray)) == -1) {
		samerrno = SE_GET_FS_STATUS_FAILED;
		snprintf(samerrmsg, MAX_MSG_LEN, GetCustMsg(samerrno));
		Trace(TR_ERR, "%s", samerrmsg);
	/*
	 *	returns -2.
	 */
		*releasing_fs_list = lst_create();
		if (*releasing_fs_list == NULL) {
			Trace(TR_ERR, "%s", samerrmsg);
			return (-1);
		}
		return (-2);
	}

	if (finfo != NULL) {
		free(finfo);
	}
	finfo = (struct sam_fs_info *)
	    mallocer(numfs * sizeof (struct sam_fs_info));
	if (finfo == NULL) {
		Trace(TR_ERR, "%s", samerrmsg);
		goto error;
	}


	for (i = 0; i < numfs; i++) {
		struct sam_fs_status *fs;
		struct sam_fs_info *fi;

		fs = fsarray + i;
		fi = finfo + i;
		if (GetFsInfo(fs->fs_name, fi) == -1) {
			samerrno = SE_GET_FS_INFO_FAILED;
			snprintf(samerrmsg, MAX_MSG_LEN,
			    GetCustMsg(samerrno), fs->fs_name);
			Trace(TR_ERR, "%s", samerrmsg);
			goto error;
		}
		if (!(fi->fi_status & FS_MOUNTED)) {
			continue;
		}
	}
	free(fsarray);
	*releasing_fs_list = lst_create();
	if (*releasing_fs_list == NULL) {
		Trace(TR_ERR, "%s", samerrmsg);
		goto error;
	}

	for (i = 0; i < numfs; i++) {
		struct	sam_fs_info *fi;
		int	pct;		/* Disk free space percentage */

		fi = finfo + i;
		if (!(fi->fi_status & FS_MOUNTED)) {
			continue;
		}
		if (fi->fi_status & FS_RELEASING) {
			rel_fs = (release_fs_t *)
			    mallocer(numfs * sizeof (release_fs_t));
			if (rel_fs == NULL) {
				Trace(TR_ERR, "%s", samerrmsg);
				lst_free_deep(*releasing_fs_list);
				*releasing_fs_list = NULL;
				return (-1);
			}
			strlcpy(rel_fs->fi_name, fi->fi_name,
			    sizeof (rel_fs->fi_name));
			pct = llpercent_used(fi->fi_capacity, fi->fi_space);
			rel_fs->used_pct = 100 - pct;
			rel_fs->fi_low = fi->fi_low;
			if (lst_append(*releasing_fs_list, rel_fs) == -1) {
				free(rel_fs);
				lst_free_deep(*releasing_fs_list);
				Trace(TR_ERR, "%s", samerrmsg);
				*releasing_fs_list = NULL;
				return (-1);
			}
		}
	}
	if (finfo) {
		free(finfo);
	}
	Trace(TR_MISC, "finished getting releasing file system");
	return (0);
error:
	if (fsarray) {
		free(fsarray);
	}
	if (finfo) {
		free(finfo);
	}
	return (-1);
}
コード例 #12
0
ファイル: proc.c プロジェクト: mycoboco/beluga
/*
 *  preprocesses input tokens to form the output list
 */
void (proc_prep)(void)
{
    lex_t *t = lst_nexti();

    while (1) {
        switch(state) {
            case SINIT:
            case SAFTRNL:
                while (1) {
                    SKIPSP(t);
                    switch(t->id) {
                        case LEX_NEWLINE:
                            lst_flush(1);
                            t = lst_nexti();
                            continue;
                        case LEX_SHARP:
                            state++;
                            assert(state == SIDIREC || state == SDIREC);
                            lex_direc = 1;
                            goto loop;
                        default:
                            state = SNORM;
                            goto loop;
                        case LEX_EOI:
                            if (mg_state == MG_SENDIF && state == SINIT)
                                mg_once();
                            cond_finalize();
                            if (inc_isffile()) {
                                lst_flush(1);
                                return;
                            }
                            if (main_opt()->pponly) {
                                lex_t *u = lst_copy(t, 0, strg_line);
                                u->id = LEX_NEWLINE;
                                u->f.sync = 2;
                                u = lst_append(u, lex_make(0, NULL, 0));
                                lst_output(u);
                                lst_discard(1);    /* discards EOI */
                                in_switch(NULL, 0);    /* pop */
                                t = lst_nexti();
                                u->pos = t->pos;
                            } else {
                                lst_discard(1);    /* discards EOI */
                                in_switch(NULL, 0);    /* pop */
                                t = lst_nexti();
                            }
                            setdirecst(t);
                            assert(state == SAFTRNL || state == SINIT);
                            goto loop;
                    }
                }
                /* assert(!"impossible control flow - should never reach here");
                   break; */
            case SIDIREC:
            case SDIREC:
                directive(t);
                t = lst_nexti();    /* token after newline */
                setdirecst(t);
                break;
            case SNORM:
                while (t->id != LEX_NEWLINE) {
                    assert(t->id != LEX_EOI);
                    if (t->id == LEX_ID && !t->f.blue)
                        mcr_expand(t);
                    t = lst_nexti();
                }
                lst_flush(1);
                state = SAFTRNL;
                return;    /* at least newline flushed */
            case SIGN:
                do {
                    SKIPSP(t);
                    if (t->id == LEX_SHARP) {
                        state = SDIREC;
                        lex_direc = 1;
                        goto loop;
                    }
                    SKIPNL(t);
                    t = lst_nexti();
                } while(t->id != LEX_EOI);
                state = SAFTRNL;
                break;
            default:
                assert(!"invalid state -- should never reach here");
                break;
        }
        loop:
            ;
    }
}
コード例 #13
0
ファイル: clx.c プロジェクト: mycoboco/beluga
/*
 *  recognizes character constants;
 *  ASSUMPTION: signed/unsigned integers are compatible on the host
 */
ux_t (clx_ccon)(lex_t *t, int *w)
{
    int cbyte;
    sz_t len = 0;
    const char *ss, *s, *e;
    ux_t lim, c;
#ifdef HAVE_ICONV
    iconv_t *cd;
#endif    /* HAVE_ICONV */

    assert(t);
    assert(w);
    assert(BUFUNIT > 2);
    assert(ty_wuchartype);    /* ensures types initialized */
    assert(xgeu(xmxu, TG_UCHAR_MAX));
    assert(xgeu(xmxu, TG_WUCHAR_MAX));
    assert(ir_cur);

    ss = s = LEX_SPELL(t);
    if (*s == 'L')
        *w = 1, s++;
    e = ++s;    /* skips ' */

    if (*w) {
        cbyte = ty_wchartype->size;
        assert(cbyte <= BUFUNIT);
        lim = TG_WUCHAR_MAX;
#ifdef HAVE_ICONV
        cd = main_ntow;
#endif    /* HAVE_ICONV */
    } else {
        cbyte = 1;
        lim = TG_UCHAR_MAX;
#ifdef HAVE_ICONV
        cd = main_ntoe;
#endif    /* HAVE_ICONV */
    }

    switch(*e) {
        case '\'':    /* empty; diagnosed elsewhere */
        case '\0':    /* unclosed; diagnosed elsewhere */
            return xO;
        case '\\':    /* escape sequences */
            assert(sizeof(c) >= cbyte);
            c = lex_bs(t, ss, &e, lim, "character constant");
#if HAVE_ICONV
            if (cd && !(s[1] == 'x' || (s[1] >= '0' && s[1] <= '7'))) {
                char x = xnu(c);
                ICONV_DECL(&x, 1);
                assert(xe(xiu(x), c));
                obuf = strg_sbuf, obufv = strg_sbuf;
                olen = strg_slen, olenv = strg_slen;
                ICONV_DO(cd, 1, {});
                strg_sbuf = obuf, strg_slen = olen;    /* for later reuse */
                len = strg_slen - len - olenv;
            } else {
#else    /* !HAVE_ICONV */
            {
#endif    /* HAVE_ICONV */
                if (*w)
                    memcpy(strg_sbuf, (char *)&c + ((LITTLE)? 0: sizeof(c)-cbyte), cbyte);
                else
                    strg_sbuf[0] = xnu(c);
                len = cbyte;
            }
            break;
        default:    /* ordinary chars */
#ifdef HAVE_ICONV
            if (cd) {
                do {
                    e++;
                } while(!FIRSTUTF8(*e));
                {
                    ICONV_DECL((char *)s, e - s);
                    obuf = strg_sbuf, obufv = strg_sbuf;
                    olen = strg_slen, olenv = strg_slen;
                    ICONV_DO(cd, 1, {});
                    strg_sbuf = obuf, strg_slen = olen;    /* for later reuse */
                    len = strg_slen - len - olenv;
                }
            } else {
#else    /* !HAVE_ICONV */
            {
#endif    /* HAVE_ICONV */
                assert(TG_CHAR_BIT == CHAR_BIT);
                if (*w) {
                    strg_sbuf[(LITTLE)? 0: cbyte-1] = *e;
                    memset(strg_sbuf + ((LITTLE)? 1: 0), 0, cbyte-1);
                } else
                    strg_sbuf[0] = *e;
                e++;
                len = cbyte;
            }
            break;
    }

    if (*e != '\'' && *e != '\0') {
        for (s = e; *e != '\0' && *e != '\''; e++)
            continue;
        err_dpos((FIRSTUTF8(*s))? lmap_spell(t, ss, s, e): t->pos, ERR_CONST_LARGECHAR);
    } else if (len != cbyte) {
        err_dpos(t->pos, (*w)? ERR_CONST_WIDENOTFIT: ERR_CONST_MBNOTFIT);
        return xO;
    }

    c = xO;
    memcpy(&c, strg_sbuf + ((LITTLE)? 0: sizeof(c)-cbyte), cbyte);
    if (*w) {
        switch(main_opt()->wchart) {
            case 0:    /* long */
                c = SYM_CROPSL(c);
                break;
            case 1:    /* ushort */
                c = SYM_CROPUS(c);
                break;
            case 2:    /* int */
                c = SYM_CROPSI(c);
                break;
        }
    } else    /* int from char */
        c = (main_opt()->uchar)? SYM_CROPUC(c): SYM_CROPSC(c);

    return c;
}


/*
 *  recognizes string literals
 */
static sz_t scon(lex_t *t, int *w)
{
    int cbyte;
    lex_t *n;
    sz_t clen = 0, len = 0;
    const char *ss, *s, *e;
    ux_t lim;
#ifdef HAVE_ICONV
    iconv_t *cd;
#endif

    assert(t);
    assert(w);
    assert(BUFUNIT > 2);
    assert(ty_wuchartype);    /* ensures types initialized */
    assert(xgeu(xmxu, TG_UCHAR_MAX));
    assert(xgeu(xmxu, TG_WUCHAR_MAX));
    assert(ir_cur);

    ss = s = LEX_SPELL(t);
    if (*s == 'L')
        *w = 1, s++;
    e = ++s;    /* skips " */
    while ((n = lst_peekns())->id == LEX_SCON) {
        if (*n->spell == 'L') {
            if (!*w) {    /* mb + wide = wide */
                err_dmpos(n->pos, ERR_CONST_MBWIDE, t->pos, NULL);
                err_dmpos(n->pos, ERR_CONST_MBWIDESTD, t->pos, NULL);
                *w = 2;    /* silences warnings */
            }
        } else if (*w == 1) {    /* wide + mb = wide */
            err_dmpos(n->pos, ERR_CONST_MBWIDE, t->pos, NULL);
            err_dmpos(n->pos, ERR_CONST_MBWIDESTD, t->pos, NULL);
            *w = 2;    /* silences warnings */
        }
        while ((t = lst_append(t, lst_next()))->id != LEX_SCON)
            continue;
    }
    clx_cpos = lmap_range(t->next->pos, t->pos);

    if (*w) {
        cbyte = ty_wchartype->size;
        assert(cbyte <= BUFUNIT);
        lim = TG_WUCHAR_MAX;
#ifdef HAVE_ICONV
        cd = main_ntow;
#endif    /* HAVE_ICONV */
    } else {
        cbyte = 1;
        lim = TG_UCHAR_MAX;
#ifdef HAVE_ICONV
        cd = main_ntoe;
#endif    /* HAVE_ICONV */
    }

    n = t->next;
    while (1) {
        while (1) {
            while (*e != '\\' && *e != '"' && *e != '\0')
                e++;
            if (e > s) {    /* ordinary chars */
#ifdef HAVE_ICONV
                if (cd) {
                    ICONV_DECL((char *)s, e - s);
                    obuf = strg_sbuf, obufv = strg_sbuf + len;
                    olen = strg_slen, olenv = strg_slen - len;
                    ICONV_INIT(cd);
                    ICONV_DO(cd, 0, {});
                    strg_sbuf = obuf, strg_slen = olen;    /* for later reuse */
                    len += (strg_slen - len - olenv);
                } else {
#else    /* !HAVE_ICONV */
                {
#endif    /* HAVE_ICONV */
                    sz_t d = e - s;
                    assert(TG_CHAR_BIT == CHAR_BIT);
                    while (len + (d*cbyte) > strg_slen)    /* rarely iterates */
                        MEM_RESIZE(strg_sbuf, strg_slen += BUFUNIT);
                    if (*w) {
                        while (s < e) {
                            strg_sbuf[len + ((ir_cur->f.little_endian)? 0: cbyte-1)] = *s++;
                            memset(strg_sbuf + len + ((ir_cur->f.little_endian)? 1: 0), 0,
                                   cbyte-1);
                            len += cbyte;
                        }
                    } else {
                        memcpy(&strg_sbuf[len], s, d);
                        len += d;
                    }
                }
                for (; s < e; s++)
                    if (FIRSTUTF8(*s))
                        clen++;
            }
            if (*e == '\\') {    /* escape sequences */
                ux_t c;
                assert(sizeof(c) >= cbyte);
                c = lex_bs(n, ss, &e, lim, "string literal");
#if HAVE_ICONV
                if (cd) {    /* inserts initial seq before every esc seq */
                    ICONV_DECL(NULL, 0);
                    UNUSED(ilenv);
                    UNUSED(ibufv);
                    obuf = strg_sbuf, obufv = strg_sbuf + len;
                    olen = strg_slen, olenv = strg_slen - len;
                    ICONV_INIT(cd);
                    strg_sbuf = obuf, strg_slen = olen;    /* for later reuse */
                    len += (strg_slen - len - olenv);
                }
                if (cd && !(s[1] == 'x' || (s[1] >= '0' && s[1] <= '7'))) {
                    char x = xnu(c);
                    ICONV_DECL(&x, 1);
                    assert(xe(xiu(x), c));
                    obuf = strg_sbuf, obufv = strg_sbuf + len;
                    olen = strg_slen, olenv = strg_slen - len;
                    ICONV_DO(cd, 0, {});
                    strg_sbuf = obuf, strg_slen = olen;    /* for later reuse */
                    len += (strg_slen - len - olenv);
                } else {
#else    /* !HAVE_ICONV */
                {
#endif    /* HAVE_ICONV */
                    if (len + cbyte > strg_slen)
                        MEM_RESIZE(strg_sbuf, strg_slen += BUFUNIT);
                    if (*w) {
                        if (LITTLE != ir_cur->f.little_endian)
                            CHGENDIAN(c, sizeof(c));
                        memcpy(strg_sbuf+len,
                               &c + ((ir_cur->f.little_endian)? 0: sizeof(c)-cbyte), cbyte);
                        len += cbyte;
                    } else
                        strg_sbuf[len++] = xnu(c);
                }
                clen++;
                s = e;
                continue;
            }
            break;    /* " or NUL */
        }
        if (n == t) {
            if (len + cbyte > strg_slen)
                MEM_RESIZE(strg_sbuf, strg_slen += BUFUNIT);
            memset(strg_sbuf+len, 0, cbyte);
            len += cbyte;
            clen++;
            break;
        }
        while ((n = n->next)->id != LEX_SCON)
            if (n->id < 0)
                strg_free((arena_t *)n->spell);
        ss = s = LEX_SPELL(n);
        if (*s == 'L')
            s++;
        e = ++s;    /* skips " */
    }

    if (len % cbyte != 0)
        err_dpos(clx_cpos, ERR_CONST_WIDENOTFIT);
    if (*w)
        clen = (len /= cbyte);

    if (clen - 1 > TL_STR_STD) {    /* -1 for NUL; note TL_STR_STD may warp around */
        err_dpos(clx_cpos, ERR_CONST_LONGSTR);
        err_dpos(clx_cpos, ERR_CONST_LONGSTRSTD, (unsigned long)TL_STR_STD);
    }

    return len;
}


#define N 0    /* no suffix */
#define U 1    /* suffix: U */
#define L 2    /* suffix: L */
#define X 3    /* suffix: UL */
#ifdef SUPPORT_LL
#define M 4    /* suffix: LL */
#define Z 5    /* suffix: ULL */
#endif    /* SUPPORT_LL */
#define D 0    /* base: decimal */
#define H 1    /* base: octal or hexadecimal */

/*
 *  determines the type of an integer constant
 */
static const char *icon(const char *cs, ux_t n, int ovf, int base, const lmap_t *pos)
{
    static struct tab {
        ux_t limit;
        ty_t *type;
#ifdef SUPPORT_LL
    } tab[Z+1][H+1][7];
#else    /* !SUPPORT_LL */
    } tab[X+1][H+1][5];
#endif    /* SUPPORT_LL */

    int suffix;
    struct tab *p;

    assert(cs);
    assert(pos);
    assert(ty_inttype);
#ifdef SUPPORT_LL
    assert(xgeu(xmxu, TG_ULLONG_MAX));
#else    /* !SUPPORT_LL */
    assert(xgeu(xmxu, TG_ULONG_MAX));
#endif    /* SUPPORT_LL */

    if (xe(tab[N][D][0].limit, xO)) {
        /* no suffix, decimal; different in C90 */
        tab[N][D][0].limit = TG_INT_MAX;
        tab[N][D][0].type  = ty_inttype;
        tab[N][D][1].limit = TG_LONG_MAX;
        tab[N][D][1].type  = ty_longtype;
#ifdef SUPPORT_LL
        tab[N][D][2].limit = TG_LLONG_MAX;
        tab[N][D][2].type  = ty_llongtype;
        tab[N][D][3].limit = TG_ULLONG_MAX;
        tab[N][D][3].type  = ty_ullongtype;
        tab[N][D][4].limit = xmxu;
        tab[N][D][4].type  = ty_inttype;
#else    /* SUPPORT_LL */
        tab[N][D][2].limit = TG_ULONG_MAX;
        tab[N][D][2].type  = ty_ulongtype;
        tab[N][D][3].limit = xmxu;
        tab[N][D][3].type  = ty_inttype;
#endif    /* SUPPORT_LL */

        /* no suffix, octal or hex */
        tab[N][H][0].limit = TG_INT_MAX;
        tab[N][H][0].type  = ty_inttype;
        tab[N][H][1].limit = TG_UINT_MAX;
        tab[N][H][1].type  = ty_unsignedtype;
        tab[N][H][2].limit = TG_LONG_MAX;
        tab[N][H][2].type  = ty_longtype;
        tab[N][H][3].limit = TG_ULONG_MAX;
        tab[N][H][3].type  = ty_ulongtype;
#ifdef SUPPORT_LL
        tab[N][H][4].limit = TG_LLONG_MAX;
        tab[N][H][4].type  = ty_llongtype;
        tab[N][H][5].limit = TG_ULLONG_MAX;
        tab[N][H][5].type  = ty_ullongtype;
        tab[N][H][6].limit = xmxu;
        tab[N][H][6].type  = ty_inttype;
#else    /* !SUPPORT_LL */
        tab[N][H][4].limit = xmxu;
        tab[N][H][4].type  = ty_inttype;
#endif    /* SUPPORT_LL */

        /* U, decimal, octal or hex */
        tab[U][H][0].limit = tab[U][D][0].limit = TG_UINT_MAX;
        tab[U][H][0].type  = tab[U][D][0].type  = ty_unsignedtype;
        tab[U][H][1].limit = tab[U][D][1].limit = TG_ULONG_MAX;
        tab[U][H][1].type  = tab[U][D][1].type  = ty_ulongtype;
#ifdef SUPPORT_LL
        tab[U][H][2].limit = tab[U][D][2].limit = TG_ULLONG_MAX;
        tab[U][H][2].type  = tab[U][D][2].type  = ty_ullongtype;
        tab[U][H][3].limit = tab[U][D][3].limit = xmxu;
        tab[U][H][3].type  = tab[U][D][3].type  = ty_inttype;
#else    /* !SUPPORT_LL */
        tab[U][H][2].limit = tab[U][D][2].limit = xmxu;
        tab[U][H][2].type  = tab[U][D][2].type  = ty_inttype;
#endif    /* SUPPORT_LL */

        /* L, decimal; different in C90 */
        tab[L][D][0].limit = TG_LONG_MAX;
        tab[L][D][0].type  = ty_longtype;
#ifdef SUPPORT_LL
        tab[L][D][1].limit = TG_LLONG_MAX;
        tab[L][D][1].type  = ty_llongtype;
        tab[L][D][2].limit = TG_ULLONG_MAX;
        tab[L][D][2].type  = ty_ullongtype;
        tab[L][D][3].limit = xmxu;
        tab[L][D][3].type  = ty_inttype;
#else    /* !SUPPORT_LL */
        tab[L][D][1].limit = TG_ULONG_MAX;
        tab[L][D][1].type  = ty_ulongtype;
        tab[L][D][2].limit = xmxu;
        tab[L][D][2].type  = ty_inttype;
#endif    /* SUPPORT_LL */

        /* L, octal or hex */
        tab[L][H][0].limit = TG_LONG_MAX;
        tab[L][H][0].type  = ty_longtype;
        tab[L][H][1].limit = TG_ULONG_MAX;
        tab[L][H][1].type  = ty_ulongtype;
#ifdef SUPPORT_LL
        tab[L][H][2].limit = TG_LLONG_MAX;
        tab[L][H][2].type  = ty_llongtype;
        tab[L][H][3].limit = TG_ULLONG_MAX;
        tab[L][H][3].type  = ty_ullongtype;
        tab[L][H][4].limit = xmxu;
        tab[L][H][4].type  = ty_inttype;
#else    /* !SUPPORT_LL */
        tab[L][H][2].limit = xmxu;
        tab[L][H][2].type  = ty_inttype;
#endif    /* SUPPORT_LL */

        /* UL, decimal, octal or hex */
        tab[X][H][0].limit = tab[X][D][0].limit = TG_ULONG_MAX;
        tab[X][H][0].type  = tab[X][D][0].type  = ty_ulongtype;
#ifdef SUPPORT_LL
        tab[X][H][1].limit = tab[X][D][1].limit = TG_ULLONG_MAX;
        tab[X][H][1].type  = tab[X][D][1].type  = ty_ullongtype;
        tab[X][H][2].limit = tab[X][D][2].limit = xmxu;
        tab[X][H][2].type  = tab[X][D][2].type  = ty_inttype;
#else    /* !SUPPORT_LL */
        tab[X][H][1].limit = tab[X][D][1].limit = xmxu;
        tab[X][H][1].type  = tab[X][D][1].type  = ty_inttype;
#endif    /* SUPPORT_LL */

#ifdef SUPPORT_LL
        /* LL, decimal, octal or hex */
        tab[M][H][0].limit = tab[M][D][0].limit = TG_LLONG_MAX;
        tab[M][H][0].type  = tab[M][D][0].type  = ty_llongtype;
        tab[M][H][1].limit = tab[M][D][1].limit = TG_ULLONG_MAX;
        tab[M][H][1].type  = tab[M][D][1].type  = ty_ullongtype;
        tab[M][H][2].limit = tab[M][D][2].limit = xmxu;
        tab[M][H][2].type  = tab[M][D][2].type  = ty_inttype;

        /* ULL, decimal, octal or hex */
        tab[Z][H][0].limit = tab[Z][D][0].limit = TG_ULLONG_MAX;
        tab[Z][H][0].type  = tab[Z][D][0].type  = ty_ullongtype;
        tab[Z][H][1].limit = tab[Z][D][1].limit = xmxu;
        tab[Z][H][1].type  = tab[Z][D][1].type  = ty_inttype;
#endif    /* SUPPORT_LL */
    }

    base = (base == 10)? D: H;
    suffix = N;

    if (tolower((unsigned char)cs[0]) == 'l') {
#ifdef SUPPORT_LL
        if (cs[1] == cs[0])
            cs += 2, suffix = M;
        else
#endif    /* SUPPORT_LL */
            cs++, suffix = L;
    }
    if (tolower((unsigned char)cs[0]) == 'u')
        cs++, suffix++;
    if (suffix <= U && tolower((unsigned char)cs[0]) == 'l') {
#ifdef SUPPORT_LL
        if (cs[1] == cs[0])
            cs += 2, suffix += M;
        else
#endif    /* SUPPORT_LL */
            cs++, suffix += L;
    }

    for (p = tab[suffix][base]; xgu(n, p->limit); p++)
        continue;
    if (ovf || (xe(p->limit, xmxu) && p->type == ty_inttype)) {
        err_dpos(pos, ERR_CONST_LARGEINT);
#ifdef SUPPORT_LL
        n = TG_ULLONG_MAX;
        tval.type = ty_ullongtype;
#else    /* !SUPPORT_LL */
        n = TG_ULONG_MAX;
        tval.type = ty_ulongtype;
#endif    /* SUPPORT_LL */
    } else
        tval.type = p->type;

#ifdef SUPPORT_LL
    if (suffix % 2 == 0 && base == D && TY_ISUNSIGN(p->type))
        err_dpos(pos, ERR_CONST_LARGEUNSIGN);
    else if (tval.type == ty_llongtype && (suffix == N || suffix == L) && xleu(n, TG_ULONG_MAX)) {
        err_dpos(pos, ERR_CONST_UNSIGNINC90);
        if (main_opt()->std == 1)
            tval.type = ty_ulongtype;
    }
    if ((TY_ISLLONG(tval.type) || TY_ISULLONG(tval.type)))
        err_dpos(pos, ERR_CONST_LLONGINC90, tval.type);
#endif    /* SUPPORT_LL */

#ifdef SUPPORT_LL
    if (tval.type->op == TY_INT || tval.type->op == TY_LONG || tval.type->op == TY_LLONG)
#else    /* !SUPPORT_LL */
    if (tval.type->op == TY_INT || tval.type->op == TY_LONG)
#endif    /* SUPPORT_LL */
        tval.u.c.v.s = n;
    else
        tval.u.c.v.u = n;

    return cs;
}

#undef H
#undef D
#undef Z
#undef M
#undef X
#undef L
#undef U
#undef N


/*
 *  determines the type of a floating constant;
 *  ASSUMPTION: fp types of the host are same as those of the target
 */
static const char *fcon(const char *cs, long double ld, const lmap_t *pos)
{
    assert(cs);
    assert(pos);
    assert(ty_floattype);    /* ensures types initiailized */

    switch(*cs) {
        case 'f':
        case 'F':
            cs++;    /* skips f or F */
            if ((OVF(ld) && errno == ERANGE) || ld > TG_FLT_MAX) {
                err_dpos(pos, ERR_CONST_LARGEFP);
                ld = TG_FLT_MAX;
            } else if ((ld == 0.0 && errno == ERANGE) || (ld > 0.0 && ld < TG_FLT_MIN)) {
                err_dpos(pos, ERR_CONST_TRUNCFP);
                ld = 0.0f;
            }
            tval.type = ty_floattype;
            tval.u.c.v.f = (float)ld;
            break;
        case 'l':
        case 'L':
            cs++;    /* skips l or L */
            if ((OVF(ld) && errno == ERANGE) || ld > TG_LDBL_MAX) {
                err_dpos(pos, ERR_CONST_LARGEFP);
                ld = TG_LDBL_MAX;
            } else if ((ld == 0.0 && errno == ERANGE) || (ld > 0.0 && ld < TG_LDBL_MIN))
                err_dpos(pos, ERR_CONST_TRUNCFP);
            tval.type = ty_ldoubletype;
            tval.u.c.v.ld = (long double)ld;
            break;
        default:
            if ((OVF(ld) && errno == ERANGE) || ld > TG_DBL_MAX) {
                err_dpos(pos, ERR_CONST_LARGEFP);
                ld = (double)TG_DBL_MAX;
            } else if ((ld == 0.0 && errno == ERANGE) || (ld > 0.0 && ld < TG_DBL_MIN)) {
                err_dpos(pos, ERR_CONST_TRUNCFP);
                ld = 0.0;
            }
            tval.type = ty_doubletype;
            tval.u.c.v.d = (double)ld;
            break;
    }

    return cs;
}


/*
 *  recognizes integer or floating constants;
 *  ASSUMPTION: strtold() supported on the host
 */
static int ifcon(lex_t *t)
{
    ux_t n;
    int b, d;
    long double ld;
    int err = 0, ovf = 0;
    const char *ss, *s;
    char *p = "0123456789abcdef";    /* no const for reuse with strtold() */

    assert(t);

    ss = s = LEX_SPELL(t);

    if (*s == '.')
        goto fcon;
    n = xO;
    if (s[0] == '0' && (s[1] == 'x' || s[1] == 'X') &&
        isxdigit(((unsigned char *)s)[2])) {    /* 0x[0-9] */
        b = 16;
        s++;    /* skips 0 */
        while (isxdigit(*(unsigned char *)++s)) {
            d = strchr(p, tolower(*(unsigned char *)s)) - p;
            if (xt(xba(n, xbc(xsrl(xmxu, 4)))))
                ovf = 1;
            n = xau(xsl(n, 4), xiu(d));
        }
        s = icon(s, n, ovf, b, t->pos);
        b = LEX_ICON;
    } else {    /* 0 or other digits */
        b = (*s == '0')? 8: 10;
        if (b == 8)
            while (isdigit(*(unsigned char *)s)) {
                d = *s++ - '0';
                if (*s == '8' || *s == '9')
                    p = (char *)s, err = 1;
                if (xt(xba(n, xbc(xsrl(xmxu, 3)))))
                    ovf = 1;
                n = xau(xsl(n, 3), xiu(d));
            }
        else    /* b == 10 */
            while (isdigit(*(unsigned char *)s)) {
                d = *s++ - '0';
                if (xgu(n, xdu(xsu(xmxu, xiu(d)), xiu(10))))
                    ovf = 1;
                n = xau(xmu(xiu(10), n), xiu(d));
            }

        fcon:
            if (b != 16 && (*s == '.' || *s == 'e' || *s == 'E')) {
                if (*s == '.')
                    do {
                        s++;    /* skips . and digits */
                    } while(isdigit(*s));
                if (*s == 'e' || *s == 'E') {
                    if (*++s == '-' || *s == '+')    /* skips e or E */
                        s++;    /* skips - or + */
                    if (!isdigit(*s)) {
                        err_dpos(lmap_spell(t, ss, s, s+1), ERR_CONST_NOEXPDIG);
                        err = 1;
                    }
                }
                if (!err) {
                    errno = 0;
                    ld = strtold(ss, &p);
                    s = fcon((s = p), ld, t->pos);
                }
                b = LEX_FCON;
            } else {
                if (err)
                    err_dpos(lmap_spell(t, ss, p, p+1), ERR_CONST_ILLOCTESC);
                else
                    s = icon(s, n, ovf, b, t->pos);
                b = LEX_ICON;
            }
    }

    if (*s && !err) {
        for (p = (char *)s; *p; p++)
            continue;
        err_dpos(lmap_spell(t, ss, s, p), ERR_CONST_PPNUMSFX, s, b);
        err = 1;
    }

    clx_sym = (err)? NULL: &tval;
    return b;
}
コード例 #14
0
/*
 * Make disk volume entry.
 */
static void
cfgVolume(void)
{


	char *path;
	disk_vol_t *dv;

	Trace(TR_OPRMSG, "handling disk Volume");

	/*
	 * Check for invalid (too long) volume name.
	 */
	if (strlen(dir_name) > (sizeof (vsn_t) - 1)) {
		ReadCfgError(CustMsg(2881));
	}



	dv = (disk_vol_t *)mallocer(sizeof (disk_vol_t));
	if (dv == NULL) {
		ReadCfgError(samerrno);
	}
	memset(dv, 0, sizeof (disk_vol_t));
	snprintf(dv->vol_name, sizeof (dv->vol_name), dir_name);
	dv->set_flags |= DV_vol_name;

	/*
	 * If this is a honeycomb volume set the honeycomb flag in
	 * the disk_volume_t and call into a separate
	 * honeycomb specific parsing function.
	 */
	if (strcmp(token, HONEYCOMB_RESOURCE_NAME) == 0) {
		dv->status_flags |= DV_STK5800_VOL;
		cfgHCVolume(dv);
	} else {

		/*
		 * If token contains a colon the first part of the token
		 * is a host id. The second half is the path.
		 */
		if ((path = strchr(token, ':')) != NULL) {
			*path++ = '\0';
			snprintf(dv->host, sizeof (dv->host), token);
			dv->set_flags |= DV_host;
		} else {
			*dv->host = '\0';
			path = token;
		}

		if (*path != '/') {
			snprintf(dv->path, sizeof (dv->path), "/%s", path);
			dv->set_flags |= DV_path;
		} else {
			snprintf(dv->path, sizeof (dv->path), path);
			dv->set_flags |= DV_path;
		}
	}

	/*
	 * Explicit check for extra fields removed. Ignore any further
	 * information on the line.
	 */

	if (lst_append(dv_cfg->disk_vol_list, dv) != 0) {
		free(dv);
		ReadCfgError(samerrno);
	}
}
コード例 #15
0
ファイル: log_info.c プロジェクト: BackupTheBerlios/samqfs
/*
 * get log information for releaser (one log per file system)
 *
 * Returns a formatted string
 *
 * name=name,
 * type=Log/Trace,
 * state=on/off,
 * path=filename,
 * flags=flags,
 * size=size,
 * modtime=last modified time (num of seconds since 1970)
 */
int
get_releaselog_info(
	sqm_lst_t **lst_releaselog
)
{

	char buffer[BUFSIZ] = {0};
	char global_log[128] = {0};
	int chars = 0;
	sqm_lst_t *lst_rel_fs_dir = NULL;
	node_t *node_rel_fs_dir = NULL;
	rl_fs_directive_t *rel_fs_dir = NULL;
	struct stat statbuf;

	/* get releaser configuration */
	if (get_all_rl_fs_directives(NULL, &lst_rel_fs_dir) == -1) {
		return (-1);
	}

	*lst_releaselog = lst_create(); /* initialize */

	node_rel_fs_dir = lst_rel_fs_dir->head;
	for (node_rel_fs_dir = lst_rel_fs_dir->head;
	    node_rel_fs_dir != NULL;
	    node_rel_fs_dir = node_rel_fs_dir->next) {

		char releaser_log[128]; releaser_log[0] = '\0';
		buffer[0] = '\0'; chars = 0;

		rel_fs_dir = (rl_fs_directive_t *)node_rel_fs_dir->data;

		/*
		 * Get the global properties logfile
		 * assume it would always be at the head of the list
		 */
		if (strcmp(rel_fs_dir->fs, GLOBAL) == 0) {
			strlcpy(global_log, rel_fs_dir->releaser_log,
			    sizeof (global_log));

			chars = snprintf(buffer, sizeof (buffer),
			    "%s=%s, %s=%s, %s=%s",
			    KEY_NAME,
			    GetCustMsg(SE_RELEASE_GLOBAL_LOG_DESC),
			    KEY_TYPE, GetCustMsg(SE_TYPE_LOG),
			    KEY_STATE, (global_log[0] != '\0') ?
			    STATE_ON : STATE_OFF);

			if (global_log[0] != '\0') {
				ADD_DELIM(chars, buffer);
				chars += snprintf(buffer + chars,
				    sizeof (buffer) - chars,
				    "%s=%s",
				    KEY_PATH, global_log);
				/* no flags ? */
				if (stat(global_log, &statbuf) == 0) {
					ADD_DELIM(chars, buffer);
					chars += snprintf(buffer + chars,
					    sizeof (buffer) - chars,
					    "%s=%ld, %s=%lu",
					    KEY_SIZE, statbuf.st_size,
					    KEY_MODTIME, statbuf.st_mtime);
				}
			}
			lst_append(*lst_releaselog, strdup(buffer));
			continue;

		} else {
			/* not a global property logfile */

			/*
			 * If the file system does not have a release logfile
			 * associated with it, skip
			 */
			if ((rel_fs_dir->releaser_log[0] != '\0') &&
			    (global_log[0] != '\0') &&
			    (strcmp(rel_fs_dir->releaser_log,
			    global_log) != 0)) {

				/* logfile specific to file system */
				chars = snprintf(buffer, sizeof (buffer),
				    "%s=%s %s, %s=%s, %s=%s",
				    KEY_NAME,
				    GetCustMsg(SE_RELEASE_LOG_DESC),
				    rel_fs_dir->fs,
				    KEY_TYPE, GetCustMsg(SE_TYPE_LOG),
				    KEY_STATE,
				    (rel_fs_dir->releaser_log[0] != '\0') ?
				    STATE_ON : STATE_OFF);

				if (rel_fs_dir->releaser_log[0] != '\0') {
					ADD_DELIM(chars, buffer);
					chars += snprintf(buffer + chars,
					    sizeof (buffer) - chars,
					    "%s=%s",
					    KEY_PATH,
					    rel_fs_dir->releaser_log);
					/* no flags ? */
					if (stat(rel_fs_dir->releaser_log,
					    &statbuf) == 0) {
						ADD_DELIM(chars, buffer);
						chars +=
						    snprintf(buffer + chars,
						    sizeof (buffer) - chars,
						    "%s=%ld, %s=%lu",
						    KEY_SIZE,
						    statbuf.st_size,
						    KEY_MODTIME,
						    statbuf.st_mtime);
					}
				}
				lst_append(*lst_releaselog, strdup(buffer));
			}
		}
	}
	lst_free_deep(lst_rel_fs_dir);

	return (0);
}
コード例 #16
0
ファイル: log_info.c プロジェクト: BackupTheBerlios/samqfs
/*
 * get SAM system log information
 *
 * Information is a list of formatted strings
 *
 * name=name,
 * type=Log/Trace,
 * state=on/off,
 * path=filename,
 * flags=flags,
 * size=size,
 * modtime=last modified time (num of seconds since 1970)
 */
int
get_samlog_lst(
	sqm_lst_t **lst_log
)
{
	sam_defaults_t *sam_defaults = NULL;
	char *log_keyword = NULL;
	char *flags = NULL;
	FILE *fp = NULL;
	char linebuf[BUFSIZ];

	char buffer[4096];

	/* log facility from defaults is an int, convert to syslog facility */
	if ((sam_defaults = GetDefaults()) == NULL) {
		Trace(TR_ERR, "Could not get sam log config");
		return (-1);
	}
	log_keyword = ifacility2sfacility(sam_defaults->log_facility);
	if (log_keyword == NULL) {
		Trace(TR_ERR, "Unrecognized system facility for sam log");
		return (-1);
	}

	if ((fp = fopen(SYSLOG_CONF, "r")) == NULL) {
		return (-1);
	}
	*lst_log = lst_create();

	/*
	 * res_stream format:facility.level [ ; facility.level ]<tab>action
	 *
	 * there can be multiple lines with this facility
	 * e.g.
	 * local7.debug	/var/adm/sam-debug
	 * local7.warn	/var/adm/sam-warn
	 * local7.crit	/var/adm/sam-crit
	 */
	while (fgets(linebuf, BUFSIZ, fp)) {

		linebuf[BUFSIZ - 1] = '\0';

		char *lptr = linebuf;

		/* ignore whitespaces, empty lines and comments */
		lptr += strspn(lptr, WHITESPACE);
		if (lptr[0] == CHAR_POUND) {
			continue;
		}
		if (strstr(lptr, log_keyword) == NULL) {
			continue;
		}
		char *facility = NULL, *action = NULL, *lasts = NULL;
		if ((facility = strtok_r(lptr, WHITESPACE, &lasts)) != NULL) {
			action = strtok_r(NULL, WHITESPACE, &lasts);
		}
		if (facility == NULL || action == NULL) { /* ignore */
			continue;
		}
		Trace(TR_MISC, "facility=%s, action=%s", facility, action);
		char *keyword = NULL;
		flags = NULL;
		lasts = NULL;
		/* tokenize facility to get keyword and flag */
		if ((keyword = strtok_r(facility, COLON, &lasts)) != NULL) {
			flags = strtok_r(NULL, ":", &lasts);
			flags = (flags != NULL) ? flags : "";
		}
		free(keyword);

		struct stat statbuf;
		off_t size = 0; long age = 0;

		if (stat(action, &statbuf) == 0) {
			size = statbuf.st_size;
			age = statbuf.st_mtime;
		}
		snprintf(buffer, sizeof (buffer),
		    "%s=%s, %s=%s, %s=%s, %s=%s, %s=%s, %s=%ld, %s=%lu",
		    KEY_NAME,
		    GetCustMsg(SE_SYSTEM_LOG_DESC),
		    KEY_TYPE, GetCustMsg(SE_TYPE_LOG),
		    KEY_STATE, STATE_ON,
		    KEY_PATH, action,
		    KEY_FLAGS, flags,
		    KEY_SIZE, size,
		    KEY_MODTIME, age);

		lst_append(*lst_log, strdup(buffer));
		buffer[0] = '\0';
	}
	free(log_keyword);
	fclose(fp);
	Trace(TR_MISC, "SAM system log info obtained");
	return (0);

}
コード例 #17
0
ファイル: log_info.c プロジェクト: BackupTheBerlios/samqfs
/*
 * get device log information
 * Device-logging messages are written to individual log files
 * There is one log file for each library, tape drive etc. Log files are
 * located in /var/opt/SUNWsamfs/devlog. The name of each log file is the
 * same as the equipment ordinal specified in the mcf file
 * flags (events) is one or more of:
 * all, date, err, default, detail, module, label etc.
 *
 * Returns a list of formatted strings
 *
 * name=name,
 * type=Log/Trace,
 * state=on/off,
 * path=filename,
 * flags=flags,
 * size=size,
 * modtime=last modified time (num of seconds since 1970)
 */
int
get_devlog_info(
	sqm_lst_t **lst_devlog
)
{
	drive_t *drive = NULL;
	library_t *lib = NULL;
	sqm_lst_t *lst_lib = NULL;
	node_t *node_lib = NULL, *node_drive = NULL;

	if (get_all_libraries(NULL, &lst_lib) != 0) {
		return (-1);
	}
	*lst_devlog = lst_create();

	node_lib = lst_lib->head;
	while (node_lib != NULL) {
		int chars = 0;
		char buffer[BUFSIZ] = {0};
		char *params = NULL;


		lib = (library_t *)node_lib->data;

		chars = snprintf(buffer, sizeof (buffer),
		    "%s=%s %s %02d, %s=%s",
		    KEY_NAME, GetCustMsg(SE_DEVICE_LOG_DESC),
		    (strcmp(lib->base_info.equ_type, "hy") == 0) ?
		    GetCustMsg(SE_HISTORIAN_DESC) : lib->base_info.set,
		    lib->base_info.eq,
		    KEY_TYPE, GetCustMsg(SE_TYPE_LOG));

		if (devlog_params(lib->base_info.eq, &params) != NULL) {

			ADD_DELIM(chars, buffer);
			strlcat(buffer, params, sizeof (buffer));
			free(params); params = NULL;

			lst_append(*lst_devlog, strdup(buffer));
		}
		/* now the devlog for drives */
		node_drive = lib->drive_list->head;
		while (node_drive != NULL) {
			buffer[0] = '\0'; chars = 0;

			drive = (drive_t *)node_drive->data;
			chars = snprintf(buffer, sizeof (buffer),
			    "%s=%s %s %02d, %s=%s",
			    KEY_NAME, GetCustMsg(SE_DEVICE_LOG_DESC),
			    drive->base_info.set,
			    drive->base_info.eq,
			    KEY_TYPE, GetCustMsg(SE_TYPE_LOG));

			if (devlog_params(drive->base_info.eq, &params)
			    != NULL) {

				ADD_DELIM(chars, buffer);
				strlcat(buffer, params, sizeof (buffer));
				free(params); params = NULL;

				lst_append(*lst_devlog, strdup(buffer));
			}
			node_drive = node_drive->next;
		}
		buffer[0] = '\0'; chars = 0;
		node_lib = node_lib->next;
	}
	lst_free_deep_typed(lst_lib, FREEFUNCCAST(free_library));
	return (0);
}
コード例 #18
0
ファイル: process_job.c プロジェクト: BackupTheBerlios/samqfs
/*
 * function to get information about a running processes that match the input
 * parameters.
 */
int
get_process_jobs(
ctx_t		*ctx		/* ARGSUSED */,
char		*filter,	/* see Filter Strings in process_job.h */
sqm_lst_t		**job_list)	/* list of proc_job_t */
{

	static char	*procdir = "/proc";	/* standard /proc directory */
	struct dirent64	*dent;
	struct dirent64	*dentp;
	DIR		*dirp;
	char		pname[MAXPATHLEN+1];

	Trace(TR_MISC, "getting process job with filter %s", Str(filter));

	if (ISNULL(job_list)) {
		Trace(TR_OPRMSG, "getting process jobs failed %d %s",
		    samerrno, samerrmsg);
		return (-1);
	}

	if ((dirp = opendir(procdir)) == NULL) {
		samerrno = SE_OPENDIR_FAILED;
		snprintf(samerrmsg, MAX_MSG_LEN,
		    GetCustMsg(samerrno), procdir, "");
		strlcat(samerrmsg, strerror(errno), MAX_MSG_LEN);
		Trace(TR_OPRMSG, "open dir %s failed", procdir);
		return (-1);
	}

	dent = mallocer(sizeof (struct dirent64) + MAXPATHLEN + 1);
	if (dent == NULL) {
		closedir(dirp);
		return (-1);
	}

	*job_list = lst_create();
	if (*job_list == NULL) {
		Trace(TR_ERR, "getting process jobs failed %d %s", samerrno,
		    samerrmsg);
		(void) closedir(dirp);
		free(dent);
		return (-1);
	}

	/* for each active process --- */
	while ((readdir64_r(dirp, dent, &dentp)) == 0) {
		int	procfd;	/* filedescriptor for /proc/nnnnn/psinfo */
		psinfo_t info;	/* process information from /proc */
		char *job_str;

		if (dentp == NULL) {
			break;
		}

		if (dentp->d_name[0] == '.')		/* skip . and .. */
			continue;

		snprintf(pname, sizeof (pname), "%s/%s/psinfo",
		    procdir, dentp->d_name);

		if ((procfd = open(pname, O_RDONLY)) == -1) {
			continue;
		}

		/*
		 * Get the info structure for the process and close quickly.
		 */
		if (readbuf(procfd, (char *)&info, sizeof (info)) < 0) {
			continue;
		}
		(void) close(procfd);

		if (info.pr_lwp.pr_state == 0)		/* can't happen? */
			continue;

		/* Screen out processes that do not match our criteria. */
		/*
		 * make this a helper function that takes an info
		 * and a proc_job and returns true if match has been made.
		 * this implies a signature change for this function to take
		 * a job.
		 */
		if (psinfo_matches_filter(info, filter)) {
			if (create_process_job(&info, &job_str) != 0) {
				(void) closedir(dirp);
			}
			lst_append(*job_list, job_str);
		}

	}

	(void) closedir(dirp);
	free(dent);
	return (0);
}
コード例 #19
0
ファイル: samrdumps.c プロジェクト: BackupTheBerlios/samqfs
/* Restore child nodes. Recursive. */
static int
restore_children(char *dir_name, int *copy, char *dest, char *mountpt,
	dumpspec_t *dsp, replace_t replace, boolean_t count_only)
{
	int		st;
	char		childdest[MAXPATHLEN + 1];
	char		msgbuf[MAX_MSGBUF_SIZE] = {0};
	char		catmsg[MAX_MSGBUF_SIZE] = {0};
	sqm_lst_t		*lstp = NULL;
	sqm_lst_t		*dirlist = NULL;
	uint32_t	morefiles = 0;
	restrict_t	filter;
	filedetails_t	*details;
	char		*ptr;
	char		startFrom[MAXPATHLEN + 1];
	node_t		*node;
	char		*lastFile = NULL;
	char		*startp;
	char		*destp;

	dirlist = lst_create();
	if (dirlist == NULL) {
		return (-1);
	}

	memset(&filter, 0, sizeof (restrict_t));

/* TODO:  Add testcancel points and cleanup function */

	startFrom[0] = '\0';

	/*
	 * get file info from the database in chunks so as not to
	 * overwhelm ourselves if we're restoring a huge directory
	 */
	do {
		lstp = lst_create();
		if (lstp == NULL) {
			goto done;
		}
		st = list_snapshot_files(dsp->fsname, dsp->snapname,
		    dir_name, startFrom, filter, 0, 2048, FALSE,
		    &morefiles, lstp);

		if (st != 0) {
			/* list_snapshot_files doesn't set samerrmsg */
			snprintf(msgbuf, sizeof (msgbuf),
			    GetCustMsg(SE_RESTORE_FAILED), "");
			snprintf(catmsg, sizeof (catmsg), "%d %s ",
			    st, strerror(st));
			strlcat(msgbuf, catmsg, sizeof (msgbuf));
			strlcat(msgbuf, dir_name, sizeof (msgbuf));
			rlog(dsp->logfil, msgbuf, NULL, NULL);
			PostEvent(DUMP_CLASS, DUMP_INTERRUPTED_SUBCLASS,
			    SE_RESTORE_FAILED, LOG_ERR,
			    msgbuf, NOTIFY_AS_FAULT);
			goto done;
		}

		/*
		 * Create new destination path - add filename with
		 * strlcat to avoid possible problems with % in
		 * the pathname.
		 */
		strlcpy(childdest, dest, MAXPATHLEN + 1);
		strlcat(childdest, "/", MAXPATHLEN + 1);
		destp = childdest + strlen(childdest);

		for (node = lstp->head; node != NULL; node = node->next) {
			details = node->data;

			if (details == NULL) {
				continue;
			}

			/*
			 * save the path name in case we need it to get
			 * more files
			 */
			lastFile = details->file_name;

			*destp = '\0';
			strlcat(childdest, details->file_name, MAXPATHLEN + 1);

			/* if we're only counting, don't call restore_node */

			/* Restore the child node */
			if (!count_only) {
				st = restore_node(details, copy, childdest,
				    mountpt, dsp, replace);
				if (st != 0) {
					strlcpy(catmsg,
					    GetCustMsg(SE_RESTORE_FAILED),
					    sizeof (catmsg));
					snprintf(msgbuf, sizeof (msgbuf),
					    catmsg, samerrmsg);
					rlog(dsp->logfil, msgbuf, NULL, NULL);
					PostEvent(DUMP_CLASS,
					    DUMP_INTERRUPTED_SUBCLASS,
					    SE_RESTORE_FAILED, LOG_ERR,
					    msgbuf, NOTIFY_AS_FAULT);
					/* file already exists isn't fatal */
					if (samerrno ==
					    SE_FILE_ALREADY_EXISTS) {
						st = 0;
					}
				}
			}

			if (S_ISDIR(details->prot)) {
				lst_append(dirlist, details->file_name);
				/* ensure not doubly deleted */
				details->file_name = NULL;
			}
		}

		if (count_only) {
			restore_max += lstp->length;
		}

		if (lastFile) {
			strlcpy(startFrom, lastFile, sizeof (startFrom));
		}
		lst_free_deep_typed(lstp, FREEFUNCCAST(free_file_details));
		lstp = NULL;
	} while (morefiles > 0);

	/* restore any directories we found along the way */

	strlcpy(startFrom, dir_name, sizeof (startFrom));
	strlcat(startFrom, "/", sizeof (startFrom));
	startp = startFrom + strlen(startFrom);

	for (node = dirlist->head; node != NULL; node = node->next) {
		ptr = (char *)node->data;
		*startp = '\0';

		/* Create new source path */
		strlcat(startp, ptr, sizeof (startFrom));

		/* Create new destination path */
		snprintf(childdest, MAXPATHLEN + 1, "%s/%s", dest, ptr);

		/* this will log individual errors for failure */
		(void) restore_children(startFrom, copy, childdest, mountpt,
		    dsp, replace, count_only);
	}

done:
	if (lstp != NULL) {
		lst_free_deep_typed(lstp, FREEFUNCCAST(free_file_details));
	}
	if (dirlist != NULL) {
		lst_free_deep(dirlist);
	}

	return (st);
}
コード例 #20
0
ファイル: file_util.c プロジェクト: BackupTheBerlios/samqfs
/*
 *  filepath may be either a directory or a fully-qualified path.
 *  if it's fully-qualified, only directory entries that sort alphabetically
 *  after the specified file will be returned.
 *
 *  morefiles will be set if there are more entries left in the directory
 *  after maxentries have been returned.  This is intended to let the caller
 *  know they can continue reading.
 *
 *  Note that the directory may change while we're reading it.  If it does,
 *  files that have been added or removed since we started reading it may
 *  not be accurately reflected.
 */
int
list_directory(
	ctx_t		*c,			/* ARGSUSED */
	int		maxentries,
	char		*listDir,		/* directory to list */
	char		*startFile,		/* if continuing, start here */
	char		*restrictions,
	uint32_t	*morefiles,		/* OUT */
	sqm_lst_t		**direntries)		/* OUT */
{
	int		rval = 0;
	int		st = 0;
	DIR		*curdir; /* Variable for directory system calls */
	dirent64_t	*entry;	/* Pointer to a directory entry */
	dirent64_t	*entryp;
	struct stat64	sout;
	restrict_t	filter = {0};
	char		*data;	/* Pointer to data item to add to list */
	node_t		*node;
	sqm_lst_t		*lstp = NULL;
	char		buf[MAXPATHLEN + 1];
	char		*fname;

	if (ISNULL(listDir, direntries, morefiles)) {
		return (-1);
	}

	*morefiles = 0;

	/* Set up wildcard restrictions */
	rval = set_restrict(restrictions, &filter);
	if (rval) {
		return (rval);
	}

	curdir = opendir(listDir); /* Set up to ask for directory entries */
	if (curdir == NULL) {
		return (samrerr(SE_NOSUCHPATH, listDir));
	}

	*direntries = lst_create(); /* Return results in this list */
	if (*direntries == NULL) {
		closedir(curdir);
		return (-1);	/* If allocation failed, samerr is set */
	}
	lstp = *direntries;

	entry = mallocer(sizeof (struct dirent64) + MAXPATHLEN + 1);
	if (entry == NULL) {
		closedir(curdir);
		lst_free(*direntries);
		*direntries = NULL;
		return (-1);
	}

	/* Walk through directory entries */
	while ((rval = readdir64_r(curdir, entry, &entryp)) == 0) {
		if (entryp == NULL) {
			break;
		}

		fname = (char *)&(entry->d_name[0]);

		if ((strcmp(fname, ".") == 0) ||
		    (strcmp(fname, "..") == 0)) {
			continue;
		}

		/*
		 * If we were given a non-directory, start after
		 * that file alphabetically.
		 */
		if (startFile != NULL) {
			if ((strcmp(fname, startFile)) <= 0) {
				continue;
			}
		}

		/* Create full pathname and get stat info */
		snprintf(buf, sizeof (buf), "%s/%s", listDir, fname);
		if (lstat64(buf, &sout) != 0) {
			continue; /* Ignore file which can't be stat'ed */
		}

		/*
		 * think about ways to avoid a double-stat in when we're
		 * fetching file details
		 */
		if (check_restrict_stat(fname, &sout, &filter)) {
			continue; /* Not this entry */
		}

		/* copy to allocated struct */
		data = copystr(fname);
		if (data == NULL) {
			rval = -1;
			break;	/* samerr already set */
		}

		/*
		 * caller wants all entries for the directory
		 * should there be a top-end limit, to avoid the case where
		 * the directory has millions of entries?
		 */
		if (maxentries <= 0) {
			rval = lst_append(lstp, data);
			if (rval != 0) {
				free(data);
				break;
			}
			continue;
		}

		/*
		 * Directory may have more entries than requested, so pre-sort
		 * the list so we return the first <n> sorted alphabetically.
		 */
		for (node = lstp->head; node != NULL; node = node->next) {

			st = strcmp(data, (char *)(node->data));
			if (st > 0) {
				continue;
			}

			if (st < 0) {
				rval = lst_ins_before(lstp, node, data);
				data = NULL;
			}

			if ((rval != 0) || (st == 0)) {
				free(data);
				data = NULL;
			}
			break;
		}

		/* entry sorts higher than existing entries */
		if (data != NULL) {
			if (lstp->length < maxentries) {
				rval = lst_append(lstp, data);
				if (rval != 0) {
					free(data);
					break;
				}
			} else {
				/* no room for this entry */
				free(data);
				(*morefiles)++;
			}
		}

		/* Keep list to designated limits */
		if (lstp->length > maxentries) {
			/* pop off the last entry */
			lst_remove(lstp, lstp->tail);
			(*morefiles)++;
		}
	}

	closedir(curdir);
	free(entry);

	if (rval) {
		lst_free_deep(*direntries);
		*direntries = NULL;
	} else if (maxentries <= 0) {
		lst_qsort(*direntries, node_cmp);
	}

	return (rval);
}
コード例 #21
0
ファイル: callback_home.c プロジェクト: 5ouya/raspC
int callback_home(struct lws *wsi, enum lws_callback_reasons reason, void *user,
    void *in, size_t len)  {

    struct per_session_data__details *pss =
    (struct per_session_data__details *)user; 




    switch (reason) {
        case LWS_CALLBACK_PROTOCOL_INIT:{
            break;
        }
        case LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION:
        {            
            check_session(wsi,pss);
            increment_client_count();
            if(lst_find(&clinets_lst,pss->uid)<0){
                lst_append(&clinets_lst, pss->user,pss->uid,pss->gid,pss->session_id+24);
            }               
            break; 
        }         
        case LWS_CALLBACK_WS_PEER_INITIATED_CLOSE:
        {
            new_user=pss->user;
            decrement_client_count();
            lst_remove(&clinets_lst,pss->uid);
        }   
        case LWS_CALLBACK_ESTABLISHED:
        {

            dump_user_info(pss);
            new_user=pss->user;


        }
        case LWS_CALLBACK_SERVER_WRITEABLE:
        {         
            if(strncmp(pss->checked,hash,32)!=0){
                memcpy(pss->checked,hash,32);
                
                char *out = lst_json(&clinets_lst);

                int count = strlen(out);

                unsigned char buffer[LWS_PRE + count];
                unsigned char *p = &buffer[LWS_PRE];

                int n = sprintf((char *)p, "%s", out);

                lws_write(wsi, p,  n, LWS_WRITE_TEXT);  
                free(out);  
                    
                break;              

            }


            
            break;
        }
        case LWS_CALLBACK_RECEIVE:
        {
        //received_msg = (char *) in;
        //chalter=1;
        //lws_callback_on_writable_all_protocol(lws_get_context(wsi),lws_get_protocol(wsi));

            break;
        }  
        default:
        break;      

    }
    return 0;
}
コード例 #22
0
ファイル: releaser.c プロジェクト: BackupTheBerlios/samqfs
/*
 * release_files
 * Used to release files and directories and to set releaser
 * attributes for files and directories.
 *
 *
 * Attr Flags
 * RL_OPT_RECURSIVE
 * RL_OPT_NEVER
 * RL_OPT_WHEN_1
 * RL_OPT_PARTIAL
 * RL_OPT_DEFAULTS
 *
 * If any attrubute other than RL_OPT_RECURSIVE is specified the disk space
 * will not be released. Instead the indicated attributes will be set
 * for each file in the file list.
 *
 * The RL_OPT_NEVER & RL_OPT_ALWAYS_WHEN_1 are
 * mutually exclusive.
 *
 * PARAMS:
 *   sqm_lst_t  *files,	 IN - list of fully quallified file names
 *   int32_t options	 IN - bit fields indicate release options (see above).
 *   int32_t *partial_sz IN -
 * RETURNS:
 *   success -  0	operation successfully issued release not necessarily
 *			complete.
 *   error   -  -1
 */
int
release_files(ctx_t *c /* ARGSUSED */, sqm_lst_t *files, int32_t options,
    int32_t partial_sz, char **job_id) {

	char		buf[32];
	char		**command;
	node_t		*n;
	argbuf_t 	*arg;
	size_t		len = MAXPATHLEN * 2;
	boolean_t	found_one = B_FALSE;
	pid_t		pid;
	int		ret;
	int		status;
	FILE		*out;
	FILE		*err;
	exec_cleanup_info_t *cl;
	char release_s_buf[32];
	int arg_cnt;
	int cur_arg = 0;

	if (ISNULL(files, job_id)) {
		Trace(TR_ERR, "release files failed:%s", samerrmsg);
		return (-1);
	}


	/*
	 * Determine how many args to the command and create the command
	 * array. Note that command is malloced because the number of files
	 * is not known prior to execution. The arguments themselves need
	 * not be malloced because the child process will get a copy.
	 * Include space in the command array for:
	 * - the command
	 * - all possible options
	 * - an entry for each file in the list.
	 * - entry for the NULL
	 */
	arg_cnt = 1 + 6 + files->length + 1;
	command = (char **)calloc(arg_cnt, sizeof (char *));
	if (command == NULL) {
		setsamerr(SE_NO_MEM);
		Trace(TR_ERR, "release files failed:%s", samerrmsg);
		return (-1);
	}
	command[cur_arg++] = RELEASE_FILES_CMD;

	*buf = '\0';
	if (partial_sz) {
		snprintf(release_s_buf, sizeof (release_s_buf), "-s%d ",
		    partial_sz);
		command[cur_arg++] = release_s_buf;
	}
	if (options & RL_OPT_NEVER) {
		command[cur_arg++] = "-n";
	}
	if (options & RL_OPT_WHEN_1) {
		command[cur_arg++] = "-a";
	}
	if (options & RL_OPT_PARTIAL) {
		command[cur_arg++] = "-p";
	}
	if (options & RL_OPT_DEFAULTS) {
		command[cur_arg++] = "-d";
	}
	/* Recursive must be specified last */
	if (options & RL_OPT_RECURSIVE) {
		command[cur_arg++] = "-r";
	}

	/* make the argument buffer for the activity */
	arg = (argbuf_t *)mallocer(sizeof (releasebuf_t));
	if (arg == NULL) {
		free(command);
		Trace(TR_ERR, "release files failed:%s", samerrmsg);
		return (-1);
	}

	arg->rl.filepaths = lst_create();
	if (arg->rl.filepaths == NULL) {
		free(command);
		Trace(TR_ERR, "release files failed:%s", samerrmsg);
		return (-1);
	}
	arg->rl.options = options;
	arg->rl.partial_sz = partial_sz;

	/* add the file names to the cmd string and the argument buffer */
	for (n = files->head; n != NULL; n = n->next) {
		if (n->data != NULL) {
			char *cur_file;
			command[cur_arg++] = (char *)n->data;

			found_one = B_TRUE;
			cur_file = copystr(n->data);
			if (cur_file == NULL) {
				free(command);
				free_argbuf(SAMA_RELEASEFILES, arg);
				Trace(TR_ERR, "release files failed:%s",
				    samerrmsg);
				return (-1);
			}
			if (lst_append(arg->rl.filepaths, cur_file) != 0) {
				free(command);
				free(cur_file);
				free_argbuf(SAMA_RELEASEFILES, arg);
				Trace(TR_ERR, "release files failed:%s",
				    samerrmsg);
				return (-1);
			}
		}
	}

	/*
	 * Check that at least one file was found.
	 */
	if (!found_one) {
		free(command);
		free_argbuf(SAMA_RELEASEFILES, arg);
		Trace(TR_ERR, "release files failed:%s", samerrmsg);
		return (-1);
	}

	/* create the activity */
	ret = start_activity(display_release_activity, kill_fork,
	    SAMA_RELEASEFILES, arg, job_id);
	if (ret != 0) {
		free(command);
		free_argbuf(SAMA_RELEASEFILES, arg);
		Trace(TR_ERR, "release files failed:%s", samerrmsg);
		return (-1);
	}

	/*
	 * create the cleanup struct prior to the exec because it is
	 * easier to cleanup here  if the malloc fails.
	 */
	cl = (exec_cleanup_info_t *)mallocer(sizeof (exec_cleanup_info_t));
	if (cl == NULL) {
		free(command);
		lst_free_deep(arg->rl.filepaths);
		end_this_activity(*job_id);
		Trace(TR_ERR, "release files failed, error:%d %s",
		    samerrno, samerrmsg);
		return (-1);
	}

	/* exec the process */
	pid = exec_mgmt_cmd(&out, &err, command);
	if (pid < 0) {
		free(command);
		lst_free_deep(arg->rl.filepaths);
		end_this_activity(*job_id);
		Trace(TR_ERR, "release files failed:%s", samerrmsg);
		return (-1);
	}
	free(command);
	set_pid_or_tid(*job_id, pid, 0);


	/* setup struct for call to cleanup */
	strlcpy(cl->func, RELEASE_FILES_CMD, sizeof (cl->func));
	cl->pid = pid;
	strlcpy(cl->job_id, *job_id, MAXNAMELEN);
	cl->streams[0] = out;
	cl->streams[1] = err;


	/* possibly return the results or async notification */
	ret = bounded_activity_wait(&status, 10, *job_id, pid, cl,
	    cleanup_after_exec_get_output);

	if (ret == -1) {
		samerrno = SE_RELEASE_FILES_FAILED;
		snprintf(samerrmsg, MAX_MSG_LEN,
		    GetCustMsg(SE_RELEASE_FILES_FAILED));

		free(*job_id);
		*job_id = NULL;
		Trace(TR_ERR, "release files failed:%s", samerrmsg);
		return (-1);
	} else if (ret == 0) {
		/*
		 * job_id was set by start_activity. Clear it now
		 * so that the caller knows the request has been submitted.
		 */
		free(*job_id);
		*job_id = NULL;
		Trace(TR_MISC, "release files completed");
	}

	Trace(TR_MISC, "leaving release files");
	return (0);
}
コード例 #23
0
ファイル: log_info.c プロジェクト: BackupTheBerlios/samqfs
/*
 * get archiver log info, there is one archive log per file system
 *
 * Returns a formatted string
 *
 * name=name,
 * type=Log/Trace,
 * state=on/off,
 * path=filename,
 * flags=flags,
 * size=size,
 * modtime=last modified time (num of seconds since 1970)
 */
int
get_archivelog_info(
	sqm_lst_t **lst_archivelog
)
{

	ar_fs_directive_t *ar_fs_dir = NULL;
	ar_global_directive_t *ar_global = NULL;
	sqm_lst_t *lst_ar_fs_dir = NULL;
	node_t *node_ar_fs_dir = NULL;

	char buffer[BUFSIZ] = {0};
	int chars = 0;
	struct stat statbuf;

	/* get all file system directives for archiving */
	if (get_all_ar_fs_directives(NULL, &lst_ar_fs_dir) == -1) {
		return (-1);
	}

	/* get archiver log global directive */
	if (get_ar_global_directive(NULL, &ar_global) == -1) {

		lst_free_deep_typed(lst_ar_fs_dir,
		    FREEFUNCCAST(free_ar_fs_directive));
		return (-1);
	}

	*lst_archivelog = lst_create();

	/* add the global archive directive */
	chars = snprintf(buffer, sizeof (buffer),
	    "%s=%s, %s=%s, %s=%s",
	    KEY_NAME, GetCustMsg(SE_ARCHIVE_GLOBAL_LOG_DESC),
	    KEY_TYPE, GetCustMsg(SE_TYPE_LOG),
	    KEY_STATE, (ar_global->log_path[0] != '\0') ?
	    STATE_ON : STATE_OFF);

	if (ar_global->log_path[0] != '\0') {
		ADD_DELIM(chars, buffer);
		chars += snprintf(buffer + chars, sizeof (buffer) - chars,
		    "%s=%s", KEY_PATH, ar_global->log_path);

		if (stat(ar_global->log_path, &statbuf) == 0) {
			ADD_DELIM(chars, buffer);
			chars += snprintf(buffer + chars,
			    sizeof (buffer) - chars,
			    "%s=%ld, %s=%lu",
			    KEY_SIZE, statbuf.st_size,
			    KEY_MODTIME, statbuf.st_mtime);
		}
	}
	lst_append(*lst_archivelog, strdup(buffer));

	/* now check if any filesystems have overloaded the global log */
	node_ar_fs_dir = lst_ar_fs_dir->head;
	while (node_ar_fs_dir != NULL) {
		ar_fs_dir = (ar_fs_directive_t *)node_ar_fs_dir->data;

		buffer[0] = '\0'; chars = 0;
		if ((ar_fs_dir != NULL) &&
		    strcmp(ar_global->log_path, ar_fs_dir->log_path))  {

			/* Get the fsname and the logpath */
			chars = snprintf(buffer, sizeof (buffer),
			    "%s=%s %s, %s=%s, %s=%s",
			    KEY_NAME, GetCustMsg(SE_ARCHIVE_LOG_DESC),
			    ar_fs_dir->fs_name,
			    KEY_TYPE, GetCustMsg(SE_TYPE_LOG),
			    KEY_STATE, (ar_fs_dir->log_path[0] != '\0') ?
			    STATE_ON : STATE_OFF);


			if (ar_fs_dir->log_path[0] != '\0') {
				ADD_DELIM(chars, buffer);
				chars += snprintf(buffer + chars,
				    sizeof (buffer) - chars,
				    "%s=%s", KEY_PATH, ar_fs_dir->log_path);

				if (stat(ar_fs_dir->log_path, &statbuf) == 0) {
					ADD_DELIM(chars, buffer);
					chars += snprintf(buffer + chars,
					    sizeof (buffer) - chars,
					    "%s=%ld, %s=%lu",
					    KEY_SIZE, statbuf.st_size,
					    KEY_MODTIME, statbuf.st_mtime);
				}
			}
			lst_append(*lst_archivelog, strdup(buffer));
		}
		buffer[0] = '\0'; chars = 0;
		node_ar_fs_dir = node_ar_fs_dir->next;
	}
	lst_free_deep_typed(lst_ar_fs_dir, FREEFUNCCAST(free_ar_fs_directive));
	free_ar_global_directive(ar_global);
	return (0);
}
コード例 #24
0
ファイル: load.c プロジェクト: BackupTheBerlios/samqfs
/*
 * Function to get information about all pending load information.
 */
int
get_pending_load_info(
ctx_t *ctx,						/* ARGSUSED */
sqm_lst_t **pending_load_infos)	/* OUT - list of pending_load_info_t */
{
	shm_alloc_t preview_shm;
	shm_preview_tbl_t *shm_preview_tbl;
	preview_tbl_t *preview_tbl;
	preview_t *p;
	pending_load_info_t *info = NULL;
	sqm_lst_t *load_infos = NULL;
	struct passwd *pw = NULL;
	time_t now;
	int avail;		/* available entry count */
	int count;		/* active entry count */
	int i;

	Trace(TR_MISC, "getting pending load info");

	if (ISNULL(pending_load_infos)) {
		Trace(TR_OPRMSG, "null argument found");
		goto err;
	}

	load_infos = lst_create();
	if (load_infos == NULL) {
		Trace(TR_OPRMSG, "out of memory");
		goto err;
	}

	Trace(TR_OPRMSG, "attaching to shared memory");

	preview_shm.shmid = shmget(SHM_PREVIEW_KEY, 0, 0);
	if (preview_shm.shmid < 0) {
		samerrno = SE_PREVIEW_SHM_NOT_FOUND;
		snprintf(samerrmsg, MAX_MSG_LEN, GetCustMsg(samerrno));
		Trace(TR_OPRMSG,
		    "unable to find preview shared memory segment");
		*pending_load_infos = load_infos;
		Trace(TR_MISC, "got 0 pending load info");
		return (-2);
	}

	preview_shm.shared_memory = shmat(preview_shm.shmid, NULL, SHM_RDONLY);
	if (preview_shm.shared_memory == (void *)-1) {
		samerrno = SE_PREVIEW_SHM_ATTACH_FAILED;
		snprintf(samerrmsg, MAX_MSG_LEN, GetCustMsg(samerrno));
		Trace(TR_OPRMSG,
		    "unable to attach preview shared memory segment");
		goto err;
	}

	shm_preview_tbl = (shm_preview_tbl_t *)preview_shm.shared_memory;
	preview_tbl = &shm_preview_tbl->preview_table;

	Trace(TR_OPRMSG, "creating pending load info list");

	avail = preview_tbl->avail;
	count = preview_tbl->ptbl_count;

	for (i = 0; i < avail && count != 0; i++) {
		p = &preview_tbl->p[i];

		if (!p->in_use)
			continue;

		count--;

		info = (pending_load_info_t *)
		    mallocer(sizeof (pending_load_info_t));
		if (info == NULL) {
			Trace(TR_OPRMSG, "out of memory");
			goto err;
		}

		info->id = i;

		info->flags = 0;
		if (p->busy)		info->flags |= LD_BUSY;
		if (p->in_use)		info->flags |= LD_IN_USE;
		if (p->p_error)		info->flags |= LD_P_ERROR;
		if (p->write)		info->flags |= LD_WRITE;
		if (p->fs_req)		info->flags |= LD_FS_REQ;
		if (p->block_io)	info->flags |= LD_BLOCK_IO;
		if (p->stage)		info->flags |= LD_STAGE;
		if (p->flip_side)	info->flags |= LD_FLIP_SIDE;

		info->count = p->count;

		info->robot_equ = p->robot_equ;

		info->remote_equ = p->remote_equ;

		snprintf(info->media, sizeof (info->media),
		    sam_mediatoa(p->resource.archive.rm_info.media));

		info->slot = p->slot;

		info->ptime = p->ptime;

		now = time(NULL);
		info->age = now - p->ptime;

		info->priority = p->priority;

		info->pid = p->handle.pid;

		pw = getpwuid(getuid());

		if (pw != NULL) {
			snprintf(info->user, sizeof (info->user), pw->pw_name);
		} else {
			snprintf(info->user, sizeof (info->user),
			    "Unknown user");
		}

		snprintf(info->vsn, sizeof (vsn_t), p->resource.archive.vsn);

		if (lst_append(load_infos, info) == -1) {
			Trace(TR_OPRMSG, "lst append failed");
			goto err;
		}
	}

	shmdt(preview_shm.shared_memory);
	*pending_load_infos = load_infos;

	Trace(TR_OPRMSG, "returned pending load info list of size [%d]",
	    load_infos->length);
	Trace(TR_MISC, "got pending load info");
	return (0);

err:
	if (preview_shm.shared_memory != (void *)-1) {
		shmdt(preview_shm.shared_memory);
	}
	if (load_infos)
		free_list_of_pending_load_info(load_infos);
	if (info)
		free_pending_load_info(info);

	Trace(TR_ERR, "get pending load info failed: %s", samerrmsg);
	return (-1);
}
コード例 #25
0
ファイル: file_util.c プロジェクト: BackupTheBerlios/samqfs
int
list_dir(
	ctx_t *c, int maxentries, char *filepath,
	char *restrictions, sqm_lst_t **direntries) /* ARGSUSED */
{
	int rval = 0;
	DIR *curdir;		/* Variable for directory system calls */
	struct dirent64 *entry;	/* Pointer to a directory entry */
	struct dirent64 *entryp;
	struct stat64 sout;
	restrict_t filter = {0};
	char *data;		/* Pointer to data item to add to list */
	char fullpath[MAXPATHLEN];

	/* Set up wildcard restrictions */
	rval = set_restrict(restrictions, &filter);
	if (rval) {
		return (rval);
	}

	curdir = opendir(filepath); /* Set up to ask for directory entries */
	if (curdir == NULL) {
		return (samrerr(SE_NOSUCHPATH, filepath));
	}

	*direntries = lst_create(); /* Return results in this list */
	if (*direntries == NULL) {
		closedir(curdir);
		return (-1);	/* If allocation failed, samerr is set */
	}

	entry = mallocer(sizeof (struct dirent64) + MAXPATHLEN + 1);
	if (entry == NULL) {
		closedir(curdir);
		lst_free(*direntries);
		*direntries = NULL;
		return (-1);
	}

	/* Walk through directory entries */
	while ((rval = readdir64_r(curdir, entry, &entryp)) == 0) {
		if (entryp == NULL) {
			break;
		}

		if ((strcmp(entry->d_name, ".") == 0) ||
		    (strcmp(entry->d_name, "..") == 0)) {
			continue;
		}
		/* Create full pathname and get stat info */
		snprintf(
		    fullpath, MAXPATHLEN, "%s/%s", filepath,
		    entry->d_name);

		if (stat64(fullpath, &sout) != 0) {
			continue; /* Ignore file which can't be stat'ed */
		}

		if (check_restrict_stat(entry->d_name, &sout, &filter))
			continue; /* Not this entry */

		data = copystr(entry->d_name); /* Copy data to allocated mem */
		if (data == NULL) {
			rval = -1;
			break;	/* samerr already set */
		}
		lst_append(*direntries, data);
		if ((*direntries)->length >= maxentries)
			break;	/* Keep list to designated limits */
	}
	free(entry);

	if (rval) {
		lst_free_deep(*direntries); /* On failure, don't return list */
		*direntries = NULL;
	} else {
		lst_qsort(*direntries, node_cmp);
	}
	closedir(curdir);
	return (rval);
}