| File: | src/bin/ps/keyword.c |
| Warning: | line 240, column 16 Access to field 'next' results in a dereference of a null pointer (loaded from variable 'vtail') |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | /* $OpenBSD: keyword.c,v 1.49 2022/01/05 04:10:36 guenther Exp $ */ | |||
| 2 | /* $NetBSD: keyword.c,v 1.12.6.1 1996/05/30 21:25:13 cgd Exp $ */ | |||
| 3 | ||||
| 4 | /*- | |||
| 5 | * Copyright (c) 1990, 1993, 1994 | |||
| 6 | * The Regents of the University of California. All rights reserved. | |||
| 7 | * | |||
| 8 | * Redistribution and use in source and binary forms, with or without | |||
| 9 | * modification, are permitted provided that the following conditions | |||
| 10 | * are met: | |||
| 11 | * 1. Redistributions of source code must retain the above copyright | |||
| 12 | * notice, this list of conditions and the following disclaimer. | |||
| 13 | * 2. Redistributions in binary form must reproduce the above copyright | |||
| 14 | * notice, this list of conditions and the following disclaimer in the | |||
| 15 | * documentation and/or other materials provided with the distribution. | |||
| 16 | * 3. Neither the name of the University nor the names of its contributors | |||
| 17 | * may be used to endorse or promote products derived from this software | |||
| 18 | * without specific prior written permission. | |||
| 19 | * | |||
| 20 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | |||
| 21 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||
| 22 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||
| 23 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |||
| 24 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |||
| 25 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |||
| 26 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |||
| 27 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |||
| 28 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |||
| 29 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||
| 30 | * SUCH DAMAGE. | |||
| 31 | */ | |||
| 32 | ||||
| 33 | #include <sys/param.h> /* MAXCOMLEN */ | |||
| 34 | #include <sys/time.h> | |||
| 35 | #include <sys/resource.h> | |||
| 36 | ||||
| 37 | #include <err.h> | |||
| 38 | #include <errno(*__errno()).h> | |||
| 39 | #include <stddef.h> | |||
| 40 | #include <stdio.h> | |||
| 41 | #include <stdlib.h> | |||
| 42 | #include <string.h> | |||
| 43 | ||||
| 44 | #include "ps.h" | |||
| 45 | ||||
| 46 | #include <sys/ucred.h> | |||
| 47 | #include <sys/sysctl.h> | |||
| 48 | ||||
| 49 | int needheader; | |||
| 50 | ||||
| 51 | static VAR *findvar(char *); | |||
| 52 | static int vcmp(const void *, const void *); | |||
| 53 | ||||
| 54 | #ifdef NOTINUSE | |||
| 55 | int utime(), stime(), ixrss(), idrss(), isrss(); | |||
| 56 | {{"utime"}, "UTIME", USER0x04, utime, 4}, | |||
| 57 | {{"stime"}, "STIME", USER0x04, stime, 4}, | |||
| 58 | {{"ixrss"}, "IXRSS", USER0x04, ixrss, 4}, | |||
| 59 | {{"idrss"}, "IDRSS", USER0x04, idrss, 4}, | |||
| 60 | {{"isrss"}, "ISRSS", USER0x04, isrss, 4}, | |||
| 61 | #endif | |||
| 62 | ||||
| 63 | /* Compute offset in common structures. */ | |||
| 64 | #define POFF(x)__builtin_offsetof(struct kinfo_proc, x) offsetof(struct kinfo_proc, x)__builtin_offsetof(struct kinfo_proc, x) | |||
| 65 | ||||
| 66 | #define UIDFMT"u" "u" | |||
| 67 | #define UIDLEN5 5 | |||
| 68 | #define UID(n1, n2, fn, off){ n1, n2, ((void*)0), 0, fn, 5, 0, off, UINT32, "u" } \ | |||
| 69 | { n1, n2, NULL((void*)0), 0, fn, UIDLEN5, 0, off, UINT32, UIDFMT"u" } | |||
| 70 | #define GID(n1, n2, fn, off){ n1, n2, ((void*)0), 0, fn, 5, 0, off, UINT32, "u" } UID(n1, n2, fn, off){ n1, n2, ((void*)0), 0, fn, 5, 0, off, UINT32, "u" } | |||
| 71 | ||||
| 72 | #define PIDFMT"d" "d" | |||
| 73 | #define PIDLEN5 5 | |||
| 74 | #define PID(n1, n2, fn, off){ n1, n2, ((void*)0), 0, fn, 5, 0, off, INT32, "d" } \ | |||
| 75 | { n1, n2, NULL((void*)0), 0, fn, PIDLEN5, 0, off, INT32, PIDFMT"d" } | |||
| 76 | ||||
| 77 | #define TIDFMT"d" "d" | |||
| 78 | #define TIDLEN7 7 | |||
| 79 | #define TID(n1, n2, fn, off){ n1, n2, ((void*)0), 0, fn, 7, 0, off, INT32, "d" } \ | |||
| 80 | { n1, n2, NULL((void*)0), 0, fn, TIDLEN7, 0, off, INT32, TIDFMT"d" } | |||
| 81 | ||||
| 82 | #define USERLEN8 8 | |||
| 83 | #define CWDLEN40 40 | |||
| 84 | ||||
| 85 | /* Bit types must match their respective entries in struct kinfo_proc */ | |||
| 86 | /* Entries must be sorted in lexical ascending order! */ | |||
| 87 | VAR var[] = { | |||
| 88 | {"%cpu", "%CPU", NULL((void*)0), NLIST0x10, pcpu, 4}, | |||
| 89 | {"%mem", "%MEM", NULL((void*)0), NLIST0x10, pmem, 4}, | |||
| 90 | {"acflag", "ACFLG", NULL((void*)0), 0, pvar, 3, 0, POFF(p_acflag)__builtin_offsetof(struct kinfo_proc, p_acflag), UINT16, "x"}, | |||
| 91 | {"acflg", "", "acflag"}, | |||
| 92 | {"args", "", "command"}, | |||
| 93 | {"blocked", "", "sigmask"}, | |||
| 94 | {"caught", "", "sigcatch"}, | |||
| 95 | {"comm", "COMMAND", "ucomm"}, | |||
| 96 | {"command", "COMMAND", NULL((void*)0), COMM0x01|LJUST0x02|USER0x04, command, 16}, | |||
| 97 | {"cpu", "CPU", NULL((void*)0), 0, pvar, 3, 0, POFF(p_estcpu)__builtin_offsetof(struct kinfo_proc, p_estcpu), UINT32, "d"}, | |||
| 98 | {"cpuid", "CPUID", NULL((void*)0), 0, pvar, 8, 0, POFF(p_cpuid)__builtin_offsetof(struct kinfo_proc, p_cpuid), UINT64, "lld"}, | |||
| 99 | {"cputime", "", "time"}, | |||
| 100 | {"cwd", "CWD", NULL((void*)0), LJUST0x02, curwd, CWDLEN40}, | |||
| 101 | {"dsiz", "DSIZ", NULL((void*)0), 0, dsize, 4}, | |||
| 102 | {"etime", "ELAPSED", NULL((void*)0), USER0x04, elapsed, 12}, | |||
| 103 | {"f", "F", NULL((void*)0), 0, pvar, 7, 0, POFF(p_flag)__builtin_offsetof(struct kinfo_proc, p_flag), INT32, "x"}, | |||
| 104 | {"flags", "", "f"}, | |||
| 105 | GID("gid", "GID", pvar, POFF(p_gid)){ "gid", "GID", ((void*)0), 0, pvar, 5, 0, __builtin_offsetof (struct kinfo_proc, p_gid), UINT32, "u" }, | |||
| 106 | {"group", "GROUP", NULL((void*)0), LJUST0x02, gname, USERLEN8}, | |||
| 107 | {"ignored", "", "sigignore"}, | |||
| 108 | {"inblk", "INBLK", NULL((void*)0), USER0x04, pvar, 4, 0, POFF(p_uru_inblock)__builtin_offsetof(struct kinfo_proc, p_uru_inblock), UINT64, "lld"}, | |||
| 109 | {"inblock", "", "inblk"}, | |||
| 110 | {"jobc", "JOBC", NULL((void*)0), 0, pvar, 4, 0, POFF(p_jobc)__builtin_offsetof(struct kinfo_proc, p_jobc), INT16, "d"}, | |||
| 111 | {"ktrace", "KTRACE", NULL((void*)0), 0, pvar, 8, 0, POFF(p_traceflag)__builtin_offsetof(struct kinfo_proc, p_traceflag), INT32, "x"}, | |||
| 112 | /* XXX */ | |||
| 113 | {"ktracep", "KTRACEP", NULL((void*)0), 0, pvar, PTRWIDTH16, 0, POFF(p_tracep)__builtin_offsetof(struct kinfo_proc, p_tracep), UINT64, "llx"}, | |||
| 114 | {"lim", "LIM", NULL((void*)0), 0, maxrss, 5}, | |||
| 115 | {"login", "LOGIN", NULL((void*)0), LJUST0x02, logname, LOGIN_NAME_MAX32}, | |||
| 116 | {"logname", "", "login"}, | |||
| 117 | {"lstart", "STARTED", NULL((void*)0), LJUST0x02|USER0x04, lstarted, 28}, | |||
| 118 | {"majflt", "MAJFLT", NULL((void*)0), USER0x04, pvar, 4, 0, POFF(p_uru_majflt)__builtin_offsetof(struct kinfo_proc, p_uru_majflt), UINT64, "lld"}, | |||
| 119 | {"maxrss", "MAXRSS", NULL((void*)0), USER0x04, pvar, 4, 0, POFF(p_uru_maxrss)__builtin_offsetof(struct kinfo_proc, p_uru_maxrss), UINT64, "lld"}, | |||
| 120 | {"minflt", "MINFLT", NULL((void*)0), USER0x04, pvar, 4, 0, POFF(p_uru_minflt)__builtin_offsetof(struct kinfo_proc, p_uru_minflt), UINT64, "lld"}, | |||
| 121 | {"msgrcv", "MSGRCV", NULL((void*)0), USER0x04, pvar, 4, 0, POFF(p_uru_msgrcv)__builtin_offsetof(struct kinfo_proc, p_uru_msgrcv), UINT64, "lld"}, | |||
| 122 | {"msgsnd", "MSGSND", NULL((void*)0), USER0x04, pvar, 4, 0, POFF(p_uru_msgsnd)__builtin_offsetof(struct kinfo_proc, p_uru_msgsnd), UINT64, "lld"}, | |||
| 123 | {"ni", "", "nice"}, | |||
| 124 | {"nice", "NI", NULL((void*)0), 0, pnice, 3}, | |||
| 125 | {"nivcsw", "NIVCSW", NULL((void*)0), USER0x04, pvar, 5, 0, POFF(p_uru_nivcsw)__builtin_offsetof(struct kinfo_proc, p_uru_nivcsw), UINT64, "lld"}, | |||
| 126 | {"nsignals", "", "nsigs"}, | |||
| 127 | {"nsigs", "NSIGS", NULL((void*)0), USER0x04, pvar, 4, 0, POFF(p_uru_nsignals)__builtin_offsetof(struct kinfo_proc, p_uru_nsignals), UINT64, "lld"}, | |||
| 128 | {"nswap", "NSWAP", NULL((void*)0), USER0x04, pvar, 4, 0, POFF(p_uru_nswap)__builtin_offsetof(struct kinfo_proc, p_uru_nswap), UINT64, "lld"}, | |||
| 129 | {"nvcsw", "NVCSW", NULL((void*)0), USER0x04, pvar, 5, 0, POFF(p_uru_nvcsw)__builtin_offsetof(struct kinfo_proc, p_uru_nvcsw), UINT64, "lld"}, | |||
| 130 | /* XXX */ | |||
| 131 | {"nwchan", "WCHAN", NULL((void*)0), 0, pvar, PTRWIDTH16, 0, POFF(p_wchan)__builtin_offsetof(struct kinfo_proc, p_wchan), UINT64, "llx"}, | |||
| 132 | {"oublk", "OUBLK", NULL((void*)0), USER0x04, pvar, 4, 0, POFF(p_uru_oublock)__builtin_offsetof(struct kinfo_proc, p_uru_oublock), UINT64, "lld"}, | |||
| 133 | {"oublock", "", "oublk"}, | |||
| 134 | /* XXX */ | |||
| 135 | {"p_ru", "P_RU", NULL((void*)0), 0, pvar, PTRWIDTH16, 0, POFF(p_ru)__builtin_offsetof(struct kinfo_proc, p_ru), UINT64, "llx"}, | |||
| 136 | /* XXX */ | |||
| 137 | {"paddr", "PADDR", NULL((void*)0), 0, pvar, PTRWIDTH16, 0, POFF(p_paddr)__builtin_offsetof(struct kinfo_proc, p_paddr), UINT64, "llx"}, | |||
| 138 | {"pagein", "PAGEIN", NULL((void*)0), USER0x04, pagein, 6}, | |||
| 139 | {"pcpu", "", "%cpu"}, | |||
| 140 | {"pending", "", "sig"}, | |||
| 141 | PID("pgid", "PGID", pvar, POFF(p__pgid)){ "pgid", "PGID", ((void*)0), 0, pvar, 5, 0, __builtin_offsetof (struct kinfo_proc, p__pgid), INT32, "d" }, | |||
| 142 | PID("pid", "PID", pvar, POFF(p_pid)){ "pid", "PID", ((void*)0), 0, pvar, 5, 0, __builtin_offsetof (struct kinfo_proc, p_pid), INT32, "d" }, | |||
| 143 | {"pledge", "PLEDGE", NULL((void*)0), LJUST0x02|NLIST0x10, printpledge, 64}, | |||
| 144 | {"pmem", "", "%mem"}, | |||
| 145 | PID("ppid", "PPID", pvar, POFF(p_ppid)){ "ppid", "PPID", ((void*)0), 0, pvar, 5, 0, __builtin_offsetof (struct kinfo_proc, p_ppid), INT32, "d" }, | |||
| 146 | {"pri", "PRI", NULL((void*)0), 0, pri, 3}, | |||
| 147 | {"procflags", "PROCF", NULL((void*)0), 0, pvar, 7, 0, POFF(p_psflags)__builtin_offsetof(struct kinfo_proc, p_psflags), INT32, "x"}, | |||
| 148 | {"re", "RE", NULL((void*)0), INF1270x08, pvar, 3, 0, POFF(p_swtime)__builtin_offsetof(struct kinfo_proc, p_swtime), UINT32, "u"}, | |||
| 149 | GID("rgid", "RGID", pvar, POFF(p_rgid)){ "rgid", "RGID", ((void*)0), 0, pvar, 5, 0, __builtin_offsetof (struct kinfo_proc, p_rgid), UINT32, "u" }, | |||
| 150 | /* XXX */ | |||
| 151 | {"rgroup", "RGROUP", NULL((void*)0), LJUST0x02, rgname, USERLEN8}, | |||
| 152 | {"rlink", "RLINK", NULL((void*)0), 0, pvar, 8, 0, POFF(p_back)__builtin_offsetof(struct kinfo_proc, p_back), UINT64, "llx"}, | |||
| 153 | {"rss", "RSS", NULL((void*)0), 0, p_rssize, 5}, | |||
| 154 | {"rssize", "", "rsz"}, | |||
| 155 | {"rsz", "RSZ", NULL((void*)0), 0, rssize, 4}, | |||
| 156 | {"rtable", "RTABLE", NULL((void*)0), 0, pvar, 0, 0, POFF(p_rtableid)__builtin_offsetof(struct kinfo_proc, p_rtableid), INT32, "d"}, | |||
| 157 | UID("ruid", "RUID", pvar, POFF(p_ruid)){ "ruid", "RUID", ((void*)0), 0, pvar, 5, 0, __builtin_offsetof (struct kinfo_proc, p_ruid), UINT32, "u" }, | |||
| 158 | {"ruser", "RUSER", NULL((void*)0), LJUST0x02, runame, USERLEN8}, | |||
| 159 | {"sess", "SESS", NULL((void*)0), 0, pvar, PTRWIDTH16, 0, POFF(p_sess)__builtin_offsetof(struct kinfo_proc, p_sess), UINT64, "llx"}, | |||
| 160 | {"sig", "PENDING", NULL((void*)0), 0, pvar, 8, 0, POFF(p_siglist)__builtin_offsetof(struct kinfo_proc, p_siglist), INT32, "x"}, | |||
| 161 | {"sigcatch", "CAUGHT", NULL((void*)0), 0, pvar, 8, 0, POFF(p_sigcatch)__builtin_offsetof(struct kinfo_proc, p_sigcatch), UINT32, "x"}, | |||
| 162 | {"sigignore", "IGNORED", | |||
| 163 | NULL((void*)0), 0, pvar, 8, 0, POFF(p_sigignore)__builtin_offsetof(struct kinfo_proc, p_sigignore), UINT32, "x"}, | |||
| 164 | {"sigmask", "BLOCKED", NULL((void*)0), 0, pvar, 8, 0, POFF(p_sigmask)__builtin_offsetof(struct kinfo_proc, p_sigmask), UINT32, "x"}, | |||
| 165 | {"sl", "SL", NULL((void*)0), INF1270x08, pvar, 3, 0, POFF(p_slptime)__builtin_offsetof(struct kinfo_proc, p_slptime), UINT32, "u"}, | |||
| 166 | {"ssiz", "SSIZ", NULL((void*)0), 0, ssize, 4}, | |||
| 167 | {"start", "STARTED", NULL((void*)0), LJUST0x02|USER0x04, started, 8}, | |||
| 168 | {"stat", "", "state"}, | |||
| 169 | {"state", "STAT", NULL((void*)0), LJUST0x02|NLIST0x10, printstate, 6}, | |||
| 170 | {"supgid", "SUPGID", NULL((void*)0), LJUST0x02, supgid, 64}, | |||
| 171 | {"supgrp", "SUPGRP", NULL((void*)0), LJUST0x02, supgrp, 64}, | |||
| 172 | GID("svgid", "SVGID", pvar, POFF(p_svgid)){ "svgid", "SVGID", ((void*)0), 0, pvar, 5, 0, __builtin_offsetof (struct kinfo_proc, p_svgid), UINT32, "u" }, | |||
| 173 | UID("svuid", "SVUID", pvar, POFF(p_svuid)){ "svuid", "SVUID", ((void*)0), 0, pvar, 5, 0, __builtin_offsetof (struct kinfo_proc, p_svuid), UINT32, "u" }, | |||
| 174 | {"tdev", "TDEV", NULL((void*)0), 0, tdev, 4}, | |||
| 175 | TID("tid", "TID", pvar, POFF(p_tid)){ "tid", "TID", ((void*)0), 0, pvar, 7, 0, __builtin_offsetof (struct kinfo_proc, p_tid), INT32, "d" }, | |||
| 176 | {"time", "TIME", NULL((void*)0), USER0x04, cputime, 9}, | |||
| 177 | PID("tpgid", "TPGID", pvar, POFF(p_tpgid)){ "tpgid", "TPGID", ((void*)0), 0, pvar, 5, 0, __builtin_offsetof (struct kinfo_proc, p_tpgid), INT32, "d" }, | |||
| 178 | {"tsess", "TSESS", NULL((void*)0), 0, pvar, PTRWIDTH16, 0, POFF(p_tsess)__builtin_offsetof(struct kinfo_proc, p_tsess), UINT64, "llx"}, | |||
| 179 | {"tsiz", "TSIZ", NULL((void*)0), 0, tsize, 4}, | |||
| 180 | {"tt", "TT", NULL((void*)0), LJUST0x02, tname, 3}, | |||
| 181 | {"tty", "TTY", NULL((void*)0), LJUST0x02, longtname, 8}, | |||
| 182 | {"ucomm", "UCOMM", NULL((void*)0), LJUST0x02, ucomm, MAXCOMLEN16}, | |||
| 183 | UID("uid", "UID", pvar, POFF(p_uid)){ "uid", "UID", ((void*)0), 0, pvar, 5, 0, __builtin_offsetof (struct kinfo_proc, p_uid), UINT32, "u" }, | |||
| 184 | {"upr", "UPR", NULL((void*)0), 0, pvar, 3, 0, POFF(p_usrpri)__builtin_offsetof(struct kinfo_proc, p_usrpri), UINT8, "d"}, | |||
| 185 | {"user", "USER", NULL((void*)0), LJUST0x02, euname, USERLEN8}, | |||
| 186 | {"usrpri", "", "upr"}, | |||
| 187 | {"vsize", "", "vsz"}, | |||
| 188 | {"vsz", "VSZ", NULL((void*)0), 0, vsize, 5}, | |||
| 189 | {"wchan", "WCHAN", NULL((void*)0), LJUST0x02, wchan, KI_WMESGLEN8 - 1}, | |||
| 190 | {"xstat", "XSTAT", NULL((void*)0), 0, pvar, 4, 0, POFF(p_xstat)__builtin_offsetof(struct kinfo_proc, p_xstat), UINT16, "x"}, | |||
| 191 | {""}, | |||
| 192 | }; | |||
| 193 | ||||
| 194 | void | |||
| 195 | showkey(void) | |||
| 196 | { | |||
| 197 | VAR *v; | |||
| 198 | int i; | |||
| 199 | char *p, *sep; | |||
| 200 | ||||
| 201 | i = 0; | |||
| 202 | sep = ""; | |||
| 203 | for (v = var; *(p = v->name); ++v) { | |||
| 204 | int len = strlen(p); | |||
| 205 | if (termwidth && (i += len + 1) > termwidth) { | |||
| 206 | i = len; | |||
| 207 | sep = "\n"; | |||
| 208 | } | |||
| 209 | (void) printf("%s%s", sep, p); | |||
| 210 | sep = " "; | |||
| 211 | } | |||
| 212 | (void) printf("\n"); | |||
| 213 | } | |||
| 214 | ||||
| 215 | void | |||
| 216 | parsefmt(char *p) | |||
| 217 | { | |||
| 218 | static struct varent *vtail; | |||
| ||||
| 219 | ||||
| 220 | #define FMTSEP" \t,\n" " \t,\n" | |||
| 221 | while (p && *p) { | |||
| 222 | char *cp; | |||
| 223 | VAR *v; | |||
| 224 | struct varent *vent; | |||
| 225 | ||||
| 226 | while ((cp = strsep(&p, FMTSEP" \t,\n")) != NULL((void*)0) && *cp == '\0') | |||
| 227 | /* void */; | |||
| 228 | if (!cp
| |||
| 229 | break; | |||
| 230 | if (!(v = findvar(cp)) || v->parsed == 1) | |||
| 231 | continue; | |||
| 232 | v->parsed = 1; | |||
| 233 | if ((vent = malloc(sizeof(struct varent))) == NULL((void*)0)) | |||
| 234 | err(1, NULL((void*)0)); | |||
| 235 | vent->var = v; | |||
| 236 | vent->next = NULL((void*)0); | |||
| 237 | if (vhead == NULL((void*)0)) | |||
| 238 | vhead = vtail = vent; | |||
| 239 | else { | |||
| 240 | vtail->next = vent; | |||
| ||||
| 241 | vtail = vent; | |||
| 242 | } | |||
| 243 | needheader |= v->header[0] != '\0'; | |||
| 244 | } | |||
| 245 | if (!vhead) | |||
| 246 | errx(1, "no valid keywords"); | |||
| 247 | } | |||
| 248 | ||||
| 249 | static VAR * | |||
| 250 | findvar(char *p) | |||
| 251 | { | |||
| 252 | VAR *v, key; | |||
| 253 | char *hp; | |||
| 254 | ||||
| 255 | key.name = p; | |||
| 256 | ||||
| 257 | hp = strchr(p, '='); | |||
| 258 | if (hp) | |||
| 259 | *hp++ = '\0'; | |||
| 260 | ||||
| 261 | aliased: | |||
| 262 | key.name = p; | |||
| 263 | v = bsearch(&key, var, sizeof(var)/sizeof(VAR) - 1, sizeof(VAR), vcmp); | |||
| 264 | ||||
| 265 | if (v && v->alias) { | |||
| 266 | p = v->alias; | |||
| 267 | if (hp == NULL((void*)0) && v->header[0] != '\0') | |||
| 268 | hp = v->header; | |||
| 269 | goto aliased; | |||
| 270 | } | |||
| 271 | if (!v) { | |||
| 272 | warnx("%s: keyword not found", p); | |||
| 273 | eval = 1; | |||
| 274 | return (NULL((void*)0)); | |||
| 275 | } | |||
| 276 | if (hp) | |||
| 277 | v->header = hp; | |||
| 278 | return (v); | |||
| 279 | } | |||
| 280 | ||||
| 281 | static int | |||
| 282 | vcmp(const void *a, const void *b) | |||
| 283 | { | |||
| 284 | return (strcmp(((VAR *)a)->name, ((VAR *)b)->name)); | |||
| 285 | } |