util.c (56384) | util.c (64382) |
---|---|
1/* 2 * Written By Julian ELischer 3 * Copyright julian Elischer 1993. 4 * Permission is granted to use or redistribute this file in any way as long 5 * as this notice remains. Julian Elischer does not guarantee that this file 6 * is totally correct for any given task and users of this file must 7 * accept responsibility for any damage that occurs from the application of this 8 * file. --- 31 unchanged lines hidden (view full) --- 40 * SUCH DAMAGE. 41 */ 42/* 43 * Taken from the original scsi(8) program. 44 * from: scsi.c,v 1.17 1998/01/12 07:57:57 charnier Exp $"; 45 */ 46#ifndef lint 47static const char rcsid[] = | 1/* 2 * Written By Julian ELischer 3 * Copyright julian Elischer 1993. 4 * Permission is granted to use or redistribute this file in any way as long 5 * as this notice remains. Julian Elischer does not guarantee that this file 6 * is totally correct for any given task and users of this file must 7 * accept responsibility for any damage that occurs from the application of this 8 * file. --- 31 unchanged lines hidden (view full) --- 40 * SUCH DAMAGE. 41 */ 42/* 43 * Taken from the original scsi(8) program. 44 * from: scsi.c,v 1.17 1998/01/12 07:57:57 charnier Exp $"; 45 */ 46#ifndef lint 47static const char rcsid[] = |
48 "$FreeBSD: head/sbin/camcontrol/util.c 56384 2000-01-21 23:19:30Z mjacob $"; | 48 "$FreeBSD: head/sbin/camcontrol/util.c 64382 2000-08-08 06:24:17Z kbyanc $"; |
49#endif /* not lint */ 50 | 49#endif /* not lint */ 50 |
51#include <ctype.h> 52#include <err.h> 53#include <errno.h> 54#include <string.h> | |
55#include <stdlib.h> 56#include <stdio.h> | 51#include <stdlib.h> 52#include <stdio.h> |
57#include <sys/file.h> 58#include <signal.h> 59#include <unistd.h> | 53#include <string.h> 54#include <sys/types.h> |
60 | 55 |
61#include <cam/cam.h> 62#include <cam/cam_ccb.h> | |
63#include <camlib.h> 64#include "camcontrol.h" 65 | 56#include <camlib.h> 57#include "camcontrol.h" 58 |
66int verbose = 0; | 59int verbose; |
67 68/* iget: Integer argument callback 69 */ 70int 71iget(void *hook, char *name) 72{ 73 struct get_hook *h = (struct get_hook *)hook; 74 int arg; --- 77 unchanged lines hidden (view full) --- 152 break; 153 154 default: 155 printf("Unknown format letter: '%c'\n", letter); 156 } 157 if (verbose) 158 putchar('\n'); 159} | 60 61/* iget: Integer argument callback 62 */ 63int 64iget(void *hook, char *name) 65{ 66 struct get_hook *h = (struct get_hook *)hook; 67 int arg; --- 77 unchanged lines hidden (view full) --- 145 break; 146 147 default: 148 printf("Unknown format letter: '%c'\n", letter); 149 } 150 if (verbose) 151 putchar('\n'); 152} |
160 161#define START_ENTRY '{' 162#define END_ENTRY '}' 163 164static void 165skipwhite(FILE *f) 166{ 167 int c; 168 169skip_again: 170 171 while (isspace(c = getc(f))) 172 ; 173 174 if (c == '#') { 175 while ((c = getc(f)) != '\n' && c != EOF) 176 ; 177 goto skip_again; 178 } 179 180 ungetc(c, f); 181} 182 183/* mode_lookup: Lookup a format description for a given page. 184 */ 185char *mode_db = "/usr/share/misc/scsi_modes"; 186static char * 187mode_lookup(int page) 188{ 189 char *new_db; 190 FILE *modes; 191 int match, next, found, c; 192 static char fmt[4096]; /* XXX This should be with strealloc */ 193 int page_desc; 194 new_db = getenv("SCSI_MODES"); 195 196 if (new_db) 197 mode_db = new_db; 198 199 modes = fopen(mode_db, "r"); 200 if (modes == 0) 201 return 0; 202 203 next = 0; 204 found = 0; 205 206 while (!found) { 207 208 skipwhite(modes); 209 210 if (fscanf(modes, "%i", &page_desc) != 1) 211 break; 212 213 if (page_desc == page) 214 found = 1; 215 216 skipwhite(modes); 217 if (getc(modes) != START_ENTRY) 218 errx(1, "expected %c", START_ENTRY); 219 220 match = 1; 221 while (match != 0) { 222 c = getc(modes); 223 if (c == EOF) { 224 warnx("expected %c", END_ENTRY); 225 } 226 227 if (c == START_ENTRY) { 228 match++; 229 } 230 if (c == END_ENTRY) { 231 match--; 232 if (match == 0) 233 break; 234 } 235 if (found && c != '\n') { 236 if (next >= sizeof(fmt)) 237 errx(1, "buffer overflow"); 238 239 fmt[next++] = (u_char)c; 240 } 241 } 242 } 243 fmt[next] = 0; 244 245 return (found) ? fmt : 0; 246} 247 248/* -------- edit: Mode Select Editor --------- 249 */ 250struct editinfo 251{ 252 int can_edit; 253 int default_value; 254} editinfo[64]; /* XXX Bogus fixed size */ 255 256static int editind; 257volatile int edit_opened; 258static FILE *edit_file; 259static char edit_name[L_tmpnam]; 260 261static inline void 262edit_rewind(void) 263{ 264 editind = 0; 265} 266 267static void 268edit_done(void) 269{ 270 int opened; 271 272 sigset_t all, prev; 273 sigfillset(&all); 274 275 (void)sigprocmask(SIG_SETMASK, &all, &prev); 276 277 opened = (int)edit_opened; 278 edit_opened = 0; 279 280 (void)sigprocmask(SIG_SETMASK, &prev, 0); 281 282 if (opened) 283 { 284 if (fclose(edit_file)) 285 warn("%s", edit_name); 286 if (unlink(edit_name)) 287 warn("%s", edit_name); 288 } 289} 290 291static void 292edit_init(void) 293{ 294 int fd; 295 296 edit_rewind(); 297 strlcpy(edit_name, "/tmp/camXXXXXX", sizeof(edit_name)); 298 if ((fd = mkstemp(edit_name)) == -1) 299 errx(1, "mkstemp failed"); 300 if ((edit_file = fdopen(fd, "w")) == 0) 301 err(1, "%s", edit_name); 302 edit_opened = 1; 303 304 atexit(edit_done); 305} 306 307static void 308edit_check(void *hook, int letter, void *arg, int count, char *name) 309{ 310 if (letter != 'i' && letter != 'b') 311 errx(1, "can't edit format %c", letter); 312 313 if (editind >= sizeof(editinfo) / sizeof(editinfo[0])) 314 errx(1, "edit table overflow"); 315 316 editinfo[editind].can_edit = (arg != NULL); 317 editind++; 318} 319 320static void 321edit_defaults(void *hook, int letter, void *arg, int count, char *name) 322{ 323 if (letter != 'i' && letter != 'b') 324 errx(1, "can't edit format %c", letter); 325 326 editinfo[editind].default_value = (intptr_t)arg; /* truncated */ 327 editind++; 328} 329 330static void 331edit_report(void *hook, int letter, void *arg, int count, char *name) 332{ 333 if (editinfo[editind].can_edit) { 334 if (letter != 'i' && letter != 'b') 335 errx(1, "can't report format %c", letter); 336 337 fprintf(edit_file, "%s: %d\n", name, (intptr_t)arg); 338 } 339 340 editind++; 341} 342 343static int 344edit_get(void *hook, char *name) 345{ 346 int arg = editinfo[editind].default_value; 347 348 if (editinfo[editind].can_edit) { 349 char line[80]; 350 if (fgets(line, sizeof(line), edit_file) == 0) 351 err(1, "fgets"); 352 353 line[strlen(line) - 1] = 0; 354 355 if (strncmp(name, line, strlen(name)) != 0) 356 errx(1, "expected \"%s\" and read \"%s\"", name, line); 357 358 arg = strtoul(line + strlen(name) + 2, 0, 0); 359 } 360 361 editind++; 362 return arg; 363} 364 365static void 366edit_edit(void) 367{ 368 char *system_line; 369 char *editor = getenv("EDITOR"); 370 if (!editor) 371 editor = "vi"; 372 373 fclose(edit_file); 374 375 system_line = malloc(strlen(editor) + strlen(edit_name) + 6); 376 sprintf(system_line, "%s %s", editor, edit_name); 377 system(system_line); 378 free(system_line); 379 380 if ((edit_file = fopen(edit_name, "r")) == 0) 381 err(1, "%s", edit_name); 382} 383 384void 385mode_edit(struct cam_device *device, int page, int page_control, int dbd, 386 int edit, int retry_count, int timeout) 387{ 388 int i; 389 u_char data[255]; 390 u_char *mode_pars; 391 struct mode_header 392 { 393 u_char mdl; /* Mode data length */ 394 u_char medium_type; 395 u_char dev_spec_par; 396 u_char bdl; /* Block descriptor length */ 397 }; 398 399 struct mode_page_header 400 { 401 u_char page_code; 402 u_char page_length; 403 }; 404 405 struct mode_header *mh; 406 struct mode_page_header *mph; 407 408 char *fmt = mode_lookup(page); 409 if (!fmt && verbose) { 410 fprintf(stderr, 411 "No mode data base entry in \"%s\" for page %d; " 412 " binary %s only.\n", 413 mode_db, page, (edit ? "edit" : "display")); 414 } 415 416 if (edit) { 417 if (!fmt) 418 errx(1, "can't edit without a format"); 419 420 if (page_control != 0 && page_control != 3) 421 errx(1, "it only makes sense to edit page 0 " 422 "(current) or page 3 (saved values)"); 423 424 verbose = 1; 425 426 mode_sense(device, page, 1, dbd, retry_count, timeout, 427 data, sizeof(data)); 428 429 mh = (struct mode_header *)data; 430 mph = (struct mode_page_header *) 431 (((char *)mh) + sizeof(*mh) + mh->bdl); 432 433 mode_pars = (char *)mph + sizeof(*mph); 434 435 edit_init(); 436 buff_decode_visit(mode_pars, mh->mdl, fmt, edit_check, 0); 437 438 mode_sense(device, page, 0, dbd, retry_count, timeout, 439 data, sizeof(data)); 440 441 edit_rewind(); 442 buff_decode_visit(mode_pars, mh->mdl, fmt, edit_defaults, 0); 443 444 edit_rewind(); 445 buff_decode_visit(mode_pars, mh->mdl, fmt, edit_report, 0); 446 447 edit_edit(); 448 449 edit_rewind(); 450 buff_encode_visit(mode_pars, mh->mdl, fmt, edit_get, 0); 451 452 /* Eliminate block descriptors: 453 */ 454 bcopy((char *)mph, ((char *)mh) + sizeof(*mh), 455 sizeof(*mph) + mph->page_length); 456 457 mh->bdl = mh->dev_spec_par = 0; 458 mph = (struct mode_page_header *) (((char *)mh) + sizeof(*mh)); 459 mode_pars = ((char *)mph) + 2; 460 461#if 0 462 /* Turn this on to see what you're sending to the 463 * device: 464 */ 465 edit_rewind(); 466 buff_decode_visit(mode_pars, mh->mdl, fmt, arg_put, 0); 467#endif 468 469 edit_done(); 470 471 /* Make it permanent if pageselect is three. 472 */ 473 474 mph->page_code &= ~0xC0; /* Clear PS and RESERVED */ 475 mh->mdl = 0; /* Reserved for mode select */ 476 477 mode_select(device, (page_control == 3), retry_count, 478 timeout, (u_int8_t *)mh, sizeof(*mh) + mh->bdl + 479 sizeof(*mph) + mph->page_length); 480 481 return; 482 } 483 484 mode_sense(device, page, page_control, dbd, retry_count, timeout, 485 data, sizeof(data)); 486 487 /* Skip over the block descriptors. 488 */ 489 mh = (struct mode_header *)data; 490 mph = (struct mode_page_header *)(((char *)mh) + sizeof(*mh) + mh->bdl); 491 mode_pars = (char *)mph + sizeof(*mph); 492 493 if (!fmt) { 494 for (i = 0; i < mh->mdl; i++) { 495 printf("%02x%c",mode_pars[i], 496 (((i + 1) % 8) == 0) ? '\n' : ' '); 497 } 498 putc('\n', stdout); 499 } else { 500 verbose = 1; 501 buff_decode_visit(mode_pars, mh->mdl, fmt, arg_put, NULL); 502 } 503} | |