Friday, May 12, 2017

Daemons

Fortunately, as a good Unix system, Solaris supports easy daemon creation by encapsulating all the necessary steps into a single system function called daemon(3C). Thus the whole process of becoming a daemon is greatly simplified when compared to the traditional / legacy approach:

#include <sys/types.h> 
#include <sys/stat.h> 
#include <unistd.h> 

#include <cerrno> 
#include <cstdlib> 
#include <cstdarg> 

#include "toolbox.hxx"

void error( toolbox::log & log, const char * message )
{
  int code = errno;
  log.write( "ERROR: %s (%d)\n", message, code );
  ::exit( EXIT_FAILURE );
}

int main( )
{
  toolbox::log log( "trace.log" );

  if ( ! log.open() )
    return EXIT_FAILURE;

  log.write( "Starting up...\n" );

  if ( ::daemon( 0, 0 ) < 0 )
    error( log, "Couldn't become a daemon." );

  log.write( "Successfully became a daemon!\n" );
 
  
  ::umask( 0 );
 
  const int seconds = 30;
  log.write( "Resting for %d seconds...\n", seconds );
  ::sleep( seconds );

  log.write( "Bye cruel world!\n\n" );
  log.close();

  return EXIT_SUCCESS;
}


A typical log output could be similar to:

$ cat trace.log
[2017-05-12 16:29:11] Starting up...
[2017-05-12 16:29:11] Successfully became a daemon!
[2017-05-12 16:29:11] Resting for 30 seconds...
[2017-05-12 16:29:41] Bye cruel world!


It may be interesting to take a look under the hood at the system calls encapsulated by daemon(3C) in order to compare it with the traditional / legacy approach:

$ truss -f ./daemon-01
...
... getcwd("/...", 1024) = 0
... open("/.../trace.log", O_WRONLY|O_APPEND|O_CREAT, 0640) = 3

...
3155:    write(3, " [ 2 0 1 7 - 0 5 - 1 2  ".., 22) = 22
3155:    write(3, " S t a r t i n g   u p .".., 15) = 15
...
3155:    forkx(0)                                   = 3156
 

3155:    _exit(0)
... 
3156:    forkx()        (returning as child ...)    = 3155
3156:    getpid()                                   = 3156 [3155]
...
3156:    setsid()                                   = 3156
...
3156:    forkx(0)                                   = 3158
3156:    _exit(0)
...
3158:    forkx()        (returning as child ...)    = 3156
3158:    getpid()                                   = 3158 [1]
...
3158:    chdir("/")                                 = 0

...
3158:    open("/dev/null", O_RDWR)                  = 4
3158:    fcntl(4, F_DUP2FD, 0x00000000)             = 0
3158:    fcntl(4, F_DUP2FD, 0x00000001)             = 1
3158:    fcntl(4, F_DUP2FD, 0x00000002)             = 2
3158:    close(4)                                   = 0
...
3158:    write(3, " [ 2 0 1 7 - 0 5 - 1 2  ".., 22) = 22
3158:    write(3, " S u c c e s s f u l l y".., 30) = 30
...

3158:    umask(0)                                   = 022
...
3158:    write(3, " [ 2 0 1 7 - 0 5 - 1 2  ".., 22) = 22
3158:    write(3, " R e s t i n g   f o r  ".., 26) = 26
3158:    nanosleep(...) (sleeping...)
3158:    nanosleep(...) = 0
...
3158:    write(3, " [ 2 0 1 7 - 0 5 - 1 2  ".., 22) = 22
3158:    write(3, " B y e   c r u e l   w o".., 18) = 18
3158:    close(3)                                   = 0
...
3158:    _exit(0)

   

Thursday, May 11, 2017

Daemons - 1st steps

In the very start of the endeavor to the daemons' underground world I thought it would be inevitable to be acquainted with a few, perhaps new, essential concepts about processes in terms of how they are collected within the system. So I set out to knowing more about sessions and process groups. It was very instructive as a ground to better undrestanding the necessary steps to turn an ordinary process into a daemon in the traditional way. So, without further words, in essence, the main() function of a Solaris C++ program (or application) that is (or becomes) a daemon in the traditional way is:

#include <sys/types.h> 
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

