31 32#include <sys/param.h> 33#include <sys/systm.h> 34#include <sys/proc.h> 35#include <sys/stat.h> 36#include <sys/filedesc.h> 37#include <sys/jail.h> 38#include <sys/kernel.h> 39#include <sys/malloc.h> 40#include <sys/unistd.h> 41#include <sys/time.h> 42#include <sys/syscallsubr.h> 43#include <sys/sysctl.h> 44#include <sys/sysproto.h> 45#include <sys/un.h> 46 47#include <vm/vm.h> 48 49#include <netinet/in.h> 50 51#include <compat/svr4/svr4.h> 52#include <compat/svr4/svr4_types.h> 53#include <compat/svr4/svr4_signal.h> 54#include <compat/svr4/svr4_proto.h> 55#include <compat/svr4/svr4_util.h> 56#include <compat/svr4/svr4_stat.h> 57#include <compat/svr4/svr4_ustat.h> 58#include <compat/svr4/svr4_utsname.h> 59#include <compat/svr4/svr4_systeminfo.h> 60#include <compat/svr4/svr4_socket.h> 61#include <compat/svr4/svr4_time.h> 62#if defined(NOTYET) 63#include "svr4_fuser.h" 64#endif 65 66#ifdef sparc 67/* 68 * Solaris-2.4 on the sparc has the old stat call using the new 69 * stat data structure... 70 */ 71# define SVR4_NO_OSTAT 72#endif 73 74struct svr4_ustat_args { 75 svr4_dev_t dev; 76 struct svr4_ustat * name; 77}; 78 79static void bsd_to_svr4_xstat(struct stat *, struct svr4_xstat *); 80static void bsd_to_svr4_stat64(struct stat *, struct svr4_stat64 *); 81int svr4_ustat(struct thread *, struct svr4_ustat_args *); 82static int svr4_to_bsd_pathconf(int); 83 84/* 85 * SVR4 uses named pipes as named sockets, so we tell programs 86 * that sockets are named pipes with mode 0 87 */ 88#define BSD_TO_SVR4_MODE(mode) (S_ISSOCK(mode) ? S_IFIFO : (mode)) 89 90 91#ifndef SVR4_NO_OSTAT 92static void bsd_to_svr4_stat(struct stat *, struct svr4_stat *); 93 94static void 95bsd_to_svr4_stat(st, st4) 96 struct stat *st; 97 struct svr4_stat *st4; 98{ 99 memset(st4, 0, sizeof(*st4)); 100 st4->st_dev = bsd_to_svr4_odev_t(st->st_dev); 101 st4->st_ino = st->st_ino; 102 st4->st_mode = BSD_TO_SVR4_MODE(st->st_mode); 103 st4->st_nlink = st->st_nlink; 104 st4->st_uid = st->st_uid; 105 st4->st_gid = st->st_gid; 106 st4->st_rdev = bsd_to_svr4_odev_t(st->st_rdev); 107 st4->st_size = st->st_size; 108 st4->st_atim = st->st_atimespec.tv_sec; 109 st4->st_mtim = st->st_mtimespec.tv_sec; 110 st4->st_ctim = st->st_ctimespec.tv_sec; 111} 112#endif 113 114 115static void 116bsd_to_svr4_xstat(st, st4) 117 struct stat *st; 118 struct svr4_xstat *st4; 119{ 120 memset(st4, 0, sizeof(*st4)); 121 st4->st_dev = bsd_to_svr4_dev_t(st->st_dev); 122 st4->st_ino = st->st_ino; 123 st4->st_mode = BSD_TO_SVR4_MODE(st->st_mode); 124 st4->st_nlink = st->st_nlink; 125 st4->st_uid = st->st_uid; 126 st4->st_gid = st->st_gid; 127 st4->st_rdev = bsd_to_svr4_dev_t(st->st_rdev); 128 st4->st_size = st->st_size; 129 st4->st_atim = st->st_atimespec; 130 st4->st_mtim = st->st_mtimespec; 131 st4->st_ctim = st->st_ctimespec; 132 st4->st_blksize = st->st_blksize; 133 st4->st_blocks = st->st_blocks; 134 strcpy(st4->st_fstype, "unknown"); 135} 136 137 138static void 139bsd_to_svr4_stat64(st, st4) 140 struct stat *st; 141 struct svr4_stat64 *st4; 142{ 143 memset(st4, 0, sizeof(*st4)); 144 st4->st_dev = bsd_to_svr4_dev_t(st->st_dev); 145 st4->st_ino = st->st_ino; 146 st4->st_mode = BSD_TO_SVR4_MODE(st->st_mode); 147 st4->st_nlink = st->st_nlink; 148 st4->st_uid = st->st_uid; 149 st4->st_gid = st->st_gid; 150 st4->st_rdev = bsd_to_svr4_dev_t(st->st_rdev); 151 st4->st_size = st->st_size; 152 st4->st_atim = st->st_atimespec; 153 st4->st_mtim = st->st_mtimespec; 154 st4->st_ctim = st->st_ctimespec; 155 st4->st_blksize = st->st_blksize; 156 st4->st_blocks = st->st_blocks; 157 strcpy(st4->st_fstype, "unknown"); 158} 159 160int 161svr4_sys_stat(td, uap) 162 struct thread *td; 163 struct svr4_sys_stat_args *uap; 164{ 165 struct svr4_stat svr4_st; 166 struct stat st; 167 char *path; 168 int error; 169 170 CHECKALTEXIST(td, uap->path, &path); 171 172 error = kern_stat(td, path, UIO_SYSSPACE, &st); 173 free(path, M_TEMP); 174 if (error) 175 return (error); 176 bsd_to_svr4_stat(&st, &svr4_st); 177 178 if (S_ISSOCK(st.st_mode)) 179 (void) svr4_add_socket(td, uap->path, &st); 180 181 return (copyout(&svr4_st, uap->ub, sizeof svr4_st)); 182} 183 184 185int 186svr4_sys_lstat(td, uap) 187 register struct thread *td; 188 struct svr4_sys_lstat_args *uap; 189{ 190 struct svr4_stat svr4_st; 191 struct stat st; 192 char *path; 193 int error; 194 195 CHECKALTEXIST(td, uap->path, &path); 196 197 error = kern_lstat(td, path, UIO_SYSSPACE, &st); 198 free(path, M_TEMP); 199 if (error) 200 return (error); 201 bsd_to_svr4_stat(&st, &svr4_st); 202 203 if (S_ISSOCK(st.st_mode)) 204 (void) svr4_add_socket(td, uap->path, &st); 205 206 return (copyout(&svr4_st, uap->ub, sizeof svr4_st)); 207} 208 209 210int 211svr4_sys_fstat(td, uap) 212 register struct thread *td; 213 struct svr4_sys_fstat_args *uap; 214{ 215 struct svr4_stat svr4_st; 216 struct stat st; 217 int error; 218 219 220 error = kern_fstat(td, uap->fd, &st); 221 if (error) 222 return (error); 223 bsd_to_svr4_stat(&st, &svr4_st); 224 return (copyout(&svr4_st, uap->sb, sizeof svr4_st)); 225} 226 227 228int 229svr4_sys_xstat(td, uap) 230 register struct thread *td; 231 struct svr4_sys_xstat_args *uap; 232{ 233 struct svr4_xstat svr4_st; 234 struct stat st; 235 char *path; 236 int error; 237 238 CHECKALTEXIST(td, uap->path, &path); 239 240 error = kern_stat(td, path, UIO_SYSSPACE, &st); 241 free(path, M_TEMP); 242 if (error) 243 return (error); 244 245 bsd_to_svr4_xstat(&st, &svr4_st); 246 247#if defined(SOCKET_NOTYET) 248 if (S_ISSOCK(st.st_mode)) 249 (void) svr4_add_socket(td, uap->path, &st); 250#endif 251 252 return (copyout(&svr4_st, uap->ub, sizeof svr4_st)); 253} 254 255int 256svr4_sys_lxstat(td, uap) 257 register struct thread *td; 258 struct svr4_sys_lxstat_args *uap; 259{ 260 struct svr4_xstat svr4_st; 261 struct stat st; 262 char *path; 263 int error; 264 265 CHECKALTEXIST(td, uap->path, &path); 266 267 error = kern_lstat(td, path, UIO_SYSSPACE, &st); 268 free(path, M_TEMP); 269 if (error) 270 return (error); 271 272 bsd_to_svr4_xstat(&st, &svr4_st); 273 274#if defined(SOCKET_NOTYET) 275 if (S_ISSOCK(st.st_mode)) 276 (void) svr4_add_socket(td, uap->path, &st); 277#endif 278 return (copyout(&svr4_st, uap->ub, sizeof svr4_st)); 279} 280 281 282int 283svr4_sys_fxstat(td, uap) 284 register struct thread *td; 285 struct svr4_sys_fxstat_args *uap; 286{ 287 struct svr4_xstat svr4_st; 288 struct stat st; 289 int error; 290 291 292 error = kern_fstat(td, uap->fd, &st); 293 if (error) 294 return (error); 295 bsd_to_svr4_xstat(&st, &svr4_st); 296 return (copyout(&svr4_st, uap->sb, sizeof svr4_st)); 297} 298 299int 300svr4_sys_stat64(td, uap) 301 register struct thread *td; 302 struct svr4_sys_stat64_args *uap; 303{ 304 struct svr4_stat64 svr4_st; 305 struct stat st; 306 char *path; 307 int error; 308 309 CHECKALTEXIST(td, uap->path, &path); 310 311 error = kern_stat(td, path, UIO_SYSSPACE, &st); 312 free(path, M_TEMP); 313 if (error) 314 return (error); 315 316 bsd_to_svr4_stat64(&st, &svr4_st); 317 318 if (S_ISSOCK(st.st_mode)) 319 (void) svr4_add_socket(td, uap->path, &st); 320 321 return (copyout(&svr4_st, uap->sb, sizeof svr4_st)); 322} 323 324 325int 326svr4_sys_lstat64(td, uap) 327 register struct thread *td; 328 struct svr4_sys_lstat64_args *uap; 329{ 330 struct svr4_stat64 svr4_st; 331 struct stat st; 332 char *path; 333 int error; 334 335 CHECKALTEXIST(td, uap->path, &path); 336 337 error = kern_lstat(td, path, UIO_SYSSPACE, &st); 338 free(path, M_TEMP); 339 if (error) 340 return (error); 341 342 bsd_to_svr4_stat64(&st, &svr4_st); 343 344 if (S_ISSOCK(st.st_mode)) 345 (void) svr4_add_socket(td, uap->path, &st); 346 347 return (copyout(&svr4_st, uap->sb, sizeof svr4_st)); 348} 349 350 351int 352svr4_sys_fstat64(td, uap) 353 register struct thread *td; 354 struct svr4_sys_fstat64_args *uap; 355{ 356 struct svr4_stat64 svr4_st; 357 struct stat st; 358 int error; 359 360 error = kern_fstat(td, uap->fd, &st); 361 if (error) 362 return (error); 363 bsd_to_svr4_stat64(&st, &svr4_st); 364 return (copyout(&svr4_st, uap->sb, sizeof svr4_st)); 365} 366 367 368int 369svr4_ustat(td, uap) 370 register struct thread *td; 371 struct svr4_ustat_args *uap; 372{ 373 struct svr4_ustat us; 374 int error; 375 376 memset(&us, 0, sizeof us); 377 378 /* 379 * XXX: should set f_tfree and f_tinode at least 380 * How do we translate dev -> fstat? (and then to svr4_ustat) 381 */ 382 if ((error = copyout(&us, uap->name, sizeof us)) != 0) 383 return (error); 384 385 return 0; 386} 387 388/*extern char ostype[], hostname[], osrelease[], version[], machine[];*/ 389 390int 391svr4_sys_uname(td, uap) 392 register struct thread *td; 393 struct svr4_sys_uname_args *uap; 394{ 395 struct svr4_utsname sut; 396 397 memset(&sut, 0, sizeof(sut)); 398 399 strlcpy(sut.sysname, ostype, sizeof(sut.sysname)); 400 getcredhostname(td->td_ucred, sut.nodename, sizeof(sut.nodename)); 401 strlcpy(sut.release, osrelease, sizeof(sut.release)); 402 strlcpy(sut.version, version, sizeof(sut.version)); 403 strlcpy(sut.machine, machine, sizeof(sut.machine)); 404 405 return copyout((caddr_t) &sut, (caddr_t) uap->name, 406 sizeof(struct svr4_utsname)); 407} 408 409int 410svr4_sys_systeminfo(td, uap) 411 struct thread *td; 412 struct svr4_sys_systeminfo_args *uap; 413{ 414 char *str = NULL; 415 int error = 0; 416 register_t *retval = td->td_retval; 417 size_t len = 0; 418 char buf[1]; /* XXX NetBSD uses 256, but that seems 419 like awfully excessive kstack usage 420 for an empty string... */ 421 u_int rlen = uap->len; 422 423 switch (uap->what) { 424 case SVR4_SI_SYSNAME: 425 str = ostype; 426 break; 427 428 case SVR4_SI_HOSTNAME: 429 str = hostname; 430 break; 431 432 case SVR4_SI_RELEASE: 433 str = osrelease; 434 break; 435 436 case SVR4_SI_VERSION: 437 str = version; 438 break; 439 440 case SVR4_SI_MACHINE: 441 str = machine; 442 break; 443 444 case SVR4_SI_ARCHITECTURE: 445 str = machine; 446 break; 447 448 case SVR4_SI_HW_SERIAL: 449 str = "0"; 450 break; 451 452 case SVR4_SI_HW_PROVIDER: 453 str = ostype; 454 break; 455 456 case SVR4_SI_SRPC_DOMAIN:
|
458 str = domainname; 459 break; 460 461 case SVR4_SI_PLATFORM: 462#ifdef __i386__ 463 str = "i86pc"; 464#else 465 str = "unknown"; 466#endif 467 break; 468 469 case SVR4_SI_KERB_REALM: 470 str = "unsupported"; 471 break; 472#if defined(WHY_DOES_AN_EMULATOR_WANT_TO_SET_HOSTNAMES) 473 case SVR4_SI_SET_HOSTNAME: 474 name = KERN_HOSTNAME; 475 return kern_sysctl(&name, 1, 0, 0, uap->buf, rlen, td); 476 477 case SVR4_SI_SET_SRPC_DOMAIN: 478 name = KERN_NISDOMAINNAME; 479 return kern_sysctl(&name, 1, 0, 0, uap->buf, rlen, td); 480#else 481 case SVR4_SI_SET_HOSTNAME: 482 case SVR4_SI_SET_SRPC_DOMAIN: 483 /* FALLTHROUGH */ 484#endif 485 case SVR4_SI_SET_KERB_REALM: 486 return 0; 487 488 default: 489 DPRINTF(("Bad systeminfo command %d\n", uap->what)); 490 return ENOSYS; 491 } 492 493 if (str) { 494 len = strlen(str) + 1; 495 if (len > rlen) 496 len = rlen; 497 498 if (uap->buf) { 499 error = copyout(str, uap->buf, len); 500 if (error) 501 return error; 502 /* make sure we are NULL terminated */ 503 buf[0] = '\0'; 504 error = copyout(buf, &(uap->buf[len - 1]), 1); 505 } 506 else 507 error = 0; 508 } 509 /* XXX NetBSD has hostname setting stuff here. Why would an emulator 510 want to do that? */ 511 512 *retval = len; 513 return error; 514} 515 516int 517svr4_sys_utssys(td, uap) 518 register struct thread *td; 519 struct svr4_sys_utssys_args *uap; 520{ 521 switch (uap->sel) { 522 case 0: /* uname(2) */ 523 { 524 struct svr4_sys_uname_args ua; 525 ua.name = uap->a1; 526 return svr4_sys_uname(td, &ua); 527 } 528 529 case 2: /* ustat(2) */ 530 { 531 struct svr4_ustat_args ua; 532 ua.dev = (svr4_dev_t) uap->a2; 533 ua.name = uap->a1; 534 return svr4_ustat(td, &ua); 535 } 536 537 case 3: /* fusers(2) */ 538 return ENOSYS; 539 540 default: 541 return ENOSYS; 542 } 543 return ENOSYS; 544} 545 546 547int 548svr4_sys_utime(td, uap) 549 register struct thread *td; 550 struct svr4_sys_utime_args *uap; 551{ 552 struct svr4_utimbuf ub; 553 struct timeval tbuf[2], *tp; 554 char *path; 555 int error; 556 557 if (uap->ubuf != NULL) { 558 error = copyin(uap->ubuf, &ub, sizeof(ub)); 559 if (error) 560 return (error); 561 tbuf[0].tv_sec = ub.actime; 562 tbuf[0].tv_usec = 0; 563 tbuf[1].tv_sec = ub.modtime; 564 tbuf[1].tv_usec = 0; 565 tp = tbuf; 566 } else 567 tp = NULL; 568 569 CHECKALTEXIST(td, uap->path, &path); 570 error = kern_utimes(td, path, UIO_SYSSPACE, tp, UIO_SYSSPACE); 571 free(path, M_TEMP); 572 return (error); 573} 574 575 576int 577svr4_sys_utimes(td, uap) 578 register struct thread *td; 579 struct svr4_sys_utimes_args *uap; 580{ 581 char *path; 582 int error; 583 584 CHECKALTEXIST(td, uap->path, &path); 585 error = kern_utimes(td, path, UIO_SYSSPACE, uap->tptr, UIO_USERSPACE); 586 free(path, M_TEMP); 587 return (error); 588} 589 590static int 591svr4_to_bsd_pathconf(name) 592 int name; 593{ 594 switch (name) { 595 case SVR4_PC_LINK_MAX: 596 return _PC_LINK_MAX; 597 598 case SVR4_PC_MAX_CANON: 599 return _PC_MAX_CANON; 600 601 case SVR4_PC_MAX_INPUT: 602 return _PC_MAX_INPUT; 603 604 case SVR4_PC_NAME_MAX: 605 return _PC_NAME_MAX; 606 607 case SVR4_PC_PATH_MAX: 608 return _PC_PATH_MAX; 609 610 case SVR4_PC_PIPE_BUF: 611 return _PC_PIPE_BUF; 612 613 case SVR4_PC_NO_TRUNC: 614 return _PC_NO_TRUNC; 615 616 case SVR4_PC_VDISABLE: 617 return _PC_VDISABLE; 618 619 case SVR4_PC_CHOWN_RESTRICTED: 620 return _PC_CHOWN_RESTRICTED; 621 case SVR4_PC_SYNC_IO: 622#if defined(_PC_SYNC_IO) 623 return _PC_SYNC_IO; 624#else 625 return 0; 626#endif 627 case SVR4_PC_ASYNC_IO: 628 case SVR4_PC_PRIO_IO: 629 /* Not supported */ 630 return 0; 631 632 default: 633 /* Invalid */ 634 return -1; 635 } 636} 637 638 639int 640svr4_sys_pathconf(td, uap) 641 register struct thread *td; 642 struct svr4_sys_pathconf_args *uap; 643{ 644 char *path; 645 int error, name; 646 647 name = svr4_to_bsd_pathconf(uap->name); 648 649 switch (name) { 650 case -1: 651 td->td_retval[0] = -1; 652 return (EINVAL); 653 case 0: 654 td->td_retval[0] = 0; 655 return (0); 656 default: 657 CHECKALTEXIST(td, uap->path, &path); 658 error = kern_pathconf(td, path, UIO_SYSSPACE, name); 659 free(path, M_TEMP); 660 return (error); 661 } 662} 663 664 665int 666svr4_sys_fpathconf(td, uap) 667 register struct thread *td; 668 struct svr4_sys_fpathconf_args *uap; 669{ 670 register_t *retval = td->td_retval; 671 672 uap->name = svr4_to_bsd_pathconf(uap->name); 673 674 switch (uap->name) { 675 case -1: 676 *retval = -1; 677 return EINVAL; 678 case 0: 679 *retval = 0; 680 return 0; 681 default: 682 return fpathconf(td, (struct fpathconf_args *)uap); 683 } 684}
|