/
githubmirror
/
lsof
Обзор
Документация
Войти
/
githubmirror
/
lsof
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
4.96.4
dialects/sun/dnode2.c
517 строк
13 KB
Masatake YAMATO
Use LSOF_ERROR as the exit status reported when an error occurs
18 апр 2022, 08:54
18 апр 2022, 08:54
34fab02
Код
Авторство
О чём код?
/* * dnode2.c - Solaris node functions for lsof * * This module must be separate to keep separate the multiple kernel inode * structure definitions. */ /* * Copyright 1997 Purdue Research Foundation, West Lafayette, Indiana * 47907. All rights reserved. * * Written by Victor A. Abell * * This software is not subject to any license of the American Telephone * and Telegraph Company or the Regents of the University of California. * * Permission is granted to anyone to use this software for any purpose on * any computer system, and to alter it and redistribute it freely, subject * to the following restrictions: * * 1. Neither the authors nor Purdue University are responsible for any * consequences of the use of this software. * * 2. The origin of this software must not be misrepresented, either by * explicit claim or by omission. Credit to the authors and Purdue * University must appear in documentation and sources. * * 3. Altered versions must be plainly marked as such, and must not be * misrepresented as being the original software. * * 4. This notice may not be removed or altered. */ #ifndef lint static char copyright[] = "@(#) Copyright 1994 Purdue Research Foundation.\nAll rights reserved.\n"; #endif #include "lsof.h" #if defined(HASVXFS) # if defined(HASVXFSUTIL) #include <vxfsutil.h> #define EMSGPFX "vx_inode: " _PROTOTYPE(static char *add2em,(char * em, char *fmt, char *arg)); _PROTOTYPE(static char *ckptr,(char * em, char *ptr, int len, int slen, char *nm)); _PROTOTYPE(static char *getioffs,(char **vx, int *vxl, char **dev, int *devl, char **ino, int *inol, char **nl, int *nll, char **sz, int *szl)); # else /* !defined(HASVXFSUTIL) */ # if defined(HASVXFS_FS_H) && !defined(HASVXFS_VX_INODE) #undef fs_bsize #include <sys/fs/vx_fs.h> # endif /* defined(HASVXFS_FS_H) && !defined(HASVXFS_VX_INODE) */ # if HASVXFS_SOL_H #include <sys/fs/vx_sol.h> # endif /* defined(HSVXFS_SOL_H) */ # if defined(HASVXFS_SOLARIS_H) && defined(HASVXFS_U64_T) #include <sys/fs/vx_solaris.h> # endif /* defined(HASVXFS_SOLARIS_H) && defined(HASVXFS_U64_T) */ # if defined(HASVXFS_MACHDEP_H) # if defined(HASVXFS_OFF32_T) && solaris>=70000 #define off32_t VXFS_off32_t # endif /* defined(HASVXFS_OFF32_T) && solaris>=70000 */ #include <sys/fs/vx_machdep.h> # endif /* defined(HASVXFS_MACHDEP_H) */ # if defined(HASVXFS_SOLARIS_H) struct kdm_vnode { /* dummy for <sys/fs/vx_inode.h> */ int d1; }; #undef fs_bsize #define uint16_t VXFS_uint16_t # if defined(HASVXFS_OFF64_T) #define off64_t VXFS_off64_t # endif /* defined(HASVXFS_OFF64_T) */ # if defined(HASVXFS_SOLARIS_H) && !defined(HASVXFS_U64_T) #include <sys/fs/vx_solaris.h> # endif /* defined(HASVXFS_SOLARIS_H) && !defined(HASVXFS_U64_T) */ #include <sys/fs/vx_layout.h> #include <sys/fs/vx_const.h> #include <sys/fs/vx_mlink.h> # endif /* defined(HASVXFS_SOLARIS_H) */ #include <sys/fs/vx_inode.h> # endif /* defined(HASVXFSUTIL) */ # if defined(HASVXFSUTIL) static struct vx_ioffsets Ioffsets; /* VXFS inode offsets */ static int Ioffs_state = -1; /* Ioffsets state: * -1 = uninitialized * 0 = initialized * >0 = initialization error */ /* * access_vxfs_ioffsets() - access the VXFS inode offsets */ extern int access_vxfs_ioffsets() { /* * This operation is done in an external function, so it can be done before * GID permission has been surrendered. */ Ioffs_state = vxfsu_get_ioffsets(&Ioffsets, sizeof(Ioffsets)); return(Ioffs_state); } /* * add2em() - add to error message */ static char * add2em(em, fmt, arg) char *em; /* current error message */ char *fmt; /* message format */ char *arg; /* format's single string argument */ { MALLOC_S al, eml, nl; char msg[1024]; MALLOC_S msgl = (MALLOC_S)sizeof(msg); (void) snpf(msg, msgl, fmt, arg); msg[msgl - 1] = '\0'; nl = (MALLOC_S)strlen(msg); if (!em) { al = (MALLOC_S)strlen(EMSGPFX) + nl + 1; em = (char *)malloc((MALLOC_S)al); eml = (MALLOC_S)0; } else { if (!(eml = (MALLOC_S)strlen(em))) { (void) fprintf(stderr, "%s: add2em: previous message empty\n", Pn); Error(); } al = eml + nl + 3; em = (char *)realloc((MALLOC_P *)em, al); } if (!em) { (void) fprintf(stderr, "%s: no VxFS error message space\n", Pn); Error(); } (void) snpf(em + eml, al - eml, "%s%s%s", eml ? "" : EMSGPFX, eml ? "; " : "", msg); return(em); } /* * ckptr() - check pointer and length */ static char * ckptr(em, ptr, len, slen, nm) char *em; /* pointer to previous error message */ char *ptr; /* pointer to check */ int len; /* pointer's value length */ int slen; /* value's storage length */ char *nm; /* element name */ { #if defined(_LP64) #define PTR_CAST unsigned long long #else /* !defined(_LP64) */ #define PTR_CAST unsigned long #endif /* defined(_LP64) */ PTR_CAST m; char tbuf[1024]; if (!ptr) return(add2em(em, "no %s pointer", nm ? nm : "(null)")); if (len > slen) { (void) snpf(tbuf, sizeof(tbuf) - 1, "%s size, %d, > %d", nm ? nm : "(null)", len, slen); tbuf[sizeof(tbuf) - 1] = '\0'; return(add2em(em, "%s", tbuf)); } if ((m = (PTR_CAST)(len - 1)) < (PTR_CAST)1) return(em); if ((PTR_CAST)ptr & m) return(add2em(em, "%s misaligned", nm ? nm : "(null)")); return(em); } /* * getioffs() - get the vx_inode offsets */ static char * getioffs(vx, vxl, dev, devl, ino, inol, nl, nll, sz, szl) char **vx; /* pointer to allocated vx_inode space */ int *vxl; /* sizeof(*vx) */ char **dev; /* pointer to device number element of *vx */ int *devl; /* sizeof(*dev) */ char **ino; /* pointer to node number element of *vx */ int *inol; /* sizeof(*ino) */ char **nl; /* pointer to nlink element of *vx */ int *nll; /* sizeof(*nl) */ char **sz; /* pointer to size element of *vx */ int *szl; /* sizeof(*sz) */ { char *tv; int tvl; if (Ioffs_state) return(add2em((char *)NULL, "%s error", "vxfsu_get_ioffsets")); tvl = (int)(Ioffsets.ioff_dev + Ioffsets.ioff_dev_sz); if ((Ioffsets.ioff_nlink + Ioffsets.ioff_nlink_sz) > tvl) tvl = (int)(Ioffsets.ioff_nlink + Ioffsets.ioff_nlink_sz); if ((Ioffsets.ioff_number + Ioffsets.ioff_number_sz) > tvl) tvl = (int)(Ioffsets.ioff_number + Ioffsets.ioff_number_sz); if ((Ioffsets.ioff_size + Ioffsets.ioff_size_sz) > tvl) tvl = (int)(Ioffsets.ioff_size + Ioffsets.ioff_size_sz); if (!tvl) return(add2em((char *)NULL, "zero length %s", "vx_inode")); if (!(tv = (char *)malloc((MALLOC_S)tvl))) { (void) fprintf(stderr, "%s: no vx_inode space\n", Pn); Error(); } *vx = tv; *vxl = tvl; *dev = tv + Ioffsets.ioff_dev; *devl = (int)Ioffsets.ioff_dev_sz; *ino = tv + Ioffsets.ioff_number; *inol = (int)Ioffsets.ioff_number_sz; *nl = tv + Ioffsets.ioff_nlink; *nll = (int)Ioffsets.ioff_nlink_sz; *sz = tv + Ioffsets.ioff_size; *szl = (int)Ioffsets.ioff_size_sz; return((char *)NULL); } # if defined(HASVXFSRNL) #define RNLCINIT 64 /* inital RNL cache size */ #define RNLCINCR 32 /* RNL cache increment */ /* * print_vxfs_rnl_path() -- print VxFS RNL path */ int print_vxfs_rnl_path(lf) struct lfile *lf; /* file whose name is to be printed */ { char **bp = (char **)NULL; int i, j, n, p; typedef struct rmc { /* RNL mount point cache */ char *mp; /* mount point */ unsigned char s; /* RNL status: 0 = supported * 1 = not supported */ } rmc_t; static rmc_t *rm = (rmc_t *)NULL; /* RNL mount point cache */ static int rma = 0; /* allocated cache entries */ static int rmu = 0; /* used cache entries */ size_t sz; /* * This must be a VxFS file, it must have an inode and its mount point must * be known. */ if (!lf->is_vxfs || (lf->inp_ty != 1) || !lf->fsdir) return(0); /* * Locate or create an RNL mount point cache entry. */ for (i = 0; i < rmu; i++) { if (rm[i].mp == lf->fsdir) break; } if (i >= rmu) { /* * A new entry must be created. */ if (i >= rma) { /* * RNL mount point cache space must be allocated. */ rma += rm ? RNLCINCR : RNLCINIT; sz = (size_t)(rma * sizeof(rmc_t)); if (rm) rm = (rmc_t *)realloc((MALLOC_P *)rm, (MALLOC_S)sz); else rm = (rmc_t *)malloc((MALLOC_S)sz); if (!rm) { (void) fprintf(stderr, "%s: no RNL mount point cache space\n", Pn); Error(); } } i = rmu; rm[rmu].mp = lf->fsdir; rm[rmu++].s = 0; } if (rm[i].s) return(0); /* * Get the RNL path for this mount point and inode. */ if (vxfs_inotopath(lf->fsdir, (uint64_t)lf->inode, 0, &bp, &n)) { if (errno == ENOTSUP) rm[i].s = 1; return(0); } /* * Print the first RNL path, then free the allocated function reply space. */ if (bp) { for (j = 0; j < n; j++) { if (bp[j] && *bp[j]) { safestrprt(bp[j], stdout, 0); p = 1; break; } } for (j = 0; j < n; j++) { if (bp[j]) (void) free((FREE_P *)bp[j]); } (void) free((FREE_P *)bp); } else p = 0; return(p); } # endif /* defined(HASVXFSRNL) */ # endif /* defined(HASVXFSUTIL) */ /* * read_vxnode() - read Veritas file system inode information */ int read_vxnode(va, v, vfs, fx, li, vnops) KA_T va; /* containing vnode's address */ struct vnode *v; /* containing vnode */ struct l_vfs *vfs; /* local vfs structure */ int fx; /* file system index (-1 if none) */ struct l_ino *li; /* local inode value receiver */ KA_T *vnops; /* table of VxFS v_op values */ { struct vnode cv; char tbuf[32]; # if defined(HASVXFS_VX_INODE) struct vx_inode vx; int vxl = (int)sizeof(vx); dev_t *vxn_dev = (dev_t *)&vx.i_dev; int *vxn_nlink = (int *)&vx.i_nlink; unsigned int *vxn_ino = (unsigned int *)&vx.i_number; SZOFFTYPE *vxn_sz = (SZOFFTYPE *)&vx.i_size; char *vxp = (char *)&vx; # else /* !defined(HASVXFS_VX_INODE) */ # if defined(HASVXFSUTIL) static char *em = (char *)NULL; int devl, nll, szl; static int inol; static char *vxp = (char *)NULL; static int vxl = 0; static dev_t *vxn_dev = (dev_t *)NULL; static int *vxn_nlink = (int *)NULL; static char *vxn_ino = (char *)NULL; static SZOFFTYPE *vxn_sz = (SZOFFTYPE *)NULL; # else /* !defined(HASVXFSUTIL) */ struct inode vx; int vxl = sizeof(vx); dev_t *vxn_dev = (dev_t *)&vx.i_dev; int *vxn_nlink = (int *)&vx.i_nlink; long *vxn_ino = (long *)&vx.i_number; SZOFFTYPE *vxn_sz = (SZOFFTYPE *)&vx.i_size; char *vxp = (char &)&vx; # endif /* defined(HASVXFSUTIL) */ # endif /* defined(HASVXFS_VX_INODE) */ li->dev_def = li->ino_def = li->nl_def = li->rdev_def = li->sz_def = 0; /* * See if this is vnode is served by fdd_chain_vnops. If it is, its * v_data pointer leads to the "real" vnode. */ if (v->v_data && v->v_op && (VXVOP_FDDCH < VXVOP_NUM) && vnops[VXVOP_FDDCH] && ((KA_T)v->v_op == vnops[VXVOP_FDDCH])) { if (kread((KA_T)v->v_data, (char *)&cv, sizeof(cv))) { (void) snpf(Namech, Namechl, "node at %s: can't read real vx vnode: %s", print_kptr(va, tbuf, sizeof(tbuf)), print_kptr((KA_T)v->v_data, (char *)NULL, 0)); enter_nm(Namech); return(1); } # if defined(HASNCACHE) Lf->na = (KA_T)v->v_data; # endif /* defined(HASNCACHE) */ *v = cv; Ntype = vop2ty(v, fx); } # if defined(HASVXFSUTIL) /* * If libvxfsutil[64].a is in use, establish the vx_inode size and the * locations and sizes of its device, link count, node number, and size * elements. * * If an error was detected while determining the vx_inode values, repeat * the error explanation in the NAME column. */ if (!vxp && !em) { em = getioffs(&vxp, &vxl, (char **)&vxn_dev, &devl, &vxn_ino, &inol, (char **)&vxn_nlink, &nll, (char **)&vxn_sz, &szl); if (!em) { /* * Check the returned pointers and their sizes. */ em = ckptr(em, (char *)vxn_dev, devl, sizeof(dev_t), "dev"); em = ckptr(em, (char *)vxn_ino, inol, sizeof(INODETYPE), "ino"); em = ckptr(em, (char *)vxn_nlink, nll, sizeof(int), "nlink"); em = ckptr(em, (char *)vxn_sz, szl, sizeof(SZOFFTYPE), "sz"); } } if (em) { (void) snpf(Namech, Namechl, "%s", em); (void) enter_nm(Namech); return(1); } # endif /* !defined(HASVXFSUTIL) */ /* * Read vnode's vx_inode. */ if (!v->v_data || kread((KA_T)v->v_data, vxp, vxl)) { (void) snpf(Namech, Namechl, "node at %s: can't read vx_inode: %s", print_kptr(va, tbuf, sizeof(tbuf)), print_kptr((KA_T)v->v_data, (char *)NULL, 0)); (void) enter_nm(Namech); return(1); } /* * Return device number, inode number, link count, raw device number, and size. */ if (vfs && vfs->fsname) { li->dev = (dev_t)vfs->dev; li->dev_def = 1; } else if (vxn_dev) { li->dev = (dev_t)*vxn_dev; li->dev_def = 1; } if (vxn_ino) { # if defined(HASVXFSUTIL) switch (inol) { case sizeof(short): li->ino = (INODETYPE)*((short *)vxn_ino); li->ino_def = 1; break; case sizeof(unsigned int): li->ino = (INODETYPE)*((unsigned int *)vxn_ino); li->ino_def = 1; break; case sizeof(unsigned long long): li->ino = (INODETYPE)*((unsigned long long *)vxn_ino); li->ino_def = 1; break; default: break; } # else /* !defined(HASVXFSUTIL) */ li->ino = (INODETYPE)*vxn_ino; li->ino_def = 1; # endif /* defined(HASVXFSUTIL) */ } if (vxn_nlink) { li->nl = (long)*vxn_nlink; li->nl_def = 1; } li->rdev = v->v_rdev; li->rdev_def = 1; if (vxn_sz) { li->sz = (SZOFFTYPE)*vxn_sz; li->sz_def = 1; } return(0); } #endif /* defined(HASVXFS) */