#include <cerrno> 
#include <cstring>
#include <csignal> 
#include <cstdlib>
#include <cstdio>  
#include <cstdarg>  

#include <string>
#include <iostream>

#include "toolbox.hxx"

int main()
{
  // Some other log file or even syslog could be better.
  // This is just for illustrational purposes.

  // The full implementation is elsewhere. 
  toolbox::log log( "trace.log" );

  if ( log.open() )
    std::cout
       << "Log file: "
       << log.filename
       << std::endl;
  else
  {
    std::cout
       << "FAILURE"
       << std::endl;

    ::exit( EXIT_FAILURE );
  }
  

  // This function does all the "magic"!
  daemon( log );

  log.write( "Finally, success! I'm a daemon!\n" );

  const int seconds = 30;
  log.write( "Resting for %d seconds...\n", seconds );
  ::sleep( seconds );

  log.write( "Bye cruel world!\n\n" );
  log.close();

  return EXIT_SUCCESS;
}


Now let me show the magical :-) daemon() function:

// Little helper...
void error( const toolbox::log & log, const char * msg, ... )
{

  int code = errno;

  va_list ap;
  va_start( ap, msg );

  // MT-safe if setlocale(3C) not called
  // Hence, possbily a serious limitation!
  // More advanced C++ to the rescue!

  char * buffer = 0;
  ::vasprintf( &buffer, msg, ap );
  log.write( "ERROR: %s (%s)\n", buffer, ::strerror(code) );
  ::free( buffer );

  va_end( ap );


  ::exit( EXIT_FAILURE );
}

void daemon( toolbox::log & log )
{
  if ( ! log.write( "\n\nTrying to \"become\" daemon ...\n\n" ) )
    ::exit( EXIT_FAILURE );

  pid_t pid;

  // Creates a new process in the same process group.
  // Sure is the new process is NOT a process group leader.
  // The new process will be entitled to create a new session.

  if ( ( pid = ::fork() ) < 0 )
    error( log, "1st call to fork()" );
  else if ( pid > 0 )
  {
    log.write( "Bye 1st generation descendant!\n" );
    log.write( "PID %d to become a daemon!\n\n", pid );
    ::exit( EXIT_SUCCESS );
  }

  // Creates a new session, effectively
  // disassociating from the controlling terminal.

  if ( ::setsid() < 0 )
    error( log, "setsid()" );

  // The SIGHUP does not apply to me anymmore.
  // There's no controlling terminal after all!
 
  if ( ::sigignore( SIGHUP ) )
    error( log, "sigignore()" ); 


  // Creates another new process in the new process group.
  // Sure is the new process is NOT a process group leader.
  // The new process won't EVER get a controlling terminal.

  if ( ( pid = ::fork() ) < 0 )
    error(  log, "2nd call to fork()" );
  else if ( pid > 0 )
  {
    log.write( "Bye 2nd generation descendant!\n" );
    log.write( "PID %d to become a daemon!\n\n", pid );
    ::exit( EXIT_SUCCESS );
  }

  //
  // Finally! Almost there...
  //


  // Initially assures full access to daemon's own files.
  // Later, should be diligently and temporarily set to 007,
  // specially before library calls that involve files.

  ::umask( 0 );

  // Changes to the selected working directory
  // or at least to / so any unmounts should succeed.

  // After this call don't forget to specify full paths!
  if ( ::chdir( "/" ) < 0 )
    error( log, "chdir()" );


  {
    // Makes sure there's no left over open files.
    log.close();
    ::fcloseall();

    // Mute all the standard files.
    const int std_stream[] =
    {
      ::open( "/dev/null", O_RDWR ), // stdin
      ::dup2( 0, 1 ),                // stdout
      ::dup2( 0, 2 )                 // stderr
    };

    if ( ! log.open() )
      exit( EXIT_FAILURE );

    // Double-check muted descriptors are 0, 1 and 2.
    for ( auto i=0; i<3; i++ )
      if ( std_stream[ i ] != i )
        error( log, "Muting standard files." );
  }
}


A log file produced by running this daemon could be:
 
$ cat trace.log
[2017-05-11 16:29:29]
 

Trying to "become" daemon ...

[2017-05-11 16:29:29] Bye 1st generation descendant!
[2017-05-11 16:29:29] PID 2508 to become a daemon!

