PeopleSoft Corner

CB Login

Recommended Products

I use and recommend the following products:

UltraEdit

UltraCompare

BeyondCompare

SQL Developer

del.icio.us addon for Firefox

 

Browse the App Server Filesystem via iScript Print
Tuesday, 02 January 2007
Debugging that SQL-intensive page is easier when you can get to your trace files quickly. And sometimes it’s easier to look in the Process Scheduler config file to see where it’s pulling SQR’s from than to ask your over-worked DBA. But the reality is that you don’t always have access to the servers filesystems to pull this valuable information. Well no worries, here’s a technique to browse your Application Server’s filesystem using nothing but a little PeopleCode.

It’s actually pretty easy to write a set of PeopleCode functions to display a directory structure and view a file. The functions you’ll need are all well documented in PeopleBooks, with sample code and everything. If you combine them into an iScript with a few parameters on the query line, you can create a nice application server browsing utility.

Here’s a screen shot:
Browse Files Screenshot

It works pretty much like you’d expect. By default it will start in the LOGS directory ($PS_HOME/appserv/<domain>/LOGS). Clicking “..” takes you up one directory, clicking on a directory takes you into that directory, and clicking a file attempts to display it in the browser window. It doesn’t do any checking for file content before it sends it to your browser, so be careful what file you click on!
Here’s the code that I used:

/******** This iScript lists and views files in a directory ********/
Function IScript_ListDirectory()
 
&Domain = "PS89FNSB";
%Response.WriteLine("<p align=""center""><b>" | "Directory Listing" | "</b></p>");
&PS_HOME = GetEnv("PS_HOME");
 
Local string &pwd;
&pwd = %Request.GetParameter("curdir");
If None(&pwd) Then
&pwd = &PS_HOME | "/appserv/" | &Domain;
End-If;
 
If Right(&pwd, 2) = ".." Then
&pwd = Left(&pwd, Len(&pwd) - 3);
For &i = Len(&pwd) To 1 Step - 1
If Right(&pwd, 1) <> "/" Then
&pwd = Left(&pwd, Len(&pwd) - 1);
Else
&pwd = Left(&pwd, Len(&pwd) - 1);
&i = 0;
End-If;
End-For;
%Response.RedirectURL(EncodeURL(%Request.ContentURI | "/EMPLOYEE/EMPL/s/WEBLIB_BM_XX.USER1.FieldFormula.IScript_ListDirectory?&disconnect=y&type=public&curdir=" | &pwd));
End-If;
 
Local array of string &FNAMES;
Local File &MYFILE;
Local string &CurrFile;
 
