|
|
1.1 ! root 1: /* ! 2: * File: kpatch.c ! 3: * ! 4: * Purpose: ! 5: * This program is not expected to work other than on PC Coherent. ! 6: * Certain hot patches may not be effective, since some values are only ! 7: * referenced once at system initialization. ! 8: * ! 9: */ ! 10: ! 11: /* ! 12: * ---------------------------------------------------------------------- ! 13: * Includes. ! 14: */ ! 15: #include <stdio.h> ! 16: #include <errno.h> ! 17: #include <sys/patch.h> ! 18: #include "patchl.h" ! 19: ! 20: /* ! 21: * ---------------------------------------------------------------------- ! 22: * Definitions. ! 23: * Constants. ! 24: * Macros with argument lists. ! 25: * Typedefs. ! 26: * Enums. ! 27: */ ! 28: #define PATCH_DEVICE_NAME "/dev/patch" ! 29: ! 30: /* ! 31: * ---------------------------------------------------------------------- ! 32: * Functions. ! 33: * Import Functions. ! 34: * Export Functions. ! 35: * Local Functions. ! 36: */ ! 37: ! 38: void main(); ! 39: int arg_getc(); ! 40: ! 41: static int kpatch(); ! 42: static void usage(); ! 43: static int peek_patch(); ! 44: ! 45: /* ! 46: * ---------------------------------------------------------------------- ! 47: * Global Data. ! 48: * Import Variables. ! 49: * Export Variables. ! 50: * Local Variables. ! 51: */ ! 52: extern struct PatchInfo argInfo; /* yyparse puts info here. */ ! 53: ! 54: static char * lex_input; ! 55: static int lex_index; ! 56: ! 57: static int verbose = 0; /* Are we printing feedback? */ ! 58: static int kfd; /* File descriptor for patch device. */ ! 59: ! 60: static char version[] = "kpatch version 1.0 for COHERENT v.4.2"; ! 61: ! 62: static char short_helpmessage[] = "\ ! 63: kpatch -- alter installation kernel\n\ ! 64: Usage: kpatch [-v] \n\ ! 65: { symbol? | symbol=value | symbol:maj:in | symbol:maj:out } ...\n\ ! 66: "; ! 67: ! 68: static char helpmessage[] = "\ ! 69: -v Verbose mode--print what's being done.\n\ ! 70: symbol? Display present value of symbol.\n\ ! 71: symbol=value Store value into symbol.\n\ ! 72: symbol:maj:in If major number maj is not already in use,\n\ ! 73: attach CON struct symbol to driver table at major\n\ ! 74: number maj and call the load routine for the driver.\n\ ! 75: symbol:maj:out If named CON symbol is installed at major number maj,\n\ ! 76: call unload routine for the driver and remove the\n\ ! 77: driver from the driver table.\n\ ! 78: 'Value' is a numeric constant (decimal by default, hexadecimal if preceded\n\ ! 79: by '0x', octal if preceded by '0' or '0o'.\n\ ! 80: 'Value' may also be makedev(major-number, minor-number).\n\ ! 81: "; ! 82: ! 83: /* ! 84: * ---------------------------------------------------------------------- ! 85: * Code. ! 86: */ ! 87: ! 88: /************************************************************************* ! 89: * main ! 90: ************************************************************************/ ! 91: void ! 92: main(argc, argv) ! 93: int argc; ! 94: char *argv[]; ! 95: { ! 96: int c; /* For reading options from getopt(). */ ! 97: int i; ! 98: int patch_err; ! 99: char errmsg[80]; ! 100: ! 101: extern int optind; ! 102: extern char *optarg; ! 103: ! 104: if ((kfd = open(PATCH_DEVICE_NAME, 0)) == -1) { ! 105: sprintf(errmsg, "%s: device %s", argv[0], PATCH_DEVICE_NAME); ! 106: perror(errmsg); ! 107: exit(1); ! 108: } ! 109: ! 110: while ((c = getopt(argc, argv, "v?")) != EOF) { ! 111: switch (c) { ! 112: case 'v': ! 113: verbose++; ! 114: break; ! 115: case '?': ! 116: fprintf(stderr, "%s\n", version); ! 117: usage(1); /* Does not return. */ ! 118: default: ! 119: usage(0); /* Does not return. */ ! 120: } ! 121: } ! 122: ! 123: /* ! 124: * There must be at least 2 arguments left. ! 125: */ ! 126: if (argc - optind < 1) { ! 127: fprintf(stderr, "Missing arguments.\n"); ! 128: usage(0); /* Does not return */ ! 129: } ! 130: ! 131: /* ! 132: * Handle patch symbols one at a time. ! 133: * If an error occurs, display failure and save error status ! 134: * for exit value. ! 135: */ ! 136: patch_err = 0; ! 137: for (i = optind; i < argc; i++) { ! 138: if (kpatch(argv[i])) { ! 139: sprintf(errmsg, "%s: %s", argv[0], argv[i]); ! 140: if (errno) ! 141: perror(errmsg); ! 142: patch_err = 1; ! 143: } ! 144: } ! 145: close(kfd); ! 146: exit(patch_err); ! 147: } ! 148: ! 149: /************************************************************************* ! 150: * kpatch ! 151: * ! 152: * Given a patch argument, attempt to do the patch. ! 153: * Return 0 if successful, -1 if failure. ! 154: ************************************************************************/ ! 155: static int ! 156: kpatch(patch_arg) ! 157: char * patch_arg; ! 158: { ! 159: int result; ! 160: ! 161: /* ! 162: * Parse patch argument. ! 163: * If its type can be identified, pass the parsed info to ! 164: * the required action routine. ! 165: */ ! 166: lex_input = patch_arg; ! 167: lex_index = 0; ! 168: argInfo.piType = bad_arg; ! 169: if(yyparse()) ! 170: result = -1; ! 171: else { /* parse succeeded */ ! 172: pDump(); ! 173: switch(argInfo.piType) { ! 174: case peek_arg: ! 175: result = peek_patch(&argInfo); ! 176: break; ! 177: case assign_arg: ! 178: result = assign_patch(&argInfo); ! 179: break; ! 180: case con_in_arg: ! 181: result = con_in_patch(&argInfo); ! 182: break; ! 183: case con_out_arg: ! 184: result = con_out_patch(&argInfo); ! 185: break; ! 186: default: ! 187: result = -1; ! 188: } ! 189: } ! 190: ! 191: return result; ! 192: } ! 193: ! 194: /************************************************************************* ! 195: * usage ! 196: * ! 197: * Display usage message and terminate abnormally. ! 198: ************************************************************************/ ! 199: /* ! 200: */ ! 201: void ! 202: usage(verbose) ! 203: int verbose; ! 204: { ! 205: fprintf(stderr, short_helpmessage); ! 206: if (verbose) { ! 207: fprintf(stderr, helpmessage); ! 208: } ! 209: exit(1); ! 210: } ! 211: ! 212: /************************************************************************* ! 213: * arg_getc ! 214: * ! 215: * This replaces the default lex input function, taking input from global ! 216: * character pointer lex_input at position lex_index. ! 217: ************************************************************************/ ! 218: int ! 219: arg_getc() ! 220: { ! 221: int result; ! 222: ! 223: /* ! 224: * Fetch the next available character. ! 225: * If at end of string ! 226: * Return EOF. ! 227: * Else ! 228: * Advance character pointer. ! 229: */ ! 230: result = lex_input[lex_index]; ! 231: if (result == 0) ! 232: result = -1; ! 233: else ! 234: lex_index++; ! 235: return result; ! 236: } ! 237: ! 238: /************************************************************************* ! 239: * assign_patch ! 240: * ! 241: * Try to modify a kernel variable. ! 242: * Return 0 if success, -1 if failure. ! 243: ************************************************************************/ ! 244: static int ! 245: assign_patch(pip) ! 246: struct PatchInfo * pip; ! 247: { ! 248: struct patchVar pvar; ! 249: int result; ! 250: ! 251: strncpy(pvar.patch_vname, pip->piData.assignData.vname, ! 252: PATCH_VAR_NAME_LENGTH); ! 253: pvar.patch_data = & pip->piData.assignData.newValue; ! 254: result = ioctl(kfd, PATCH_WR, &pvar); ! 255: ! 256: if (result >= 0 && verbose) ! 257: printf("Value assigned: %s=0x%08x\n", ! 258: pvar.patch_vname, pip->piData.assignData.newValue); ! 259: ! 260: return result; ! 261: } ! 262: ! 263: /************************************************************************* ! 264: * con_in_patch ! 265: * ! 266: * Try to install a device driver. ! 267: * Return 0 if success, -1 if failure. ! 268: ************************************************************************/ ! 269: static int ! 270: con_in_patch(pip) ! 271: struct PatchInfo * pip; ! 272: { ! 273: struct patchCon pcon; ! 274: int result; ! 275: ! 276: strncpy(pcon.patch_vname, pip->piData.conData.vname, ! 277: PATCH_VAR_NAME_LENGTH); ! 278: pcon.patch_maj = pip->piData.conData.maj; ! 279: result = ioctl(kfd, PATCH_CON_IN, &pcon); ! 280: ! 281: if (result >= 0 && verbose) ! 282: printf("Device %s attached at major number %d\n", ! 283: pcon.patch_vname, pcon.patch_maj); ! 284: ! 285: return result; ! 286: } ! 287: ! 288: /************************************************************************* ! 289: * con_out_patch ! 290: * ! 291: * Try to uninstall a device driver. ! 292: * Return 0 if success, -1 if failure. ! 293: ************************************************************************/ ! 294: static int ! 295: con_out_patch(pip) ! 296: struct PatchInfo * pip; ! 297: { ! 298: struct patchCon pcon; ! 299: int result; ! 300: ! 301: strncpy(pcon.patch_vname, pip->piData.conData.vname, ! 302: PATCH_VAR_NAME_LENGTH); ! 303: pcon.patch_maj = pip->piData.conData.maj; ! 304: result = ioctl(kfd, PATCH_CON_OUT, &pcon); ! 305: ! 306: if (result >= 0 && verbose) ! 307: printf("Device %s detached from major number %d\n", ! 308: pcon.patch_vname, pcon.patch_maj); ! 309: ! 310: return result; ! 311: } ! 312: ! 313: /************************************************************************* ! 314: * peek_patch ! 315: * ! 316: * Try to examine a kernel variable. ! 317: * Return 0 if success, -1 if failure. ! 318: ************************************************************************/ ! 319: static int ! 320: peek_patch(pip) ! 321: struct PatchInfo * pip; ! 322: { ! 323: int vdata = 0; ! 324: struct patchVar pvar; ! 325: int result; ! 326: ! 327: strncpy(pvar.patch_vname, pip->piData.peekData.vname, ! 328: PATCH_VAR_NAME_LENGTH); ! 329: pvar.patch_data = &vdata; ! 330: result = ioctl(kfd, PATCH_RD, &pvar); ! 331: ! 332: if (result >= 0) ! 333: printf("Value inspected: %s=0x%08x\n", pvar.patch_vname, vdata); ! 334: ! 335: return result; ! 336: } ! 337: ! 338: pDump() ! 339: { ! 340: #if 0 ! 341: switch(argInfo.piType) { ! 342: case peek_arg: ! 343: printf("What is the value of %s?\n", ! 344: argInfo.piData.peekData.vname); ! 345: break; ! 346: case assign_arg: ! 347: printf("Set %s equal to %d\n", ! 348: argInfo.piData.assignData.vname, ! 349: argInfo.piData.assignData.newValue); ! 350: break; ! 351: case con_in_arg: ! 352: printf("Attach device %s to major number %d\n", ! 353: argInfo.piData.conData.vname, ! 354: argInfo.piData.conData.maj); ! 355: break; ! 356: case con_out_arg: ! 357: printf("Detach device %s from major number %d\n", ! 358: argInfo.piData.conData.vname, ! 359: argInfo.piData.conData.maj); ! 360: break; ! 361: default: ! 362: printf("Bad argument! %s\n", lex_input); ! 363: } ! 364: #endif ! 365: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.