[2017-05-11 16:29:29] Bye 2nd generation descendant!
[2017-05-11 16:29:29] PID 2509 to become a daemon!

[2017-05-11 16:29:29] Finally, success! I'm a daemon!
[2017-05-11 16:29:29] Resting for 30 seconds...
[2017-05-11 16:29:59] Bye cruel world!

   
The above approach, although traditional is not the recommended one. Nevertheless it's still possible to catch once in a while some daemons logs in SMF logs which reveal they could only have been programmed the old way...
  

Wednesday, May 10, 2017

OpenOffice install

This post is intended as a memorial or historical mention of how good Solaris is as a desktop for general applications as well as it is a superb multipurpose back-end operating system for many kinds of IT infra-structure. Once more, please, note that I intend no Copyrights infringements or any other mis-purposed suggestions. On the contrary, I would recommend going for Solaris and perhaps attempting to build updated applications with the current tools and, of course, abiding to any associated policies and requirements, for instance, the ASF policy.

Following the above disclaimer, I would like to present a mainstream desktop application that once also run very well in a Solaris desktop system, OpenOffice. Nowadays, the current (at the time of this writing) 4.1.3 version isn't available as a pre-built Solaris package or so, but it may be possible to build from the source code that do is publicly available together with some developer's support basic documentation such as:

And some "archived" info that may still be useful: 

As to how to install it I'll show a sample installation of version 3.3.0 built by Oracle that still runs on Solaris 11.3, except to known / published Java 1.6 security issues to which there are no workarounds except to use the system disconnected from the Internet:

  


NOTE
Although marked as obsolete, the application features have always been far more than the average user would ever need, specially with the handy Unix goodies such as simple "print as PDF" and so on. Such goodies took more than a decade to decently appear on other more popular platforms...

In my case I will demonstrate the installation of the en-US version together with the addition of 1 (one) extension for the Brazilian-Portuguese Spelling Dictionary. This amounts to an "almost" (due to old Java issues) fully functional Office Suite for a partial multi-language scneario. The (quite small in relation to the final power) distribution files once were:
 
  • OOo_3.3.0_Solaris_x86_install-wJRE_en-US.tar.gz
    29c91b7a123f207ee636c909c563661c (~189 Mb)
     
  • OOo_3.3.0_Solaris_x86_langpack_pt-BR.tar.gz
    e338dfb3149d19b085328c2c47552e31 (~ 13 Mb)

Although the distribution includes a JRE at first I don't use it in this demonstration because it's obsolete and has security issues as you most probably know very well. Furthermore, I was curious to see how it would behave with the more current Java installation found in Solaris 11.3 (GA / Release) which is:
 
$ java -version
java version "1.8.0_60"
Java(TM) SE Runtime Environment (build 1.8.0_60-b27)
Java HotSpot(TM) 64-Bit Server VM (build 25.60-b23, mixed mode)


So I extracted the two aforementioned filesets each to a distinct subdirectory of /tmp, to know more about their contents:

$ mkdir -p /tmp/OO
$ cd /tmp/OO

$ tar xzf /.../OOo_3.3.0_Solaris_x86_install-wJRE_en-US.tar.gz
$ tar xzf /.../OOo_3.3.0_Solaris_x86_langpack_pt-BR.tar.gz

$ ll * 
OOO330_m20_native_packed-1_en-US.9567:
total 920
-rwxr-xr-x   1 ... update
drwxr-xr-x   2 ... readmes
drwxr-xr-x   2 ... licenses
-rwxr-xr-x   1 ... setup
-rw-r--r--   1 ... JavaSetup.jar
drwxr-xr-x  53 ... packages
drwxr-xr-x   5 ... installdata

OOO330_m20_native_packed-1_pt-BR.9567:
total 8
drwxr-xr-x  14 ... packages


I tried to install it as root, by adjusting X11 access under a SU. But it didn't succeed at first with a message complaining that no adequate Java support was available. And that was right as I got to know by inspecting the installation script and finding out the supported versions were 1.4, 1.5 and 1.6. Nevertheless, I edited the script (setup) and added my version, 1.8 and fortunately that let the script happy enough to go on.

#!/bin/sh