&FNAMES = FindFiles(&pwd | "/*", %FilePath_Absolute);
If &FNAMES.Len = 0 Then /* No files in this directory - this must be a file instead */
%Response.RedirectURL(EncodeURL(%Request.ContentURI | "/EMPLOYEE/EMPL/s/WEBLIB_BM_XX.USER1.FieldFormula.IScript_ViewFile?&disconnect=y&type=public&Filename=" | &pwd));
Else
%Response.WriteLine("Directory: " | &pwd | "<br><br>");
While &FNAMES.Len > 0
&CurrFile = &FNAMES.Shift();
rem &FileURL = %Request.ContentURI | "/EMPLOYEE/EMPL/s/WEBLIB_BM_XX.USER1.FieldFormula.IScript_ViewFile?&disconnect=y&type=public&Filename=" | &CurrFile;
&FileURL = %Request.ContentURI | "/EMPLOYEE/EMPL/s/WEBLIB_BM_XX.USER1.FieldFormula.IScript_ListDirectory?&disconnect=y&type=public&curdir=" | &CurrFile;
%Response.WriteLine("<a href=""" | &FileURL | """> " | Substring(&CurrFile, Len(&pwd) + 2, Len(&CurrFile) - Len(&pwd) + 2) | "</a></br>");
End-While;
End-If;
End-Function;
 
Function IScript_ViewFile()
&Filename = %Request.GetParameter("FILENAME");
 
Local File &ServerFile;
Local string &ln, &RelativePath;
 
%Response.Write("<p align=""center""><b>" | &Filename | "</b></p>");
 
 
/* Note: To restrict access to a particular directory or subdirectory, set the environment
variable PS_FILEDIR on your application server to point to that directory. Otherwise
the user will be restricted to the PS_SERVDIR environment variable.
 
To disable security altogether, comment out the relitive path logic and replace %FilePath_Relative in the GetFile method to %FilePath_Absolute
*/
 
rem Get the relative path name;
 
If GetEnv("PS_FILEDIR") <> "" Then
&RelativePath = GetEnv("PS_FILEDIR");
Else
&RelativePath = GetEnv("PS_SERVDIR") | "/files";
End-If;
 
If Left(&Filename, Len(&RelativePath)) = &RelativePath Then
&Filename = Right(&Filename, Len(&Filename) - Len(&RelativePath));
End-If;
 
 
rem Open the file;
&ServerFile = GetFile(&Filename, "R", "A", %FilePath_Relative);
%Response.Write("<p>");
While &ServerFile.ReadLine(&ln);
%Response.WriteLine(&ln | "<br>");
End-While;
%Response.WriteLine("</p>");
&ServerFile.Close();
 
End-Function;

There are two basic functions: IScript_ListDirectory() and IScript_ViewFile.

The ListDirectory function first sets some basic values. You’ll want to change the “DOMAIN” value to be your application server domain, so that it will be able to change to the default directory correctly. (You can get the domain from a CTRL-J in your browser). Then it takes the directory passed in the “curdir” query parameter (or the default directory) and sends them to the browser as a hyperlink back to this same ListDirectory function. If for some reason the first entry isn’t a “.”, this isn’t a directory so it must be a file and it redirects you to the ViewFile iScript with the filename passed as a query parameter.

The ViewFile function uses the GetFile function to open the file passed on the URL in the Filename query parameter. It uses the %FilePath_Relative option to keep users from opening files above the directory you specify in the PS_FILEDIR or PS_SERVDIR environment variables to keep things somewhat secure. If security isn't an issue in your environment, you can follow the instructions in the comment to disable security.

Once the file is open, the function reads it one line at a time and sends it to your browser, adding a <br> tag at the end of each line.

Security Warning

This code opens up some security issues. While you can restrict users to a top-level directory for viewing the contents of files, users can browse the directory structure of the entire system with the authority of the Application Server user ID.

As a result, use some common sense before deploying this code. Make sure your systems administrator and management approves. Be sure that your app server user doesn't have access to view directories that you don't want them to view. Use the PS_FILEDIR environment variable to lock users down to a specific directory.

Making it work
Here’s how to put the code into a web library, set security, and hit it with a URL:

  1. First, create a new derived work record that starts with WEBLIB, like WEBLIB_XX.

  2. Insert a new field into the record. ISCRIPT1 works.

  3. On the FieldFormula PeopleCode, insert the code from earlier in this post.

  4. Now go on-line and pull up your favorite permission list that is in your profile. Go to the Web Libraries tab and insert a row. Pick the WEBLIB created in step 1, click Edit, and click the Full Access All button. Then click OK and Save.

  5. Now you can access the iScript with this URL (Just replace the bold parts with values that make sense in your environment):
    http://<server>.<domain>:<port>/psc/<website>/EMPLOYEE/EMPL/s/WEBLIB_XX.ISCRIPT1.FieldFormula.IScript_ListDirectory? disconnect=y&type=public&curdir=/usr/local/psoft/FDMO89/appserv/FDMO89/LOGS

  6. The first time you click on the URL, it may ask you for a PS username/pwd. Go ahead and log on. It may tell you you’re not authorized. Just paste the same URL in your browser again and it should show you the directory listing.

Comments (4)add feed
... : Brent Martin
There's been some discussion about this on the Yahoo PeopleSoft Fans user group (http://groups.yahoo.com/group/peoplesoft-fans). Bruce found that I should have used EncodeURL on my redirects which I've corrected in this post. He also left this comment which has a couple of good points you'll want to consider:

Hi Brent,

A couple of other things I did, taking your security warning to heart, included removing the ability to navigate out of the LOG directory and only showing files with LOG in the name in the file list.


I also added a portal navigation for this iscript rather than pasting in the URL. I passed in the parameter for curdir, under the iscript parameters, which in our case is /PT846/appserv/HC89/LOGS/. I had to use the Unix style slash for this since the Windows style, , wasn't recognized and the navigation failed as it saw curdir=PT846appservHC89LOGS. It took a while to figure that one out.

regards,
Bruce

January 11, 2007
Binary files : Joe : http://xtrahot.chili-mango.net
Is there a way to transfer binary files from the app server to the web browser? By using %Response.WriteBinary() and providing the correct content-type, I could use a separate iScript for serving binary data from tables (images or attachment records). The problem is, there seems to be no way to read binary from files to be used by PeopleCode, specifically as an argument to %Response.WriteBinary(). Is there?

The only option that I know that work is to use attachment functions to copy the desire file to an attachment repository and use attachment functions to serve the file to the browser. However, I'm wondering whether there are better option than this.

This is just something I've been pondering for some time, not exactly related to this blog post. I know it is probably unwise in technique you've presented to include binary files.
January 30, 2007
How To Browse *Local* Files? : David
Thanks very much for posting this script. We have a somewhat different issue.

We are using PS HCM 8.90.060 with Peopletools 8.46.17.

We don't want to return a list of files residing on the AppServer. We want to raise a Windows file browser dialog box that allows the user to browse and pick a file from local directories.

Presumably this involves some kind of Windows API function call. When the user picks the file, the filepath and filename would be returned to an edit box and a derived record field for further processing.

I'd love to be able to parse through the built-in AddAttachment function, but evidently that's proprietary. Has anyone ever seen a way to do what I'm describing?
January 27, 2008
... : Brent Martin
I'm not 100% sure how you can accomplish this, but maybe I can point you in the right direction. It seems like a standard HTML input tag will give you a input box with a browse button next to it:

input type='file' name='myFileName' size='50'

This will let a user browse for a file. You can embed that in an HTML document in your page.

Create an OK button where the onClick event calls a Javascript program (also embedded on your page in an HTML object) that reads the filename value and stores it in your derived work record input field which is added to the page and hidden.

I'm pretty sure that would work. Best of luck!

P.S. I also posted this question & answer on the PS Corner forum because it might be easier for other people to find it there. http://www.erpassociates.com/component/option,com_fireboard/Itemid,32/func,showcat/catid,2/


January 28, 2008
Write comment
quote
bold
italicize
underline
strike
url
image
quote
quote
Smiley
Smiley
Smiley
Smiley
Smiley
Smiley
Smiley
Smiley
Smiley
Smiley
Smiley
Smiley


Write the displayed characters


busy
Last Updated ( Saturday, 13 January 2007 )
 
< Prev   Next >