/* * 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); }
/* * 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); }
/* * 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); }
/* 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); }
/* * 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); }
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; }
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); }
/* * 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); } } }
/* * 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"); }
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); }
/* * 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); }
/* * 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: ; } }
/* * 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; }
/* * 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); } }
/* * 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); }
/* * 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); }
/* * 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, ¶ms) != 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, ¶ms) != 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); }
/* * 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); }
/* 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); }
/* * 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); }
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; }
/* * 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); }
/* * 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); }
/* * 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); }
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); }