jarfilename="JavaSetup.jar"
tempdir=/var/tmp/install_$$
java_runtime="java"
java_runtime_set="no"
java_runtime_found="no"
java_runtime_sufficient="no"
java_versions_supported="1.4 1.5 1.6 1.8"
rpm2cpio_found="no"
rpm_found="no"
sunjavahotspot="HotSpot"
errortext=""
errorcode=""


...

Of course this ought to have some consequences.
The first one came right after launching setup:

# ./setup


I clicked OK and then:

 

I could only click Next:


Of course the Typical shouldn't work well due to the obsolescence.
So I chose Custom and clicked Next:



Having chosen what make more sense to me, I clicked Next:



As everything seemed fine, I clicked Install Now:


And after a while:


I finally clicked Finish.

As having a pending issue around Java, the first thing I did next was to launch the "basic hosting" of the suite and try to make sure (under Tools | Options) it shouldn't expect much of any Java installation (but not before passing through the 1st time registration dialog and one more Java warning message as previously shown...).




# which openoffice.org3
/usr/bin/openoffice.org3


# openoffice.org3



And that completed my installation.
The desktop integration was cool:


By the way, regarding Printer Administration I chose:





Finally, the last step was to install the additional extension for a convenience dictionary to one of my languages. At first I had no idea how to install it but browsing the fileset directory I saw:

# cd /tmp/OO/OOO330_m20_native_packed-1_pt-BR.9567
# ll packages/openofficeorg3-dict-pt/
 total 40
-rw-r--r--   1 ... pkginfo
drwxr-xr-x   3 ... reloc
-rw-r--r--   1 ... pkgmap
drwxr-xr-x   2 ... install
drwxr-xr-x   2 ... archive

 
This reminded me of another study I posted long ago: SVr4 relocatable package. More specifically, the output of pkgmk(1) before being streamed via pkgtrans(1). So I attempted to treat it as a non-streamed SVr4 package and it worked!

# pkgadd -d ./packages/

The following packages are available:
  1  ooobasis33-pt-BR            Language module ...  

  2  ooobasis33-pt-BR-base       Base language module ....
  3  ooobasis33-pt-BR-binfilter  Legacy filters ...
  4  ooobasis33-pt-BR-calc       Calc language module ...
  5  ooobasis33-pt-BR-draw       Draw language module ...
  6  ooobasis33-pt-BR-help       Language help module ...
  7  ooobasis33-pt-BR-impress    Impress language module ...  

  8  ooobasis33-pt-BR-math       Math language module ...
  9  ooobasis33-pt-BR-res        Language resource module ...

 10  ooobasis33-pt-BR-writer     Writer language module ...
 

... 2 more menu choices to follow;
<RETURN> for more choices, <CTRL-D> to stop display:

 11  openofficeorg3-dict-pt      Pt dictionary ...
 12  openofficeorg3-pt-BR        Brand language module ...

Select package(s) you wish to process (or 'all' to process
all packages). (default: all) [?,??,q]:
11


Processing ... <openofficeorg3-dict-pt> from </tmp/...>

Pt dictionary for OpenOffice.org 3.3(i386) 3.3.0,REV=...
Copyright 2000, 2010 Oracle and/or its affiliates. 

All rights reserved.
Use is subject to license terms.

This product is made available subject to the terms of GNU Lesser General Public License Version 3. A copy of the LGPL license can be found at http://www.openoffice.org/license.html

------------------------------------
Third Party Code. Additional copyright notices and license terms applicable to portions of the Software are set forth in the THIRDPARTYLICENSEREADME.html file.

------------------------------------
All trademarks and registered trademarks mentioned herein are the property of their respective owners. 

------------------------------------
Copyright (c) 2000,2010 Oracle and/or it affiliates. 

All rights reserved.

This product has been created with contributions from the OpenOffice.org community, of which Oracle is a principal member. OpenOffice.org acknowledges all community members, especially those mentioned at http://www.openoffice.org/welcome/credits.html.

------------------------------------

           GNU LESSER GENERAL PUBLIC LICENSE
                       Version 3, 29 June 2007

...


Using </> as the package base directory.
## Processing package information.
## Processing system information.
   3 package pathnames are already properly installed.
## Verifying package dependencies.
## Verifying disk space requirements.
## Checking for conflicts with packages already installed.
## Checking for setuid/setgid programs.

