/*
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
/*
* fbconf_xorg - Frame buffer configuration program for Xorg
*/
#include <libgen.h> /* basename() */
#include <stdio.h> /* fprintf(), printf(), putc() */
#include <stdlib.h> /* exit() */
#include <string.h> /* memcpy(), strcat(), strcpy() */
#include <unistd.h> /* geteuid(), getuid(), seteuid(), unlink() */
#include "xf86Parser.h" /* Public function, etc. declarations */
#include "Configint.h" /* Private definitions, xf86confcalloc() ... */
#include "configProcs.h" /* Private function, etc. declarations */
#include "sun_edid.h" /* EDID data parsing */
#include "fbc.h" /* Common fbconf_xorg(1M) definitions */
#include "fbc_xorg.h" /* Edit config file data representations */
#include "fbc_Device.h" /* Edit Device sections */
#include "fbc_Option.h" /* Edit Option lists */
#include "fbc_ask.h" /* User interaction */
#include "fbc_dev.h" /* Identify the graphics device (-dev opt) */
#include "fbc_edit_config.h" /* Write an updated config file */
#include "fbc_error.h" /* Error reporting */
#include "fbc_gamma_table.h" /* Read, pack, and write a gamma table */
#include "fbc_getargs.h" /* Program command line processing */
#include "fbc_get_properties.h" /* Get fbconf_xorg(1M) program properties */
#include "fbc_mode_list.h" /* List of Modes from the config file */
#include "fbc_open_device.h" /* Open the frame buffer device */
#include "fbc_propt.h" /* Display the current option settings */
#include "fbc_properties.h" /* fbconf_xorg(1M) program properties */
#include "fbc_res.h" /* Video modes/resolutions (-res option) */
#include "fbc_write_config.h" /* Write an updated config file */
/*
* fbc_check_args()
*
* Make sure all program command line argument strings are properly
* terminated within a reasonable number of characters. See Bug
* 4031253, reported for ffbconfig circa 10 Feb 1997.
*
* Command line option strings generally don't exceed 16 characters
* (e.g., "-deftransparent"). The longest argument strings would be
* pathnames (e.g. for -gfile). A string longer than MAXPATHLEN
* (typically 1024) characters would be expected to fail anyway for
* one reason or another.
*
* If this function segfaults despite all precautions, the caller has
* insured that it'll happen while the user is executing as himself.
*
* Note that the fbc_prog_name string used by fbc_errormsg() has been
* set at build time to something useable. The argv[0] string isn't
* trusted until everything checks out.
*/
static
void
const int argc, /* Program argument count */
char *const argv[]) /* Program argument vector */
{
/*
* Make sure something exists resembling an argument vector
*/
fbc_errormsg("Program argument vector is missing\n");
}
/*
* Make sure all argument strings are properly Nul-terminated, etc.
*/
}
len = 0;
if (len >= MAX_ARG_LEN) {
"Program argument %d is unacceptably long\n",
arg);
}
len += 1;
}
}
/*
* Make sure the argument vector is NULL-terminated
*/
fbc_errormsg("Program argument vector is not terminated\n");
}
} /* fbc_check_args() */
/*
* main()
*
* Main function for the fbconf_xorg(1M) frame buffer configuration
* program for Xorg.
*/
int
main(
const int argc, /* Program argument count */
char *const argv[]) /* Program argument vector */
{
/*
* For security, neutralize the EUID except when accessing system files
*/
fbc_errormsg("Unable to change effective user ID\n");
return (FBC_EXIT_FAILURE);
}
}
/*
* Safely validate all command line argument strings
*
* This is an suid program. Bug 4031253 involves a buffer
* overflow attack that uses an exec(2) call to pass a
* non-string argument to ffbconfig, which is invoked with
* superpowers.
*/
/*
* Zero all of the fbconf_xorg(1M) parameters
*/
/*
* Get the program name for diagnostic messages
*/
/*
* Use generic fbconf_xorg properties until the actual device is known
*
* This enables minimal usage text display, sets basic
* defaults, etc.
*/
/*
* Determine the device pathname (-dev argument) and open it
*
* The device pathname (explicitly named or resolved from the
* * Specifies which device file to open, which in turn
* yeilds the VISUAL identifier string (e.g. "SUNWkfb"):
* * Helps to confirm the device's validity
* * Determines which device-specific library to
* dynamically open and use (e.g. libSUNWkfb_conf.so)
* * Helps to match master and slave devices
* * Specifies which Device section to find (or create) in
* the configuration file
* * Gives the name for the Device section's Driver entry
* (e.g. "kfb")
* * Contains a unit number (which may have a future use)
* * May may include a stream letter (e.g. "a" or "b")
*/
if (device_arg == NULL) {
/*
* Determine the default device, which includes opening it
*/
sizeof (device_path_buf),
sizeof (device_type_buf),
&device) != FBC_SUCCESS) {
fbc_errormsg("Unable to open default device\n");
return (FBC_EXIT_FAILURE);
}
} else {
/*
* Parse the -dev device name argument
*/
device_path_buf, sizeof (device_path_buf),
device_type_buf, sizeof (device_type_buf),
&device) != FBC_SUCCESS) {
return (FBC_EXIT_USAGE);
}
/*
* Open the -dev device and get the VISUAL env identifier name
*
* The VISUAL environment identifier, rather than the
* device name, determines which libSUNWxxx_conf.so
* library is needed with this frame buffer device.
* The device name still should agree with the
* identifier name (e.g."kfb0" w/ "SUNWkfb").
*/
/* Error message has been displayed, so just exit */
return (FBC_EXIT_FAILURE);
}
}
/*
* Initialize the default state for the -file command line option
*
* The configuration file location is not likely to be device
* dependent, but it could be changed via the call to
* fbc_get_properties() below.
*/
/*
* Establish device-specific properties and fbconf_xorg(1M) behavior
*/
return (FBC_EXIT_FAILURE); /* Unknown device type, etc. */
}
/*
* Communicate gamma table pathname info with the -gfile option handler
*/
/*
* No dynamically allocated gamma table packed data strings yet
*/
/*
* Evaluate the program command line
*
* The fbc_get_properties() code path above is able to
* provide a wrapper for fbc_getargs() or to replace it
* altogether, should that be necessary.
*/
/*
* If the program command line is a no-op, display usage and terminate
*
* The command line is a no-op if none of these operations
* has been requested:
* * Display help text (-help)
* * Display the frame buffer device configuration (-prconf)
* * Display EDID data from the display device (-predid)
* * Display the software configuration (-propt)
* * Display a video modes/resolutions list (-res ?)
* * Modify one or more entries in the configuration file
*
* -file is specified.
*/
return (FBC_EXIT_SUCCESS);
}
/*
* If -help was specified, display device-specific program help text
*
* terminate immediately upon satisfying those request(s).
*/
return (FBC_EXIT_SUCCESS);
}
}
/*
* Restore the effective UID while reading the config file
*/
}
/*
* Search for and open the input configuration file
*/
NULL);
if (config_file_path != NULL) {
/*
* Save the pathname of the opened input config file
*/
/*
* Read the input configuration file
*/
fbc_errormsg("Error in configuration file\n");
return (FBC_EXIT_FAILURE);
}
}
/*
* Neutralize the EUID again
*/
fbc_errormsg("Unable to change effective user ID\n");
return (FBC_EXIT_FAILURE);
}
}
/*
* If no config file, allocate and zero the config IR structure
*/
if (config_file_path == NULL) {
{
fbc_errormsg("Insufficient memory\n");
return (FBC_EXIT_FAILURE);
}
}
/*
*
* Sections that are required by Xorg or that are referenced
* based on the command line will be created if they are not
* found. The -res option is an implied reference to the
* Monitor section or the Modes sections it may reference.
*/
}
!= 0) {
return (FBC_EXIT_FAILURE);
}
/*
* If -res ? was specified, display the video mode names and terminate
*/
return (FBC_EXIT_SUCCESS);
}
/*
* If -res <video_mode> was specified, validate & canonicalize the mode
*
* The video mode name is passed to and from the function via
* the fbvar.xf86_entry_mods.video_mode structure. The
* mode_name_buf buffer may be needed for canonicalization.
*/
&device,
&fbvar,
sizeof (mode_name_buf),
return (FBC_EXIT_USAGE); /* Invalid video mode name */
}
}
/*
* See if there's any work to do involving a gamma file (-gfile)
*/
/*
* Construct the output gamma table pathname for this device
*
* This must be done after xf86openConfigFile() is
* called, so the config file pathname will be known,
* and before the call to fbc_edit_active_sections(),
* which might use this gamma table pathname as the
* "GFile" Option entry value.
*/
sizeof (gfile_out_path))
!= FBC_SUCCESS) {
return (FBC_EXIT_FAILURE);
}
/*
* See if we'll be removing an old file or creating a new one
*/
/*
* Read and pack the gamma correction table
*/
!= 0) {
return (FBC_EXIT_FAILURE);
}
/*
* Fix the modification descriptor for the "GFile" Opt
*
* See commentary in fbc_Option_GFile().
*/
}
}
}
/*
* See whether we're modifying the configuration
*/
/*
* Edit the in-memory copy of the config sections
*/
(void) fbc_edit_active_sections(
/*
* Apply any constraints on the results (e.g., memory limits)
*/
return (FBC_EXIT_FAILURE);
}
}
/*
* Do any device initialization
*/
!= FBC_SUCCESS) {
return (FBC_EXIT_FAILURE);
}
}
/*
* If "-res try", give the new video mode a 10-second trial
*
* The "try" keyword should not have been recognized
* if there is no res_mode_try() function. Treat
* such an anomoly as an unsuccessful trial (drawing
* attention to the need to fix the code in
* SUNWxxx_get_properties(), etc.).
*/
"Unsuccessful video mode trial. No changes made!\n");
return (FBC_EXIT_FAILURE);
}
printf("Video resolution will be set to \"%s\"\n",
}
}
/*
* Identify the active video Mode, if any
*
* This is done for the benefit of the -propt display code.
* It must be done after the -res <video-mode> has been
* executed.
*/
/*
* If -prconf was specified, display current hardware configuration
*/
printf("\n--- Hardware Configuration for %s ---\n\n",
}
/*
* If -predid was specified, display the EDID data
*/
}
/*
* If -propt was specified, display the current config option settings
*
* This should be executed after any modifications to the in-
* memory configuration are made.
*/
printf("\n--- Graphics Configuration for %s ---\n",
}
/*
* Write the updated config and any gamma file, and close everything
*/
/*
* Announce config file creation if no input file was found
*/
if (config_file_path == NULL) {
printf("New configuration file, %s\n",
}
/*
* Set the file mode creation mask to limit modes to 644
*/
(void) umask(022);
/*
* Restore the effective UID while writing config & gamma files
*/
}
/*
* Write the updated config file and close down config stuff
*/
fbc_errormsg("Unable to update config file, %s\n",
}
/*
* If -gfile was specified, update the gamma correction table
*/
if ((exit_code == FBC_EXIT_SUCCESS) &&
/*
* Delete any now obsolete gamma table file
*/
} else {
/*
* Create the new packed gamma table file
*/
!= FBC_SUCCESS) {
}
}
}
/*
* Neutralize the effective UID again
*/
"Unable to change effective user ID\n");
return (FBC_EXIT_FAILURE);
}
}
} else {
/*
* Close down the unmodified config file(s) and IR & ER memory
*/
}
/*
* If "-res now" was specified, set the new video mode now
*/
!= FBC_SUCCESS)) {
fbc_errormsg("Unable to set new video mode now\n");
} else {
printf("Video mode has been set to \"%s\"\n",
}
}
/*
* Release the config file pathname
*/
xf86conffree((char *)config_file_path);
/*
* Release any packed gamma correction value strings
*/
/*
* Terminate ourselves, indicating the state of things
*/
return (exit_code);
} /* main() */
/* End of fbconf_xorg.c */