1 /* $OpenBSD: ukc.c,v 1.14 2007/06/28 00:52:37 ray Exp $ */ 2 3 /* 4 * Copyright (c) 1999-2001 Mats O Jansson. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27 #ifndef LINT 28 static char rcsid[] = "$OpenBSD: ukc.c,v 1.14 2007/06/28 00:52:37 ray Exp $"; 29 #endif 30 31 #include <sys/types.h> 32 #include <sys/device.h> 33 #include <sys/ioctl.h> 34 35 #include <err.h> 36 #include <kvm.h> 37 #include <fcntl.h> 38 #include <limits.h> 39 #include <nlist.h> 40 #include <stdio.h> 41 #include <stdlib.h> 42 #include <string.h> 43 #include <unistd.h> 44 45 #define UKC_MAIN 46 #include "ukc.h" 47 #include "exec.h" 48 49 void init(void); 50 void usage(void); 51 52 int ukc_mod_kernel = 0; 53 54 static void 55 check_int(int idx, const char *name) 56 { 57 if (nl[idx].n_type == 0) 58 printf("WARNING this kernel doesn't support modification " 59 "of %s.\n", name); 60 } 61 62 int 63 ukc(char *file, char *outfile, int uflag, int force) 64 { 65 extern char *__progname; 66 int i; 67 kvm_t *kd; 68 char errbuf[_POSIX2_LINE_MAX]; 69 int histlen = 0, ok = 1; 70 char history[1024], kversion[1024]; 71 72 if (file == NULL) { 73 fprintf(stderr, "%s: no file specified\n", __progname); 74 usage(); 75 } 76 77 loadkernel(file); 78 79 if (nlist(file, nl) == -1) 80 errx(1, "nlist: %s", file); 81 82 if (uflag) { 83 if ((kd = kvm_openfiles(NULL,NULL,NULL,O_RDONLY, errbuf)) == 0) 84 errx(1, "kvm_openfiles: %s", errbuf); 85 86 if (kvm_nlist(kd, knl) == -1) 87 errx(1, "kvm_nlist: %s", kvm_geterr(kd)); 88 89 i = 0; 90 while (i < NLENTRIES) { 91 if (nl[i].n_type != knl[i].n_type || 92 nl[i].n_desc != knl[i].n_desc || 93 nl[i].n_value != knl[i].n_value) 94 ok = 0; 95 i++; 96 } 97 98 if (knl[I_HISTLEN].n_type != 0 && ok) { 99 if (kvm_read(kd, knl[I_HISTLEN].n_value, &histlen, 100 sizeof(histlen)) != sizeof(histlen)) 101 warnx("cannot read %s: %s", 102 knl[I_HISTLEN].n_name, 103 kvm_geterr(kd)); 104 } 105 if (knl[CA_HISTORY].n_type != 0 && ok) { 106 if (kvm_read(kd, knl[CA_HISTORY].n_value, history, 107 sizeof(history)) != sizeof(history)) 108 warnx("cannot read %s: %s", 109 knl[CA_HISTORY].n_name, 110 kvm_geterr(kd)); 111 } 112 if (knl[P_VERSION].n_type != 0 && ok) { 113 if (kvm_read(kd, knl[P_VERSION].n_value, kversion, 114 sizeof(kversion)) != sizeof(kversion)) 115 warnx("cannot read %s: %s", 116 knl[P_VERSION].n_name, 117 kvm_geterr(kd)); 118 } 119 } 120 121 printf("%s", adjust((caddr_t)nl[P_VERSION].n_value)); 122 123 if (force == 0 && outfile == NULL) 124 printf("warning: no output file specified\n"); 125 126 if (nl[IA_EXTRALOC].n_type == 0 || nl[I_NEXTRALOC].n_type == 0 || 127 nl[I_UEXTRALOC].n_type == 0 || nl[I_HISTLEN].n_type == 0 || 128 nl[CA_HISTORY].n_type == 0) { 129 printf("\ 130 WARNING this kernel doesn't contain all information needed!\n\ 131 WARNING the commands add and change might not work.\n"); 132 oldkernel = 1; 133 } 134 135 if (nl[P_PDEVNAMES].n_type == 0 || 136 nl[I_PDEVSIZE].n_type == 0 || 137 nl[S_PDEVINIT].n_type == 0) { 138 printf("\ 139 WARNING this kernel doesn't support pseudo devices.\n"); 140 nopdev = 1; 141 } 142 143 check_int(I_BUFCACHEPCT, "BUFCACHEPERCENT"); 144 check_int(I_NKMEMPG, "NKMEMPAGES"); 145 check_int(I_SHMSEG, "SHMSEG"); 146 check_int(I_SHMMAXPGS, "SHMMAXPGS"); 147 148 init(); 149 150 if (uflag) { 151 if (ok) { 152 if (strcmp(adjust((caddr_t)nl[P_VERSION].n_value), 153 kversion) != 0) 154 ok = 1; 155 } 156 if (!ok) { 157 printf("WARNING kernel mismatch. -u ignored.\n"); 158 printf("WARNING the running kernel version:\n"); 159 printf("%s", kversion); 160 } else 161 process_history(histlen, history); 162 } 163 164 if (config()) { 165 if (force == 0 && outfile == NULL) { 166 fprintf(stderr, "not forced\n"); 167 return (1); 168 } 169 if (outfile == NULL) 170 outfile = file; 171 if (ukc_mod_kernel == 0) { 172 fprintf(stderr, "Kernel not modified\n"); 173 return (1); 174 } else { 175 printf ("Saving modified kernel.\n"); 176 savekernel(outfile); 177 } 178 } 179 return(0); 180 } 181 182 void 183 init(void) 184 { 185 int i = 0, fd; 186 struct cfdata *cd; 187 short *ln; 188 int *p; 189 #ifdef NOTDEF 190 struct winsize w; 191 #endif 192 193 cd = get_cfdata(0); /* get first item */ 194 while (cd->cf_attach != 0) { 195 maxdev = i; 196 totdev = i; 197 198 ln = get_locnamp(cd->cf_locnames); 199 while (*ln != -1) { 200 if (*ln > maxlocnames) 201 maxlocnames = *ln; 202 ln++; 203 } 204 i++; 205 cd++; 206 } 207 208 while (cd->cf_attach == 0) { 209 totdev = i; 210 i++; 211 cd++; 212 } 213 214 totdev = totdev - 1; 215 216 if (nopdev == 0) { 217 p = (int *)adjust((caddr_t)nl[I_PDEVSIZE].n_value); 218 maxpseudo = *p; 219 } 220 221 if ((fd = open("/dev/tty", O_RDWR)) < 0) 222 fd = 2; 223 224 #ifdef NOTDEF 225 if (ioctl(fd, TIOCGWINSZ, &w) == 0) 226 printf("row %d col %d\n", w.ws_row, w.ws_col); 227 228 if ((s = getenv("LINES")) != NULL) 229 sc_height = atoi(s); 230 else 231 sc_height = tgetnum("li"); 232 233 if (sc_height <= 0) 234 sc_height = 24; 235 236 if ((s = getenv("COLUMNS")) != NULL) 237 sc_width = atoi(s); 238 else 239 sc_width = tgetnum("co"); 240 241 if (sc_width <= 0) 242 sc_width = 80; 243 #endif 244 } 245