... contains scripts which will be executed with super-user
permission during the process of installing this package.

... continue with the installation ... [y,n,?]
y

Installing Pt dictionary for OpenOffice.org 3.3 ...

## Installing part 1 of 1.
10261 blocks
## Executing postinstall script.

Installation of <openofficeorg3-dict-pt> was successful.

 
Finally!



But that's not yet the whole story...
There pending issue around Java will seriously impair many functions.
So I decided to install Java 1.6 and use it disconnected from the Internet.
To find the missing piece of software I went to Oracle Java Archive.
I acknowledged the warnings and disclaimers and proceeded to Java 6 SE:
 

In my case I downloaded to /downloads/java:
  • jre-6u45-solaris-i586.sh
  • jre-6u45-solaris-x64.sh

The "special-purpose installation" was quite simple:

# cd /opt
# bash /downloads/java/jre-6u45-solaris-i586.sh

Finally, I "activated it" in OpenOffice by going to Tools | Options, clicking on the Add... button and by navigating to and selecting /opt/jre1.6.0_45:


NOTE
I perhaps should have considered a better location to install the Java 6 Update 45 package. According to part of another post, Updating Java ad hoc, I probably should have expanded it to /usr/jdk/instances/ and have created a symbolic link on the parent directory and have used this last symbolic link on the above dialog.
NOTE
I know that Java 8 didn't work, but I'm not sure if there's anything to do with bitness (Java 8 is always 64-bits). I haven't tested a 32-bits Java 7 Update 80 instead of Java 6 Update 45 on the above dialog, but if it works, then there could be a chance of using an up-to-date 32-bits manually built OpenJDK alternative; that would be cool.
   

Monday, May 8, 2017

Last login - GUI

Possibly one the first things I've noticed on Solaris 11.3 was the change of login policy last login notification message immediately perceived at the GUI login. Later on an Oracle article talked about it which I considered very useful, Last login tracking in pam_unix_session, and where you can learn more about the change. Under the hood was pam_unix_session(5) a.k.a. pam_unix_session.so.1. By the way, the last logins are registered on the binary file /var/adm/lastlog. To know more about this and other related files you can read login(1) (specially the FILES topic to the end of it) and utmpx(4).

The "new" warning notice is important (even for compliance) as a simple yet crucial security verification: if the system is telling me that my last login was on a date and time I do not recognize, then my account most probably have been compromised! But on some other rather specific scenarios the message can be really annoying. Thus it would be nice to get rid of it:


But how? The aforementioned article tells us how: by tuning the PAM.
I reproduce it here just for added convenience...

Create or update the following file:

$ ll /etc/pam.d/gdm
-rw-r--r--   1 root  sys    52 ... /etc/pam.d/gdm


And add or adjust the following line:

$ grep session /etc/pam.d/gdm
session  required    pam_unix_session.so.1   nowarn

  
Cool!

VirtualBox VM additions

I took a long while until the VirtualBox Guest Additions for Solaris become available. So long that I used to not count on it ever more. But then all of a sudden for some reason I can't remember why I mounted the VirtualBox 5.1.18 Guest Additions on a Solaris 11.3 and happily noticed that, yes, they were there! It's an old (SVr4) Solaris package file (.pkg extension). So I immediately set to install it but, as usual, there was no available documentation, at least I couldn't easily find it. At first I tried an unattended SVr4 package install but it didn't work so I was forced to do it interactively.

For recap I started by mounting the VirtualBox Guest Additions as follows:


And then the usual optical media icon kicked in on my desktop:


But double-clicking on it won't work as expected, unfortunately. They probably didn't have the time for this final perfection, but I wonder if that was a typical case of lazyness; whatever, I went to the very comfortable CLI and served myself:

# cd /media/VBOXADDITIONS_5.1.18_114002

# ll *.pkg
-r-xr-xr-x   1 root root  17M ... VBoxSolarisAdditions.pkg

 
# pkgadd -d VBoxSolarisAdditions.pkg all

Processing package instance <SUNWvboxguest> from </media/VBOXADDITIONS_5.1.18_114002/VBoxSolarisAdditions.pkg>

