Now you know what can you find in every source file in your YaST module. This part will show you how to clean them up by removing functions and files unneeded for our module and a basic behavior and UI for SSHD Configuration will be set up.
This part will summarize functions and files removed from our YaST module created using the y2tool helper.
You can download the changed source files here or you can download them one by one later in this section.
The file Sshd2.pm
has been completely removed
from the project and also the appropriate record in the
Makefile.am
file should be changed to reflect on
that change because installing files using the broken
Makefile.am
would lead into erroneous
result.
Original version:
module_DATA = \ Sshd.ycp \ Sshd2.pm
New version:
module_DATA = \ Sshd.ycp
![]() | Note |
---|---|
This configuration module will provide the basic functional interface with no global variables. The main reason for a functional interface is that you can simply control your configuration data flow. Global variables are more vulnerable to corruption by other modules. |
You had better download the changed file
Sshd.ycp
here
Here you can see the list of changes in the original file:
Cleaning the source code from unneeded functions:
Remove Modified()
function (both definitions
global boolean Modified...
).
Remove AbortFunction()
function.
Remove Abort()
function.
Remove Export()
function.
Remove Summary()
function.
Remove Overview()
function.
Remove AutoPackages()
function.
Remove Import()
function.
New and modified functionality:
Remove the global
keyword from all definitions
of variables to make them local-only because we don't want anybody to
change our data internally but using the functions.
Original:
global boolean modified = false;
Changed:
boolean modified = false;
Add this
import "Service"; import "Popup";
under other imports in the module. We are using these modules later in the module.
Add new variable definition
integer sl = 1000;
after the boolean modified...
definition. This variable is used for length definition of short
sleeps between read and write progress steps.
Add new GetModified()
function just after the
integer sl = 1000;
definition:
/** * Returns whether the configuration has been modified. */ global boolean GetModified() { return modified; }
Add new SetModified()
function after the
GetModified()
one:
/** * Sets that the configuration has been modified. */ global void SetModified() { modified = true; }
Modify Abort()
function:
/** * Returns a confirmation popup dialog whether user wants to really abort. */ global boolean Abort() { return Popup::ReallyAbort(GetModified()); }
Add new PollAbort()
function after the
Abort()
function:
/** * Checks whether an Abort button has been pressed. * If so, calls function to confirm the abort call. * * @return boolean true if abort confirmed */ global boolean PollAbort() { if (UI::PollInput() == `abort) return Abort(); return false; }
Modify Read()
function:
Two useless progress steps were removed. Some texts were
changed, e.g., Sshd
to
SSHD
.
/** * Read all SSHD settings * @return true on success */ global boolean Read() { /* SSHD read dialog caption */ string caption = _("Initializing SSHD Configuration"); integer steps = 2; Progress::New( caption, " ", steps, [ /* Progress stage 1/2 */ _("Read current SSHD configuration"), /* Progress stage 2/2 */ _("Read current SSHD state") ], [ /* Progress step 1/2 */ _("Reading current SSHD configuration..."), /* Progress step 2/2 */ _("Reading current SSHD state..."), /* Progress finished */ Message::Finished() ], "" ); sleep(sl); if(PollAbort()) return false; Progress::NextStage(); /* Error message */ if(false) Report::Error(Message::CannotReadCurrentSettings()); sleep(sl); if(PollAbort()) return false; Progress::NextStep(); /* Error message */ if(false) Report::Error(_("Cannot read current SSHD state.")); sleep(sl); if(PollAbort()) return false; Progress::NextStage (); sleep(sl); modified = false; return true; }
Modify Write()
function:
Some texts were changed, e.g., Sshd
to
SSHD
.
Message::SuSEConfigFailed()
is replaced with
Message::CannotAdjustService("sshd")
.
/** * Write all SSHD settings * @return true on success */ global boolean Write() { /* SSHD read dialog caption */ string caption = _("Saving SSHD Configuration"); integer steps = 2; Progress::New(caption, " ", steps, [ /* Progress stage 1/2 */ _("Write the SSHD settings"), /* Progress stage 2/2 */ _("Adjust the SSHD service") ], [ /* Progress step 1/2 */ _("Writing the SSHD settings..."), /* Progress step 2/2 */ _("Adjusting the SSHD service..."), Message::Finished() ], "" ); sleep(sl); if(PollAbort()) return false; Progress::NextStage(); /* Error message */ if(false) Report::Error (_("Cannot write SSHD settings.")); sleep(sl); if(PollAbort()) return false; Progress::NextStage (); /* Error message */ if(false) Report::Error (Message::CannotAdjustService("sshd")); sleep(sl); Progress::NextStage (); sleep(sl); return true; }
You had better download the changed file
complex.ycp
here
Here is the list of changes in the file:
Removed unneeded functions:
Remove Modified()
function.
Remove ReallyAbort()
function.
Remove PollAbort()
function.
Remove SummaryDialog()
function.
Remove OverviewDialog()
function.
You had better download the changed file
dialogs.ycp
here
Here is the list of changes in the file:
Removed unneeded functions:
Remove Configure1Dialog()
function.
Remove Configure2Dialog()
function.
Added new functions:
Add new ServerConfigurationDialog()
function.
This function creates a dialog using the Wizard module
and then handles the user input in the endless loop. After
the Abort
or Next
button
is pressed, handler skips outside the loop and returns the
ID of the pressed button as the function
result.
/** * Server Configuration Dialog * * @return any dialog result */ any ServerConfigurationDialog() { /* a dialog caption */ string caption = _("SSHD Server Configuration"); term contents = `VBox ( `Left(`Label(_("SSHD TCP Ports"))), `Left( `VBox ( `MinSize( 40, 5, /* A table header */ `Table(`id("Port"), `header("Port"), []) ), `HBox ( /* a push button */ `PushButton(`id("add_port"), _("&Add...")), /* a push button */ `PushButton(`id("edit_port"), _("&Edit...")), /* a push button */ `PushButton(`id("delete_port"), _("&Delete")) ), `VSpacing(1), `Frame ( /* a dialog frame caption */ _("Server Features"), `VBox ( /* a check box */ `Left(`CheckBox(`id("AllowTcpForwarding"), _("Allow &TCP Forwarding"))), /* a check box */ `Left(`CheckBox(`id("X11Forwarding"), _("Allow &X11 Forwarding"))), /* a check box */ `Left(`CheckBox(`id("Compression"), _("Allow &Compression"))) ) ), `VStretch() ) ) ); Wizard::SetContentsButtons(caption, contents, HELPS["server_configuration"]:"", Label::BackButton(), Label::NextButton()); Wizard::DisableBackButton(); any ret = nil; while(true) { ret = UI::UserInput(); /* abort? */ if(ret == `abort) { if(Sshd::Abort()) break; else continue; /* next */ } else if(ret == `next) { break; /* unknown */ } else { y2error("unexpected retcode: %1", ret); continue; } } Wizard::RestoreBackButton(); return ret; }
This dialog defines the the table of TCP Ports connected with Add..., Edit... and Delete buttons. Add... and Edit... button labels are followed by dots because pressing these buttons would open a new small pop-up dialog on the top of the current one. Server Features options are surrounded by a `Frame widget.
Add new LoginSettingsDialog()
function.
This function creates a dialog using the Wizard module
and then handles the user input in the endless loop. After
the Abort
, Next
or
Back
button is pressed, handler skips outside
the loop and returns the ID of the pressed
button as the function result.
/** * Login Settings Dialog * * @return any dialog result */ any LoginSettingsDialog() { /* a dialog caption */ string caption = _("SSHD Server Login Settings"); term contents = `VBox( `Frame ( _("General Login Settings"), `VBox ( /* A check box */ `Left(`CheckBox(`id("PrintMotd"), _("Print &Message of the Day After Login"))), /* A check box */ `Left(`CheckBox(`id("PermitRootLogin"), _("Permi&t Root Login"))) ) ), `VSpacing(1), `Frame ( _("Authentication Settings"), `VBox ( /* A text entry */ `Left(`TextEntry(`id("MaxAuthTries"), _("Ma&ximum Authentication Tries"))), /* A check box */ `Left(`CheckBox (`id("PasswordAuthentication"), _("Pa&sswordAuthentication"))), /* A check box */ `Left(`CheckBox (`id("RSAAuthentication"), _("RSA Authenti&cation"))), /* A check box */ `Left(`CheckBox (`id("PubkeyAuthentication"), _("Public &Key Authentication"))) ) ), `VStretch() ); Wizard::SetContentsButtons(caption, contents, HELPS["login_settings"]:"", Label::BackButton(), Label::NextButton()); Wizard::SetNextButton(`next, Label::AcceptButton()); any ret = nil; while(true) { ret = UI::UserInput(); /* abort? */ if(ret == `abort) { if(Sshd::Abort()) break; else continue; /* next */ } else if(ret == `next) { break; } else if(ret == `back) { break; /* unknown */ } else { y2error("unexpected retcode: %1", ret); continue; } } Wizard::RestoreNextButton(); return ret; }
This simple dialog contains two frames of General Login Settings and Authentication Settings with check boxes.
You had better download the changed file
helps.ycp
here
Here is the list of changes in the file:
Remove helps for summary
,
overview
, c1
and
c2
.
Add new helps for server_configuration
and login_settings
/* Server Configuration dialog help */ "server_configuration" : _("<p><b><big>Server Configuration</big></b><br> Configure SSHD here.<br></p>"), /* Login Settings dialog help */ "login_settings" : _("<p><b><big>Login Settings</big></b><br> Configure SSHD login settings here.<br></p>"),
![]() | Note |
---|---|
Structure of helps is: map HELPS = $[ // TRANSLATORS: Comment for translators (this is a help text for...) "help_for" : _("Help text marked for translation..."), ]; |
You had better download the changed file
sshd.ycp
here
Here is the list of changes in the file:
Remove a command line definition.
Remove installation proposal support.
This client still runs the workflow via
CommandLine
module with an empty command line
definition just to inform that the command line interface is not
available for this module if anyone tries to run it.
This file has been completely removed from
the package and also the appropriate record in the
Makefile.am
file.
This file has been completely removed from
the package and also the appropriate record in the
Makefile.am
file.
Makefile.am
file should be changed this way.
Original version:
client_DATA = \ sshd.ycp \ sshd_auto.ycp \ sshd_proposal.ycp
New version:
client_DATA = \ sshd.ycp
You had better download the changed file
wizards.ycp
here
Here is the list of changes in the file:
Remove AddSequence()
function.
Remove AutoSequence()
function.
Testsuites were designed for checking the global functionality, such as functions of modules, to keep them consistent. They can also help to find out when something else, used by your module, is suddenly changed.
In this tutorial, all testsuites
testsuite/tests/Sshd.*
have been completely
removed. Creating and running testsuites will be later described in
another tutorial.
We have worked hard to get this project where it is and now we would like to enjoy the current status by running the application.
# Enter the basic directory of the project cd sshd # We have changed some Makefiles make -f Makefile.cvs # Check the syntax and compile YCP modules make # Install the project files to the system sudo make install # Run the application in Qt sudo /sbin/yast2 sshd # ... or run the application in ncurses sudo /sbin/yast sshd
Now we can check it out. Dialogs are still not connected with the data, there are no pre-filled values and you still can't save the changed configuration, in spite of these facts, it is still a great success ;)!
See the current status of your module:
![]() | Important |
---|---|
After that, anytime you want to check the current status of changed source code, just run these commands: # Enter the directory with changed files cd sshd/src/ # Compile and install files into the system sudo make install # Run the application sudo /sbin/yast2 sshd |