Blog Viewer

Scripting How-To: Ensure proper ownership and permissions on file creation in SLAX

By Erdem posted 08-08-2015 05:35


Ensure Proper Ownership and Permissions on File Creation in SLAX


From time to time you might find a situation where your SLAX script needs to write data to a file for some later processing or review. For SLAX version 1.0 and higher, there are several options available for writing file output in SLAX. The preferred method is to use the <xsl:document> element, since it doesn't require defining any additional namespaces.  


IMPORTANT: While creating the files, <xsl:document> does not provide any ability for you to specify file ownership or permissions, so your files are created with ownership "nobody" and permissions of "644". Anyone can read the file, but only user "nobody" (or root) can modify or delete it.   


Suffice to say, littering your file system with files that can only be removed by user "root" is a bad practice. 


Fortunately, there is a workaround for this: 


Initially create your file using the <file-put> RPC (which will allow you to specify ownership and permissions), then subsequently overwrite that file with your "real" data using the <xsl:document> element.   Now you have a file that can modified or deleted by someone other than root.


Click the following for a more detailed run-down on this topic. 


A script was needed to do a fair amount of file create/update/read operations, so a simple convenience function was written to handle the initial housekeeping of setting proper ownership and permissions for those files. The function name is "touchfile" since it's analogous to the *nix touch(1) utility.


Here's the function:


01	/*
02	 * Create file with file-put rpc just before overwriting it.
03	 * This is a work-around for default file owner/permission issues
04	 * Inputs:
05	 *   $con: handle from previous jcs:open()
06	 *      $filename: full pathname for file.
07	 */
08	<func:function name="check:touchfile"> {
09	    param $con; 
10	    param $filename;
11	    var $put-rpc = {
12	        <file-put> {
13	            <filename> $filename;
14	            <permission> "666";
15	            <encoding> "ascii";
16	            <delete-if-exist> "yes";
17	            <file-contents> "TO BE OVERWRITTEN";
18	        }
19	    }
20	    var $res = jcs:execute($con,$put-rpc);
21	    <func:result select="$res">;
22	}


Once this function is written, any time you need to create a file, simply call this new "touchfile" function, then write to the file as needed, using (for example) <xsl:document>.


Below is a snippet (another function) that calls the "touchfile" function, then writes the real data to the file:


01	<func:function name="check:write-if-status"> {
02	    param $con;
03	    param $data;
04	    param $filename;
05	    expr jcs:output( "\tWriting interface precheck data to: ", $filename);
06	    var $res = check:touchfile($con,$filename);   
07	    var $wr = <exsl:document href=$filename method="xml" omit-xml-declaration="yes" standalone="yes" indent="yes"> {
08	        <precheck> {
09	            apply-templates $data/physical-interface { mode "strip"; };
10	            apply-templates $data/logical-interface { mode "strip"; };
11	        }
12	    }
13	    <func:result select="true()">;
14	}

A couple of notes:


  • The functions are declared in SLAX 1.0 format.  SLAX 1.1 function syntax is a bit more streamlined.  (SLAX 1.0 format is forward compatible to libslax 1.1 systems.) 
  • <exsl:document> was used instead of <xsl:document> to write the file.