PageRenderTime 59ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 1ms

/usr/src/cmd/allocate/mkdevalloc.c

https://bitbucket.org/a3217055/illumos-gate
C | 1314 lines | 999 code | 147 blank | 168 comment | 294 complexity | 6c176c2251f21ea45fe32011dfe19378 MD5 | raw file
Possible License(s): BSD-2-Clause, BSD-3-Clause, LGPL-2.0, 0BSD, AGPL-3.0, GPL-2.0, GPL-3.0, LGPL-2.1, LGPL-3.0, BSD-3-Clause-No-Nuclear-License-2014, MPL-2.0-no-copyleft-exception, AGPL-1.0
  1. /*
  2. * CDDL HEADER START
  3. *
  4. * The contents of this file are subject to the terms of the
  5. * Common Development and Distribution License (the "License").
  6. * You may not use this file except in compliance with the License.
  7. *
  8. * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  9. * or http://www.opensolaris.org/os/licensing.
  10. * See the License for the specific language governing permissions
  11. * and limitations under the License.
  12. *
  13. * When distributing Covered Code, include this CDDL HEADER in each
  14. * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15. * If applicable, add the following below this CDDL HEADER, with the
  16. * fields enclosed by brackets "[]" replaced with your own identifying
  17. * information: Portions Copyright [yyyy] [name of copyright owner]
  18. *
  19. * CDDL HEADER END
  20. */
  21. /*
  22. * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
  23. * Use is subject to license terms.
  24. */
  25. /*
  26. * scan /dev directory for mountable objects and construct device_allocate
  27. * file for allocate....
  28. *
  29. * devices are:
  30. * tape (cartridge)
  31. * /dev/rst*
  32. * /dev/nrst*
  33. * /dev/rmt/...
  34. * audio
  35. * /dev/audio
  36. * /dev/audioctl
  37. * /dev/sound/...
  38. * floppy
  39. * /dev/diskette
  40. * /dev/fd*
  41. * /dev/rdiskette
  42. * /dev/rfd*
  43. * CD
  44. * /dev/sr*
  45. * /dev/nsr*
  46. * /dev/dsk/c?t?d0s?
  47. * /dev/rdsk/c?t?d0s?
  48. *
  49. */
  50. #include <errno.h>
  51. #include <fcntl.h>
  52. #include <sys/types.h> /* for stat(2), etc. */
  53. #include <sys/stat.h>
  54. #include <dirent.h> /* for readdir(3), etc. */
  55. #include <unistd.h> /* for readlink(2) */
  56. #include <stropts.h>
  57. #include <string.h> /* for strcpy(3), etc. */
  58. #include <strings.h> /* for bcopy(3C), etc. */
  59. #include <stdio.h> /* for perror(3) */
  60. #include <stdlib.h> /* for atoi(3) */
  61. #include <sys/dkio.h>
  62. #include <locale.h>
  63. #include <libintl.h>
  64. #include <libdevinfo.h>
  65. #include <secdb.h>
  66. #include <deflt.h>
  67. #include <auth_attr.h>
  68. #include <auth_list.h>
  69. #include <bsm/devices.h>
  70. #include <bsm/devalloc.h>
  71. #include <tsol/label.h>
  72. #ifndef TEXT_DOMAIN
  73. #define TEXT_DOMAIN "SUNW_OST_OSCMD"
  74. #endif
  75. #define MKDEVALLOC "mkdevalloc"
  76. #define MKDEVMAPS "mkdevmaps"
  77. #define DELTA 5 /* array size delta when full */
  78. #define SECLIB "/etc/security/lib"
  79. /* "/dev/rst...", "/dev/nrst...", "/dev/rmt/..." */
  80. struct tape {
  81. char *name;
  82. char *device;
  83. int number;
  84. } *tape;
  85. #define DFLT_NTAPE 10 /* size of initial array */
  86. #define SIZE_OF_RST 3 /* |rmt| */
  87. #define SIZE_OF_NRST 4 /* |nrmt| */
  88. #define SIZE_OF_TMP 4 /* |/tmp| */
  89. #define SIZE_OF_RMT 8 /* |/dev/rmt| */
  90. #define TAPE_CLEAN SECLIB"/st_clean"
  91. /* "/dev/audio", "/dev/audioctl", "/dev/sound/..." */
  92. struct audio {
  93. char *name;
  94. char *device;
  95. int number;
  96. } *audio;
  97. #define DFLT_NAUDIO 10 /* size of initial array */
  98. #define SIZE_OF_SOUND 10 /* |/dev/sound| */
  99. #define AUDIO_CLEAN SECLIB"/audio_clean"
  100. /* "/dev/sr", "/dev/nsr", "/dev/dsk/c?t?d0s?", "/dev/rdsk/c?t?d0s?" */
  101. struct cd {
  102. char *name;
  103. char *device;
  104. int id;
  105. int controller;
  106. int number;
  107. } *cd;
  108. #define DFLT_NCD 10 /* size of initial array */
  109. #define SIZE_OF_SR 2 /* |sr| */
  110. #define SIZE_OF_RSR 3 /* |rsr| */
  111. #define SIZE_OF_DSK 8 /* |/dev/dsk| */
  112. #define SIZE_OF_RDSK 9 /* |/dev/rdsk| */
  113. #define CD_CLEAN SECLIB"/sr_clean"
  114. /* "/dev/sr", "/dev/nsr", "/dev/dsk/c?t?d0s?", "/dev/rdsk/c?t?d0s?" */
  115. struct rmdisk {
  116. char *name;
  117. char *device;
  118. int id;
  119. int controller;
  120. int number;
  121. } *rmdisk, *rmdisk_r;
  122. #define DFLT_RMDISK 10 /* size of initial array */
  123. /* "/dev/fd0*", "/dev/rfd0*", "/dev/fd1*", "/dev/rfd1*" */
  124. struct fp {
  125. char *name;
  126. char *device;
  127. int number;
  128. } *fp;
  129. #define DFLT_NFP 10 /* size of initial array */
  130. #define SIZE_OF_FD0 3 /* |fd0| */
  131. #define SIZE_OF_RFD0 4 /* |rfd0| */
  132. #define FLOPPY_CLEAN SECLIB"/fd_clean"
  133. static void dotape();
  134. static void doaudio();
  135. static void dofloppy();
  136. static int docd();
  137. static void dormdisk(int);
  138. static void initmem();
  139. static int expandmem(int, void **, int);
  140. static void no_memory(void);
  141. int system_labeled = 0;
  142. int do_devalloc = 0;
  143. int do_devmaps = 0;
  144. int do_files = 0;
  145. devlist_t devlist;
  146. int
  147. main(int argc, char **argv)
  148. {
  149. int cd_count = 0;
  150. char *progname;
  151. (void) setlocale(LC_ALL, "");
  152. (void) textdomain(TEXT_DOMAIN);
  153. if ((progname = strrchr(argv[0], '/')) == NULL)
  154. progname = argv[0];
  155. else
  156. progname++;
  157. if (strcmp(progname, MKDEVALLOC) == 0)
  158. do_devalloc = 1;
  159. else if (strcmp(progname, MKDEVMAPS) == 0)
  160. do_devmaps = 1;
  161. else
  162. exit(1);
  163. system_labeled = is_system_labeled();
  164. if (!system_labeled) {
  165. /*
  166. * is_system_labeled() will return false in case we are
  167. * starting before the first reboot after Trusted Extensions
  168. * is enabled. Check the setting in /etc/system to see if
  169. * TX is enabled (even if not yet booted).
  170. */
  171. if (defopen("/etc/system") == 0) {
  172. if (defread("set sys_labeling=1") != NULL)
  173. system_labeled = 1;
  174. /* close defaults file */
  175. (void) defopen(NULL);
  176. }
  177. }
  178. #ifdef DEBUG
  179. /* test hook: see also devfsadm.c and allocate.c */
  180. if (!system_labeled) {
  181. struct stat tx_stat;
  182. system_labeled = is_system_labeled_debug(&tx_stat);
  183. if (system_labeled) {
  184. fprintf(stderr, "/ALLOCATE_FORCE_LABEL is set,\n"
  185. "forcing system label on for testing...\n");
  186. }
  187. }
  188. #endif
  189. if (system_labeled && do_devalloc && (argc == 2) &&
  190. (strcmp(argv[1], DA_IS_LABELED) == 0)) {
  191. /*
  192. * write device entries to device_allocate and device_maps.
  193. * default is to print them on stdout.
  194. */
  195. do_files = 1;
  196. }
  197. initmem(); /* initialize memory */
  198. dotape();
  199. doaudio();
  200. dofloppy();
  201. cd_count = docd();
  202. if (system_labeled)
  203. dormdisk(cd_count);
  204. return (0);
  205. }
  206. static void
  207. dotape()
  208. {
  209. DIR *dirp;
  210. struct dirent *dep; /* directory entry pointer */
  211. int i, j;
  212. char *nm; /* name/device of special device */
  213. char linkvalue[2048]; /* symlink value */
  214. struct stat stat; /* determine if it's a symlink */
  215. int sz; /* size of symlink value */
  216. char *cp; /* pointer into string */
  217. int ntape; /* max array size */
  218. int tape_count;
  219. int first = 0;
  220. char *dname, *dtype, *dclean;
  221. da_args dargs;
  222. deventry_t *entry;
  223. ntape = DFLT_NTAPE;
  224. /*
  225. * look for rst* and nrst*
  226. */
  227. if ((dirp = opendir("/dev")) == NULL) {
  228. perror(gettext("open /dev failure"));
  229. exit(1);
  230. }
  231. i = 0;
  232. while (dep = readdir(dirp)) {
  233. /* ignore if neither rst* nor nrst* */
  234. if (strncmp(dep->d_name, "rst", SIZE_OF_RST) &&
  235. strncmp(dep->d_name, "nrst", SIZE_OF_NRST))
  236. continue;
  237. /* if array full, then expand it */
  238. if (i == ntape) {
  239. /* will exit(1) if insufficient memory */
  240. ntape = expandmem(i, (void **)&tape,
  241. sizeof (struct tape));
  242. }
  243. /* save name (/dev + / + d_name + \0) */
  244. nm = (char *)malloc(SIZE_OF_TMP + 1 + strlen(dep->d_name) + 1);
  245. if (nm == NULL)
  246. no_memory();
  247. (void) strcpy(nm, "/dev/");
  248. (void) strcat(nm, dep->d_name);
  249. tape[i].name = nm;
  250. /* ignore if not symbolic link (note i not incremented) */
  251. if (lstat(tape[i].name, &stat) < 0) {
  252. perror("stat(2) failed ");
  253. exit(1);
  254. }
  255. if ((stat.st_mode & S_IFMT) != S_IFLNK)
  256. continue;
  257. /* get name from symbolic link */
  258. if ((sz = readlink(tape[i].name, linkvalue,
  259. sizeof (linkvalue))) < 0)
  260. continue;
  261. nm = (char *)malloc(sz + 1);
  262. if (nm == NULL)
  263. no_memory();
  264. (void) strncpy(nm, linkvalue, sz);
  265. nm[sz] = '\0';
  266. tape[i].device = nm;
  267. /* get device number */
  268. cp = strrchr(tape[i].device, '/');
  269. cp++; /* advance to device # */
  270. (void) sscanf(cp, "%d", &tape[i].number);
  271. i++;
  272. }
  273. (void) closedir(dirp);
  274. /*
  275. * scan /dev/rmt and add entry to table
  276. */
  277. if ((dirp = opendir("/dev/rmt")) == NULL) {
  278. perror(gettext("open /dev failure"));
  279. exit(1);
  280. }
  281. while (dep = readdir(dirp)) {
  282. /* skip . .. etc... */
  283. if (strncmp(dep->d_name, ".", 1) == NULL)
  284. continue;
  285. /* if array full, then expand it */
  286. if (i == ntape) {
  287. /* will exit(1) if insufficient memory */
  288. ntape = expandmem(i, (void **)&tape,
  289. sizeof (struct tape));
  290. }
  291. /* save name (/dev/rmt + / + d_name + \0) */
  292. nm = (char *)malloc(SIZE_OF_RMT + 1 + strlen(dep->d_name) + 1);
  293. if (nm == NULL)
  294. no_memory();
  295. (void) strcpy(nm, "/dev/rmt/");
  296. (void) strcat(nm, dep->d_name);
  297. tape[i].name = nm;
  298. /* save device name (rmt/ + d_name + \0) */
  299. nm = (char *)malloc(SIZE_OF_TMP + strlen(dep->d_name) + 1);
  300. if (nm == NULL)
  301. no_memory();
  302. (void) strcpy(nm, "rmt/");
  303. (void) strcat(nm, dep->d_name);
  304. tape[i].device = nm;
  305. (void) sscanf(dep->d_name, "%d", &tape[i].number);
  306. i++;
  307. }
  308. tape_count = i;
  309. (void) closedir(dirp);
  310. /* remove duplicate entries */
  311. for (i = 0; i < tape_count - 1; i++) {
  312. for (j = i + 1; j < tape_count; j++) {
  313. if (strcmp(tape[i].device, tape[j].device))
  314. continue;
  315. tape[j].number = -1;
  316. }
  317. }
  318. if (system_labeled) {
  319. dname = DA_TAPE_NAME;
  320. dtype = DA_TAPE_TYPE;
  321. dclean = DA_DEFAULT_TAPE_CLEAN;
  322. } else {
  323. dname = "st";
  324. dtype = "st";
  325. dclean = TAPE_CLEAN;
  326. }
  327. for (i = 0; i < 8; i++) {
  328. for (j = 0; j < tape_count; j++) {
  329. if (tape[j].number != i)
  330. continue;
  331. if (do_files) {
  332. (void) da_add_list(&devlist, tape[j].name, i,
  333. DA_TAPE);
  334. } else if (do_devalloc) {
  335. /* print device_allocate for tape devices */
  336. if (system_labeled) {
  337. (void) printf("%s%d%s\\\n",
  338. dname, i, KV_DELIMITER);
  339. (void) printf("\t%s%s\\\n",
  340. DA_TAPE_TYPE, KV_DELIMITER);
  341. (void) printf("\t%s%s\\\n",
  342. DA_RESERVED, KV_DELIMITER);
  343. (void) printf("\t%s%s\\\n",
  344. DA_RESERVED, KV_DELIMITER);
  345. (void) printf("\t%s%s\\\n",
  346. DEFAULT_DEV_ALLOC_AUTH,
  347. KV_DELIMITER);
  348. (void) printf("\t%s\n\n", dclean);
  349. } else {
  350. (void) printf(
  351. "st%d;st;reserved;reserved;%s;",
  352. i, DEFAULT_DEV_ALLOC_AUTH);
  353. (void) printf("%s%s\n", SECLIB,
  354. "/st_clean");
  355. }
  356. break;
  357. } else if (do_devmaps) {
  358. /* print device_maps for tape devices */
  359. if (first) {
  360. (void) printf(" ");
  361. } else {
  362. if (system_labeled) {
  363. (void) printf("%s%d%s\\\n",
  364. dname, i, KV_TOKEN_DELIMIT);
  365. (void) printf("\t%s%s\\\n",
  366. dtype, KV_TOKEN_DELIMIT);
  367. (void) printf("\t");
  368. } else {
  369. (void) printf("st%d:\\\n", i);
  370. (void) printf("\trmt:\\\n");
  371. (void) printf("\t");
  372. }
  373. first++;
  374. }
  375. (void) printf("%s", tape[j].name);
  376. }
  377. }
  378. if (do_devmaps && first) {
  379. (void) printf("\n\n");
  380. first = 0;
  381. }
  382. }
  383. if (do_files && tape_count) {
  384. dargs.rootdir = NULL;
  385. dargs.devnames = NULL;
  386. dargs.optflag = DA_ADD;
  387. for (entry = devlist.tape; entry != NULL; entry = entry->next) {
  388. dargs.devinfo = &(entry->devinfo);
  389. (void) da_update_device(&dargs);
  390. }
  391. }
  392. }
  393. static void
  394. doaudio()
  395. {
  396. DIR *dirp;
  397. struct dirent *dep; /* directory entry pointer */
  398. int i, j;
  399. char *nm; /* name/device of special device */
  400. char linkvalue[2048]; /* symlink value */
  401. struct stat stat; /* determine if it's a symlink */
  402. int sz; /* size of symlink value */
  403. char *cp; /* pointer into string */
  404. int naudio; /* max array size */
  405. int audio_count = 0;
  406. int len, slen;
  407. int first = 0;
  408. char dname[128];
  409. char *dclean;
  410. da_args dargs;
  411. deventry_t *entry;
  412. naudio = DFLT_NAUDIO;
  413. if ((dirp = opendir("/dev")) == NULL) {
  414. perror(gettext("open /dev failure"));
  415. exit(1);
  416. }
  417. i = 0;
  418. while (dep = readdir(dirp)) {
  419. if (strcmp(dep->d_name, "audio") &&
  420. strcmp(dep->d_name, "audioctl"))
  421. continue;
  422. /* if array full, then expand it */
  423. if (i == naudio) {
  424. /* will exit(1) if insufficient memory */
  425. naudio = expandmem(i, (void **)&audio,
  426. sizeof (struct audio));
  427. }
  428. /* save name (/dev + 1 + d_name + \0) */
  429. nm = (char *)malloc(SIZE_OF_TMP + 1 + strlen(dep->d_name) + 1);
  430. if (nm == NULL)
  431. no_memory();
  432. (void) strcpy(nm, "/dev/");
  433. (void) strcat(nm, dep->d_name);
  434. audio[i].name = nm;
  435. /* ignore if not symbolic link (note i not incremented) */
  436. if (lstat(audio[i].name, &stat) < 0) {
  437. perror(gettext("stat(2) failed "));
  438. exit(1);
  439. }
  440. if ((stat.st_mode & S_IFMT) != S_IFLNK)
  441. continue;
  442. /* get name from symbolic link */
  443. if ((sz = readlink(audio[i].name, linkvalue,
  444. sizeof (linkvalue))) < 0)
  445. continue;
  446. nm = (char *)malloc(sz + 1);
  447. if (nm == NULL)
  448. no_memory();
  449. (void) strncpy(nm, linkvalue, sz);
  450. nm[sz] = '\0';
  451. audio[i].device = nm;
  452. cp = strrchr(audio[i].device, '/');
  453. cp++; /* advance to device # */
  454. (void) sscanf(cp, "%d", &audio[i].number);
  455. i++;
  456. }
  457. (void) closedir(dirp);
  458. if ((dirp = opendir("/dev/sound")) == NULL) {
  459. goto skip;
  460. }
  461. while (dep = readdir(dirp)) {
  462. /* skip . .. etc... */
  463. if (strncmp(dep->d_name, ".", 1) == NULL)
  464. continue;
  465. /* if array full, then expand it */
  466. if (i == naudio) {
  467. /* will exit(1) if insufficient memory */
  468. naudio = expandmem(i, (void **)&audio,
  469. sizeof (struct audio));
  470. }
  471. /* save name (/dev/sound + / + d_name + \0) */
  472. nm = (char *)malloc(SIZE_OF_SOUND + 1 +
  473. strlen(dep->d_name) + 1);
  474. if (nm == NULL)
  475. no_memory();
  476. (void) strcpy(nm, "/dev/sound/");
  477. (void) strcat(nm, dep->d_name);
  478. audio[i].name = nm;
  479. nm = (char *)malloc(SIZE_OF_SOUND + 1 +
  480. strlen(dep->d_name) + 1);
  481. if (nm == NULL)
  482. no_memory();
  483. (void) strcpy(nm, "/dev/sound/");
  484. (void) strcat(nm, dep->d_name);
  485. audio[i].device = nm;
  486. (void) sscanf(dep->d_name, "%d", &audio[i].number);
  487. i++;
  488. }
  489. (void) closedir(dirp);
  490. skip:
  491. audio_count = i;
  492. /* remove duplicate entries */
  493. for (i = 0; i < audio_count - 1; i++) {
  494. for (j = i + 1; j < audio_count; j++) {
  495. if (strcmp(audio[i].device, audio[j].device))
  496. continue;
  497. audio[j].number = -1;
  498. }
  499. }
  500. /* print out device_allocate entries for audio devices */
  501. (void) strcpy(dname, DA_AUDIO_NAME);
  502. slen = strlen(DA_AUDIO_NAME);
  503. len = sizeof (dname) - slen;
  504. dclean = system_labeled ? DA_DEFAULT_AUDIO_CLEAN : AUDIO_CLEAN;
  505. for (i = 0; i < 8; i++) {
  506. for (j = 0; j < audio_count; j++) {
  507. if (audio[j].number != i)
  508. continue;
  509. if (system_labeled)
  510. (void) snprintf(dname+slen, len, "%d", i);
  511. if (do_files) {
  512. (void) da_add_list(&devlist, audio[j].name,
  513. i, DA_AUDIO);
  514. } else if (do_devalloc) {
  515. /* print device_allocate for audio devices */
  516. if (system_labeled) {
  517. (void) printf("%s%s\\\n",
  518. dname, KV_DELIMITER);
  519. (void) printf("\t%s%s\\\n",
  520. DA_AUDIO_TYPE, KV_DELIMITER);
  521. (void) printf("\t%s%s\\\n",
  522. DA_RESERVED, KV_DELIMITER);
  523. (void) printf("\t%s%s\\\n",
  524. DA_RESERVED, KV_DELIMITER);
  525. (void) printf("\t%s%s\\\n",
  526. DEFAULT_DEV_ALLOC_AUTH,
  527. KV_DELIMITER);
  528. (void) printf("\t%s\n\n", dclean);
  529. } else {
  530. (void) printf("audio;audio;");
  531. (void) printf("reserved;reserved;%s;",
  532. DEFAULT_DEV_ALLOC_AUTH);
  533. (void) printf("%s%s\n", SECLIB,
  534. "/audio_clean");
  535. }
  536. break;
  537. } else if (do_devmaps) {
  538. /* print device_maps for audio devices */
  539. if (first) {
  540. (void) printf(" ");
  541. } else {
  542. if (system_labeled) {
  543. (void) printf("%s%s\\\n",
  544. dname, KV_TOKEN_DELIMIT);
  545. (void) printf("\t%s%s\\\n",
  546. DA_AUDIO_TYPE,
  547. KV_TOKEN_DELIMIT);
  548. (void) printf("\t");
  549. } else {
  550. (void) printf("audio:\\\n");
  551. (void) printf("\taudio:\\\n");
  552. (void) printf("\t");
  553. }
  554. first++;
  555. }
  556. (void) printf("%s", audio[j].name);
  557. }
  558. }
  559. if (do_devmaps && first) {
  560. (void) printf("\n\n");
  561. first = 0;
  562. }
  563. }
  564. if (do_files && audio_count) {
  565. dargs.rootdir = NULL;
  566. dargs.devnames = NULL;
  567. dargs.optflag = DA_ADD;
  568. for (entry = devlist.audio; entry != NULL;
  569. entry = entry->next) {
  570. dargs.devinfo = &(entry->devinfo);
  571. (void) da_update_device(&dargs);
  572. }
  573. }
  574. }
  575. static void
  576. dofloppy()
  577. {
  578. DIR *dirp;
  579. struct dirent *dep; /* directory entry pointer */
  580. int i, j;
  581. char *nm; /* name/device of special device */
  582. char linkvalue[2048]; /* symlink value */
  583. struct stat stat; /* determine if it's a symlink */
  584. int sz; /* size of symlink value */
  585. char *cp; /* pointer into string */
  586. int nfp; /* max array size */
  587. int floppy_count = 0;
  588. int first = 0;
  589. char *dname, *dclean;
  590. da_args dargs;
  591. deventry_t *entry;
  592. nfp = DFLT_NFP;
  593. /*
  594. * look for fd* and rfd*
  595. */
  596. if ((dirp = opendir("/dev")) == NULL) {
  597. perror(gettext("open /dev failure"));
  598. exit(1);
  599. }
  600. i = 0;
  601. while (dep = readdir(dirp)) {
  602. /* ignore if neither rst* nor nrst* */
  603. if (strncmp(dep->d_name, "fd0", SIZE_OF_FD0) &&
  604. strncmp(dep->d_name, "rfd0", SIZE_OF_RFD0) &&
  605. strncmp(dep->d_name, "fd1", SIZE_OF_FD0) &&
  606. strncmp(dep->d_name, "rfd0", SIZE_OF_RFD0))
  607. continue;
  608. /* if array full, then expand it */
  609. if (i == nfp) {
  610. /* will exit(1) if insufficient memory */
  611. nfp = expandmem(i, (void **)&fp, sizeof (struct fp));
  612. }
  613. /* save name (/dev + 1 + d_name + \0) */
  614. nm = (char *)malloc(SIZE_OF_TMP + 1 + strlen(dep->d_name) + 1);
  615. if (nm == NULL)
  616. no_memory();
  617. (void) strcpy(nm, "/dev/");
  618. (void) strcat(nm, dep->d_name);
  619. fp[i].name = nm;
  620. /* ignore if not symbolic link (note i not incremented) */
  621. if (lstat(fp[i].name, &stat) < 0) {
  622. perror(gettext("stat(2) failed "));
  623. exit(1);
  624. }
  625. if ((stat.st_mode&S_IFMT) != S_IFLNK)
  626. continue;
  627. /* get name from symbolic link */
  628. if ((sz = readlink(fp[i].name, linkvalue,
  629. sizeof (linkvalue))) < 0)
  630. continue;
  631. nm = (char *)malloc(sz+1);
  632. if (nm == NULL)
  633. no_memory();
  634. (void) strncpy(nm, linkvalue, sz);
  635. nm[sz] = '\0';
  636. fp[i].device = nm;
  637. /* get device number */
  638. cp = strchr(fp[i].name, 'd');
  639. cp++; /* advance to device # */
  640. cp = strchr(cp, 'd');
  641. cp++; /* advance to device # */
  642. (void) sscanf(cp, "%d", &fp[i].number);
  643. i++;
  644. }
  645. (void) closedir(dirp);
  646. floppy_count = i;
  647. /* print out device_allocate entries for floppy devices */
  648. if (system_labeled) {
  649. dname = DA_FLOPPY_NAME;
  650. dclean = DA_DEFAULT_DISK_CLEAN;
  651. } else {
  652. dname = "fd";
  653. dclean = FLOPPY_CLEAN;
  654. }
  655. for (i = 0; i < 8; i++) {
  656. for (j = 0; j < floppy_count; j++) {
  657. if (fp[j].number != i)
  658. continue;
  659. if (do_files) {
  660. (void) da_add_list(&devlist, fp[j].name, i,
  661. DA_FLOPPY);
  662. } else if (do_devalloc) {
  663. /* print device_allocate for floppy devices */
  664. if (system_labeled) {
  665. (void) printf("%s%d%s\\\n",
  666. dname, i, KV_DELIMITER);
  667. (void) printf("\t%s%s\\\n",
  668. DA_FLOPPY_TYPE, KV_DELIMITER);
  669. (void) printf("\t%s%s\\\n",
  670. DA_RESERVED, KV_DELIMITER);
  671. (void) printf("\t%s%s\\\n",
  672. DA_RESERVED, KV_DELIMITER);
  673. (void) printf("\t%s%s\\\n",
  674. DEFAULT_DEV_ALLOC_AUTH,
  675. KV_DELIMITER);
  676. (void) printf("\t%s\n\n", dclean);
  677. } else {
  678. (void) printf(
  679. "fd%d;fd;reserved;reserved;%s;",
  680. i, DEFAULT_DEV_ALLOC_AUTH);
  681. (void) printf("%s%s\n", SECLIB,
  682. "/fd_clean");
  683. }
  684. break;
  685. } else if (do_devmaps) {
  686. /* print device_maps for floppy devices */
  687. if (first) {
  688. (void) printf(" ");
  689. } else {
  690. if (system_labeled) {
  691. (void) printf("%s%d%s\\\n",
  692. dname, i, KV_TOKEN_DELIMIT);
  693. (void) printf("\t%s%s\\\n",
  694. DA_FLOPPY_TYPE,
  695. KV_TOKEN_DELIMIT);
  696. (void) printf("\t");
  697. } else {
  698. (void) printf("fd%d:\\\n", i);
  699. (void) printf("\tfd:\\\n");
  700. (void) printf("\t");
  701. }
  702. if (i == 0) {
  703. (void) printf("/dev/diskette ");
  704. (void) printf(
  705. "/dev/rdiskette ");
  706. }
  707. first++;
  708. }
  709. (void) printf("%s", fp[j].name);
  710. }
  711. }
  712. if (do_devmaps && first) {
  713. (void) printf("\n\n");
  714. first = 0;
  715. }
  716. }
  717. if (do_files && floppy_count) {
  718. dargs.rootdir = NULL;
  719. dargs.devnames = NULL;
  720. dargs.optflag = DA_ADD;
  721. for (entry = devlist.floppy; entry != NULL;
  722. entry = entry->next) {
  723. dargs.devinfo = &(entry->devinfo);
  724. (void) da_update_device(&dargs);
  725. }
  726. }
  727. }
  728. static int
  729. docd()
  730. {
  731. DIR *dirp;
  732. struct dirent *dep; /* directory entry pointer */
  733. int i, j;
  734. char *nm; /* name/device of special device */
  735. char linkvalue[2048]; /* symlink value */
  736. struct stat stat; /* determine if it's a symlink */
  737. int sz; /* size of symlink value */
  738. char *cp; /* pointer into string */
  739. int id; /* disk id */
  740. int ctrl; /* disk controller */
  741. int ncd; /* max array size */
  742. int cd_count = 0;
  743. int first = 0;
  744. char *dname, *dclean;
  745. da_args dargs;
  746. deventry_t *entry;
  747. ncd = DFLT_NCD;
  748. /*
  749. * look for sr* and rsr*
  750. */
  751. if ((dirp = opendir("/dev")) == NULL) {
  752. perror(gettext("open /dev failure"));
  753. exit(1);
  754. }
  755. i = 0;
  756. while (dep = readdir(dirp)) {
  757. /* ignore if neither sr* nor rsr* */
  758. if (strncmp(dep->d_name, "sr", SIZE_OF_SR) &&
  759. strncmp(dep->d_name, "rsr", SIZE_OF_RSR))
  760. continue;
  761. /* if array full, then expand it */
  762. if (i == ncd) {
  763. /* will exit(1) if insufficient memory */
  764. ncd = expandmem(i, (void **)&cd, sizeof (struct cd));
  765. }
  766. /* save name (/dev + / + d_name + \0) */
  767. nm = (char *)malloc(SIZE_OF_TMP + 1 + strlen(dep->d_name) + 1);
  768. if (nm == NULL)
  769. no_memory();
  770. (void) strcpy(nm, "/dev/");
  771. (void) strcat(nm, dep->d_name);
  772. cd[i].name = nm;
  773. /* ignore if not symbolic link (note i not incremented) */
  774. if (lstat(cd[i].name, &stat) < 0) {
  775. perror(gettext("stat(2) failed "));
  776. exit(1);
  777. }
  778. if ((stat.st_mode & S_IFMT) != S_IFLNK)
  779. continue;
  780. /* get name from symbolic link */
  781. if ((sz = readlink(cd[i].name, linkvalue, sizeof (linkvalue))) <
  782. 0)
  783. continue;
  784. nm = (char *)malloc(sz + 1);
  785. if (nm == NULL)
  786. no_memory();
  787. (void) strncpy(nm, linkvalue, sz);
  788. nm[sz] = '\0';
  789. cd[i].device = nm;
  790. cp = strrchr(cd[i].device, '/');
  791. cp++; /* advance to device # */
  792. (void) sscanf(cp, "c%dt%d", &cd[i].controller, &cd[i].number);
  793. cd[i].id = cd[i].number;
  794. i++;
  795. }
  796. cd_count = i;
  797. (void) closedir(dirp);
  798. /*
  799. * scan /dev/dsk for cd devices
  800. */
  801. if ((dirp = opendir("/dev/dsk")) == NULL) {
  802. perror("gettext(open /dev/dsk failure)");
  803. exit(1);
  804. }
  805. while (dep = readdir(dirp)) {
  806. /* skip . .. etc... */
  807. if (strncmp(dep->d_name, ".", 1) == NULL)
  808. continue;
  809. /* get device # (disk #) */
  810. if (sscanf(dep->d_name, "c%dt%d", &ctrl, &id) != 2)
  811. continue;
  812. /* see if this is one of the cd special devices */
  813. for (j = 0; j < cd_count; j++) {
  814. if (cd[j].number == id && cd[j].controller == ctrl)
  815. goto found;
  816. }
  817. continue;
  818. /* add new entry to table (/dev/dsk + / + d_name + \0) */
  819. found:
  820. /* if array full, then expand it */
  821. if (i == ncd) {
  822. /* will exit(1) if insufficient memory */
  823. ncd = expandmem(i, (void **)&cd, sizeof (struct cd));
  824. }
  825. nm = (char *)malloc(SIZE_OF_DSK + 1 + strlen(dep->d_name) + 1);
  826. if (nm == NULL)
  827. no_memory();
  828. (void) strcpy(nm, "/dev/dsk/");
  829. (void) strcat(nm, dep->d_name);
  830. cd[i].name = nm;
  831. cd[i].id = cd[j].id;
  832. cd[i].device = "";
  833. cd[i].number = id;
  834. i++;
  835. }
  836. (void) closedir(dirp);
  837. /*
  838. * scan /dev/rdsk for cd devices
  839. */
  840. if ((dirp = opendir("/dev/rdsk")) == NULL) {
  841. perror(gettext("open /dev/dsk failure"));
  842. exit(1);
  843. }
  844. while (dep = readdir(dirp)) {
  845. /* skip . .. etc... */
  846. if (strncmp(dep->d_name, ".", 1) == NULL)
  847. continue;
  848. /* get device # (disk #) */
  849. if (sscanf(dep->d_name, "c%dt%d", &ctrl, &id) != 2)
  850. continue;
  851. /* see if this is one of the cd special devices */
  852. for (j = 0; j < cd_count; j++) {
  853. if (cd[j].number == id && cd[j].controller == ctrl)
  854. goto found1;
  855. }
  856. continue;
  857. /* add new entry to table (/dev/rdsk + / + d_name + \0) */
  858. found1:
  859. /* if array full, then expand it */
  860. if (i == ncd) {
  861. /* will exit(1) if insufficient memory */
  862. ncd = expandmem(i, (void **)&cd, sizeof (struct cd));
  863. }
  864. nm = (char *)malloc(SIZE_OF_RDSK + 1 + strlen(dep->d_name) + 1);
  865. if (nm == NULL)
  866. no_memory();
  867. (void) strcpy(nm, "/dev/rdsk/");
  868. (void) strcat(nm, dep->d_name);
  869. cd[i].name = nm;
  870. cd[i].id = cd[j].id;
  871. cd[i].device = "";
  872. cd[i].number = id;
  873. cd[i].controller = ctrl;
  874. i++;
  875. }
  876. (void) closedir(dirp);
  877. cd_count = i;
  878. if (system_labeled) {
  879. dname = DA_CD_NAME;
  880. dclean = DA_DEFAULT_DISK_CLEAN;
  881. } else {
  882. dname = "sr";
  883. dclean = CD_CLEAN;
  884. }
  885. for (i = 0; i < 8; i++) {
  886. for (j = 0; j < cd_count; j++) {
  887. if (cd[j].id != i)
  888. continue;
  889. if (do_files) {
  890. (void) da_add_list(&devlist, cd[j].name, i,
  891. DA_CD);
  892. } else if (do_devalloc) {
  893. /* print device_allocate for cd devices */
  894. if (system_labeled) {
  895. (void) printf("%s%d%s\\\n",
  896. dname, i, KV_DELIMITER);
  897. (void) printf("\t%s%s\\\n",
  898. DA_CD_TYPE, KV_DELIMITER);
  899. (void) printf("\t%s%s\\\n",
  900. DA_RESERVED, KV_DELIMITER);
  901. (void) printf("\t%s%s\\\n",
  902. DA_RESERVED, KV_DELIMITER);
  903. (void) printf("\t%s%s\\\n",
  904. DEFAULT_DEV_ALLOC_AUTH,
  905. KV_DELIMITER);
  906. (void) printf("\t%s\n\n", dclean);
  907. } else {
  908. (void) printf(
  909. "sr%d;sr;reserved;reserved;%s;",
  910. i, DEFAULT_DEV_ALLOC_AUTH);
  911. (void) printf("%s%s\n", SECLIB,
  912. "/sr_clean");
  913. }
  914. break;
  915. } else if (do_devmaps) {
  916. /* print device_maps for cd devices */
  917. if (first) {
  918. (void) printf(" ");
  919. } else {
  920. if (system_labeled) {
  921. (void) printf("%s%d%s\\\n",
  922. dname, i, KV_TOKEN_DELIMIT);
  923. (void) printf("\t%s%s\\\n",
  924. DA_CD_TYPE,
  925. KV_TOKEN_DELIMIT);
  926. (void) printf("\t");
  927. } else {
  928. (void) printf("sr%d:\\\n", i);
  929. (void) printf("\tsr:\\\n");
  930. (void) printf("\t");
  931. }
  932. first++;
  933. }
  934. (void) printf("%s", cd[j].name);
  935. }
  936. }
  937. if (do_devmaps && first) {
  938. (void) printf("\n\n");
  939. first = 0;
  940. }
  941. }
  942. if (do_files && cd_count) {
  943. dargs.rootdir = NULL;
  944. dargs.devnames = NULL;
  945. dargs.optflag = DA_ADD;
  946. for (entry = devlist.cd; entry != NULL; entry = entry->next) {
  947. dargs.devinfo = &(entry->devinfo);
  948. (void) da_update_device(&dargs);
  949. }
  950. }
  951. return (cd_count);
  952. }
  953. static void
  954. dormdisk(int cd_count)
  955. {
  956. DIR *dirp;
  957. struct dirent *dep; /* directory entry pointer */
  958. int i, j;
  959. char *nm; /* name/device of special device */
  960. int id; /* disk id */
  961. int ctrl; /* disk controller */
  962. int nrmdisk; /* max array size */
  963. int fd = -1;
  964. int rmdisk_count;
  965. int first = 0;
  966. int is_cd;
  967. int checked;
  968. int removable;
  969. char path[MAXPATHLEN];
  970. da_args dargs;
  971. deventry_t *entry;
  972. nrmdisk = DFLT_RMDISK;
  973. i = rmdisk_count = 0;
  974. /*
  975. * scan /dev/dsk for rmdisk devices
  976. */
  977. if ((dirp = opendir("/dev/dsk")) == NULL) {
  978. perror("gettext(open /dev/dsk failure)");
  979. exit(1);
  980. }
  981. while (dep = readdir(dirp)) {
  982. is_cd = 0;
  983. checked = 0;
  984. removable = 0;
  985. /* skip . .. etc... */
  986. if (strncmp(dep->d_name, ".", 1) == NULL)
  987. continue;
  988. /* get device # (disk #) */
  989. if (sscanf(dep->d_name, "c%dt%d", &ctrl, &id) != 2)
  990. continue;
  991. /* see if we've already examined this device */
  992. for (j = 0; j < i; j++) {
  993. if (id == rmdisk[j].id &&
  994. ctrl == rmdisk[j].controller &&
  995. (strcmp(dep->d_name, rmdisk[j].name) == 0)) {
  996. checked = 1;
  997. break;
  998. }
  999. if (id == rmdisk[j].id && ctrl != rmdisk[j].controller)
  1000. /*
  1001. * c2t0d0s0 is a different rmdisk than c3t0d0s0.
  1002. */
  1003. id = rmdisk[j].id + 1;
  1004. }
  1005. if (checked)
  1006. continue;
  1007. /* ignore if this is a cd */
  1008. for (j = 0; j < cd_count; j++) {
  1009. if (id == cd[j].id && ctrl == cd[j].controller) {
  1010. is_cd = 1;
  1011. break;
  1012. }
  1013. }
  1014. if (is_cd)
  1015. continue;
  1016. /* see if device is removable */
  1017. (void) snprintf(path, sizeof (path), "%s%s", "/dev/rdsk/",
  1018. dep->d_name);
  1019. if ((fd = open(path, O_RDONLY | O_NONBLOCK)) < 0)
  1020. continue;
  1021. (void) ioctl(fd, DKIOCREMOVABLE, &removable);
  1022. (void) close(fd);
  1023. if (removable == 0)
  1024. continue;
  1025. /*
  1026. * add new entry to table (/dev/dsk + / + d_name + \0)
  1027. * if array full, then expand it
  1028. */
  1029. if (i == nrmdisk) {
  1030. /* will exit(1) if insufficient memory */
  1031. nrmdisk = expandmem(i, (void **)&rmdisk,
  1032. sizeof (struct rmdisk));
  1033. /* When we expand rmdisk, need to expand rmdisk_r */
  1034. (void) expandmem(i, (void **)&rmdisk_r,
  1035. sizeof (struct rmdisk));
  1036. }
  1037. nm = (char *)malloc(SIZE_OF_DSK + 1 + strlen(dep->d_name) + 1);
  1038. if (nm == NULL)
  1039. no_memory();
  1040. (void) strcpy(nm, "/dev/dsk/");
  1041. (void) strcat(nm, dep->d_name);
  1042. rmdisk[i].name = nm;
  1043. rmdisk[i].id = id;
  1044. rmdisk[i].controller = ctrl;
  1045. rmdisk[i].device = "";
  1046. rmdisk[i].number = id;
  1047. rmdisk_r[i].name = strdup(path);
  1048. i++;
  1049. }
  1050. rmdisk_count = i;
  1051. (void) closedir(dirp);
  1052. for (i = 0, j = rmdisk_count; i < rmdisk_count; i++, j++) {
  1053. if (j == nrmdisk) {
  1054. /* will exit(1) if insufficient memory */
  1055. nrmdisk = expandmem(j, (void **)&rmdisk,
  1056. sizeof (struct rmdisk));
  1057. }
  1058. rmdisk[j].name = rmdisk_r[i].name;
  1059. rmdisk[j].id = rmdisk[i].id;
  1060. rmdisk[j].controller = rmdisk[i].controller;
  1061. rmdisk[j].device = rmdisk[i].device;
  1062. rmdisk[j].number = rmdisk[i].number;
  1063. }
  1064. rmdisk_count = j;
  1065. for (i = 0; i < 8; i++) {
  1066. for (j = 0; j < rmdisk_count; j++) {
  1067. if (rmdisk[j].id != i)
  1068. continue;
  1069. if (do_files) {
  1070. (void) da_add_list(&devlist, rmdisk[j].name, i,
  1071. DA_RMDISK);
  1072. } else if (do_devalloc) {
  1073. /* print device_allocate for rmdisk devices */
  1074. (void) printf("%s%d%s\\\n",
  1075. DA_RMDISK_NAME, i, KV_DELIMITER);
  1076. (void) printf("\t%s%s\\\n",
  1077. DA_RMDISK_TYPE, KV_DELIMITER);
  1078. (void) printf("\t%s%s\\\n",
  1079. DA_RESERVED, KV_DELIMITER);
  1080. (void) printf("\t%s%s\\\n",
  1081. DA_RESERVED, KV_DELIMITER);
  1082. (void) printf("\t%s%s\\\n",
  1083. DEFAULT_DEV_ALLOC_AUTH, KV_DELIMITER);
  1084. (void) printf("\t%s\n", DA_DEFAULT_DISK_CLEAN);
  1085. break;
  1086. } else if (do_devmaps) {
  1087. /* print device_maps for rmdisk devices */
  1088. if (first) {
  1089. (void) printf(" ");
  1090. } else {
  1091. (void) printf("%s%d%s\\\n",
  1092. DA_RMDISK_NAME, i,
  1093. KV_TOKEN_DELIMIT);
  1094. (void) printf("\t%s%s\\\n",
  1095. DA_RMDISK_TYPE, KV_TOKEN_DELIMIT);
  1096. (void) printf("\t");
  1097. first++;
  1098. }
  1099. (void) printf("%s", rmdisk[j].name);
  1100. }
  1101. }
  1102. if (do_devmaps && first) {
  1103. (void) printf("\n\n");
  1104. first = 0;
  1105. }
  1106. }
  1107. if (do_files && rmdisk_count) {
  1108. dargs.rootdir = NULL;
  1109. dargs.devnames = NULL;
  1110. dargs.optflag = DA_ADD;
  1111. for (entry = devlist.rmdisk; entry != NULL;
  1112. entry = entry->next) {
  1113. dargs.devinfo = &(entry->devinfo);
  1114. (void) da_update_device(&dargs);
  1115. }
  1116. }
  1117. }
  1118. /* set default array sizes */
  1119. static void
  1120. initmem()
  1121. {
  1122. tape = (struct tape *)calloc(DFLT_NTAPE, sizeof (struct tape));
  1123. audio = (struct audio *)calloc(DFLT_NAUDIO, sizeof (struct audio));
  1124. cd = (struct cd *)calloc(DFLT_NCD, sizeof (struct cd));
  1125. fp = (struct fp *)calloc(DFLT_NFP, sizeof (struct fp));
  1126. if (system_labeled) {
  1127. rmdisk = (struct rmdisk *)calloc(DFLT_RMDISK,
  1128. sizeof (struct rmdisk));
  1129. if (rmdisk == NULL)
  1130. no_memory();
  1131. rmdisk_r = (struct rmdisk *)calloc(DFLT_RMDISK,
  1132. sizeof (struct rmdisk));
  1133. if (rmdisk_r == NULL)
  1134. no_memory();
  1135. }
  1136. if (tape == NULL || audio == NULL || cd == NULL || fp == NULL)
  1137. no_memory();
  1138. devlist.audio = devlist.cd = devlist.floppy = devlist.rmdisk =
  1139. devlist.tape = NULL;
  1140. }
  1141. /* note n will be # elments in array (and could be 0) */
  1142. static int
  1143. expandmem(int n, void **array, int size)
  1144. {
  1145. void *old = *array;
  1146. void *new;
  1147. /* get new array space (n + DELTA) */
  1148. new = (void *)calloc(n + DELTA, size);
  1149. if (new == NULL) {
  1150. perror("memory allocation failed");
  1151. exit(1);
  1152. }
  1153. /* copy old array into new space */
  1154. bcopy(old, new, n * size);
  1155. /* now release old arrary */
  1156. free(old);
  1157. *array = new;
  1158. return (n + DELTA);
  1159. }
  1160. static void
  1161. no_memory(void)
  1162. {
  1163. (void) fprintf(stderr, "%s: %s\n", "mkdevalloc",
  1164. gettext("out of memory"));
  1165. exit(1);
  1166. /* NOT REACHED */
  1167. }