Oracle VM VirtualBox Guest Additions(i386) 5.1.18,REV=r114002.2017.03.15.16.33
Oracle Corporation
Using </> as the package base directory.
## Processing package information.
## Processing system information.
## Verifying package dependencies.
## Verifying disk space requirements.
## Checking for conflicts with packages already installed.
## Checking for setuid/setgid programs.

... contains scripts which will be executed with super-user
permission during the process of installing this package.

... continue with the installation of <SUNWvboxguest> [y,n,?]
y

Installing ... Guest Additions as <SUNWvboxguest>

## Installing part 1 of 1.
/etc/fs/vboxfs/mount <symbolic link>
/opt/VirtualBoxAdditions/1099.vboxclient
/opt/VirtualBoxAdditions/LICENSE
/opt/VirtualBoxAdditions/VBox.sh
/opt/VirtualBoxAdditions/VBoxControl
/opt/VirtualBoxAdditions/amd64/VBoxClient.Z
/opt/VirtualBoxAdditions/amd64/VBoxControl.Z
/opt/VirtualBoxAdditions/amd64/VBoxService.Z
/opt/VirtualBoxAdditions/amd64/pam_vbox.so
/opt/VirtualBoxAdditions/amd64/vboxfs
/opt/VirtualBoxAdditions/amd64/vboxfs_s10
/opt/VirtualBoxAdditions/amd64/vboxfsmount
/opt/VirtualBoxAdditions/amd64/vboxmslnk
/opt/VirtualBoxAdditions/amd64/vboxvideo_drv_110.so.Z
/opt/VirtualBoxAdditions/amd64/vboxvideo_drv_111.so.Z
/opt/VirtualBoxAdditions/amd64/vboxvideo_drv_112.so.Z
/opt/VirtualBoxAdditions/amd64/vboxvideo_drv_113.so.Z
/opt/VirtualBoxAdditions/amd64/vboxvideo_drv_114.so.Z
/opt/VirtualBoxAdditions/amd64/vboxvideo_drv_117.so.Z
/opt/VirtualBoxAdditions/amd64/vboxvideo_drv_118.so.Z
/opt/VirtualBoxAdditions/amd64/vboxvideo_drv_13.so.Z
/opt/VirtualBoxAdditions/amd64/vboxvideo_drv_14.so.Z
/opt/VirtualBoxAdditions/amd64/vboxvideo_drv_15.so.Z
/opt/VirtualBoxAdditions/amd64/vboxvideo_drv_16.so.Z
/opt/VirtualBoxAdditions/amd64/vboxvideo_drv_17.so.Z
/opt/VirtualBoxAdditions/amd64/vboxvideo_drv_18.so.Z
/opt/VirtualBoxAdditions/amd64/vboxvideo_drv_19.so.Z
/opt/VirtualBoxAdditions/amd64/vboxvideo_drv_70.so.Z
/opt/VirtualBoxAdditions/amd64/vboxvideo_drv_71.so.Z
/opt/VirtualBoxAdditions/i386/VBoxClient.Z
/opt/VirtualBoxAdditions/i386/VBoxControl.Z
/opt/VirtualBoxAdditions/i386/VBoxService.Z
/opt/VirtualBoxAdditions/i386/pam_vbox.so
/opt/VirtualBoxAdditions/i386/vboxfs
/opt/VirtualBoxAdditions/i386/vboxfs_s10
/opt/VirtualBoxAdditions/i386/vboxfsmount
/opt/VirtualBoxAdditions/i386/vboxmslnk
/opt/VirtualBoxAdditions/i386/vboxvideo_drv_110.so.Z
/opt/VirtualBoxAdditions/i386/vboxvideo_drv_111.so.Z
/opt/VirtualBoxAdditions/i386/vboxvideo_drv_112.so.Z
/opt/VirtualBoxAdditions/i386/vboxvideo_drv_113.so.Z
/opt/VirtualBoxAdditions/i386/vboxvideo_drv_114.so.Z
/opt/VirtualBoxAdditions/i386/vboxvideo_drv_117.so.Z
/opt/VirtualBoxAdditions/i386/vboxvideo_drv_118.so.Z
/opt/VirtualBoxAdditions/i386/vboxvideo_drv_13.so.Z
/opt/VirtualBoxAdditions/i386/vboxvideo_drv_14.so.Z
/opt/VirtualBoxAdditions/i386/vboxvideo_drv_15.so.Z
/opt/VirtualBoxAdditions/i386/vboxvideo_drv_16.so.Z
/opt/VirtualBoxAdditions/i386/vboxvideo_drv_17.so.Z
/opt/VirtualBoxAdditions/i386/vboxvideo_drv_18.so.Z
/opt/VirtualBoxAdditions/i386/vboxvideo_drv_19.so.Z
/opt/VirtualBoxAdditions/i386/vboxvideo_drv_70.so.Z
/opt/VirtualBoxAdditions/i386/vboxvideo_drv_71.so.Z
/opt/VirtualBoxAdditions/solaris_xorg.conf
/opt/VirtualBoxAdditions/solaris_xorg_modeless.conf
/opt/VirtualBoxAdditions/vbox_vendor_select
/opt/VirtualBoxAdditions/vboxclient.desktop
/opt/VirtualBoxAdditions/vboxguest.sh
/opt/VirtualBoxAdditions/x11config15sol.pl
/opt/VirtualBoxAdditions/x11restore.pl
/usr/bin/VBoxClient <symbolic link>
/usr/bin/VBoxClient-all <symbolic link>
/usr/bin/VBoxControl <symbolic link>
/usr/bin/VBoxService <symbolic link>
/usr/kernel/drv/amd64/vboxguest
/usr/kernel/drv/amd64/vboxms
/usr/kernel/drv/vboxguest
/usr/kernel/drv/vboxguest.conf
/usr/kernel/drv/vboxms
/usr/kernel/drv/vboxms.conf
/usr/lib/VBoxOGL.so
/usr/lib/VBoxOGLarrayspu.so
/usr/lib/VBoxOGLcrutil.so
/usr/lib/VBoxOGLerrorspu.so
/usr/lib/VBoxOGLfeedbackspu.so
/usr/lib/VBoxOGLpackspu.so
/usr/lib/VBoxOGLpassthroughspu.so
/usr/lib/amd64/VBoxOGL.so
/usr/lib/amd64/VBoxOGLarrayspu.so
/usr/lib/amd64/VBoxOGLcrutil.so
/usr/lib/amd64/VBoxOGLerrorspu.so
/usr/lib/amd64/VBoxOGLfeedbackspu.so
/usr/lib/amd64/VBoxOGLpackspu.so
/usr/lib/amd64/VBoxOGLpassthroughspu.so
/usr/sbin/vboxmslnk <sUnattended SVr4 pkg installymbolic link>
[ verifying class <none> ]
/opt/VirtualBoxAdditions/VBoxClient <linked pathname>
/opt/VirtualBoxAdditions/VBoxISAExec <linked pathname>
/opt/VirtualBoxAdditions/VBoxService <linked pathname>
/opt/VirtualBoxAdditions/vboxmslnk <linked pathname>
[ verifying class <manifest> ]
## Executing postinstall script.
Uncompressing files...
Configuring VirtualBox guest kernel module...
VirtualBox guest kernel module loaded.
VirtualBox pointer integration module loaded.
Creating links...
Installing video driver for X.Org 1.14.5...
Configuring client...
Installing 64-bit shared folders module...
Installing 32-bit shared folders module...
Configuring services (this might take a while)...
Enabling services...
Updating boot archive...
Done.
Please re-login to activate the X11 guest additions.
If ... just un-installed the previous ... a REBOOT is required.

Installation of <SUNWvboxguest> was successful.


# eject
 
$ pkginfo -l SUNWvboxguest
   PKGINST:  SUNWvboxguest
      NAME:  Oracle VM VirtualBox Guest Additions
  CATEGORY:  application
      ARCH:  i386
   VERSION:  5.1.18,REV=r114002.2017.03.15.16.33
   BASEDIR:  /
    VENDOR:  Oracle Corporation
      DESC:  ... Guest Additions for Solaris guests
    PSTAMP:  vboxguest20170315163319_r114002
  INSTDATE:  May 08 2017 17:03
   HOTLINE:  Please contact your local service provider
     EMAIL:  info@virtualbox.org
    STATUS:  completely installed
     FILES:       80 installed pathnames
                   4 linked files
                   5 directories
                  21 executables
               37263 blocks used (approx)