HOME   SEARCH

wsuit3.gif (2407 bytes)

DCE C Library Documentation

Public UNIX Systems
UNIX Software
UNIX Help
Web Tools
Client Server

IT Homepage


This document is not intended to be an explanation on how to write C language cgi scripts. It is only meant to list the available functions in the WSU implementation of the C library of cgi related functions. I won't even be describing typical C functions. I'll leave it to you to find that documentation. This library was written to be compatible with gcc so it can be moved easily to multiple platforms.

Table of Contents

Simple Test Program
test_pgm.h
test_pgm.c
Alphabetical List of Functions
Alphabetical List of Macros and Variables
Valid Probe Types
Sample Makefile
Registering a new DCE service

 

Simple Program

About the simplest possible cgi C program that will contact MVS would consist of the following *.h and *.c files. The *.h file would contain include information that gets included into the *.c file. The include file you create must be of the format "probename_c.h". The "probename_c.h" file is required. Even if empty, you still must have a "probename_c.h" file. When you register the serice, you will have a "probename.h" include file created for you. Do not modify the "probename.h" file at all.

We'll call these test_pgm_c.h and test_pgm.c in this document. You can view test_pgm_c.h and test_pgm.c below.

You can view the usage of the various functions in the alphabetical list of functions. If you want to change some of the default variables that are set, you can go to the alphabetical list of macros and variables.

test_pgm_c.h

/*

test_pgm_c.h
These are extra defs needed specifically for test_pgm.c
Created: (drg) 6/10/97
Modified:
9/19/97: (drg) fixed initialization

*/

#define PROBE_NAME "test_pgm"
#define PROBE_TYPE SIC
#define BACKGROUND "/AIS/ATMS/graphics/simpgray.gif"

#ifdef PROD
# define PRODUCTION TRUE
#else
# define PRODUCTION FALSE
#endif

/* Miscellaneous macros */

#if PRODUCTION == TRUE
# define RETURN_LINK "https://www.it.wsu.edu/AIS/SIC/sicintro.htm"
#else
# define RETURN_LINK "https://www.develop.it.wsu.edu/AIS/SIC/sicintro.htm"
#endif

#define RETURN_LABEL "Student Information Center Menu"
#define WEB_CENTER "Student Information Center"

char* logout_link;

The "PROBE_NAME" should be the name of the C program. You can override this with something else, but it is not advisable.

 

The "PROBE_TYPE" macro must be one of the valid probe types. You can check below for the valid Probe Types.

If you have a particular background you want to be used on all pages of this probe, you can set it with the "BACKGROUND" macro.

The Makefile used to compile the probe is setup to run with the "PROD" parameter on or off, depending on whether you specified "dev" or "prod" when you called the Makefile. If PROD has been set, the the "PRODUCTION" macro is set to TRUE. Otherwise it is FALSE. The PRODUCTION macro is used to set things such as the return host address, etc. You can view a Sample Makefile at the end of this document.

Depending on whether PRODUCTION is true or false, the value of RETURN_LINK is established to return to one server or another.

RETURN_LABEL is set to be the same irregardless of whether you are in production or development. RETURN_LABEL could be put in the previous #if for RETURN_LINK and set differently depending on whether the production or development system is being used.

The WEB_CENTER macro is used in different titles. It can be set here along with the other values.

The last line for "logout_link" is necessary to setup that particular global variable.

You must put an include statement near the top of your C program. The include for "probename.h" is created for you automatically. Never modify the "probename.h" file. The "probename.h" file assumes that you have a "probename_c.h" file in your directory. If you aren't going to have an include of your own, you still must create an empty "probename_c.h" file.

At the top of your C program, you must have one line that indicates that this is your main routine. This is the MAIN_CLIENT_CODE statement as listed below.

test_pgm.c

/* 

	test_pgm.c

	test probe.
 
	Created: 5/30/97 (drg)
	Modified:
		10/22/97 (drg) modified to print correctly

*/


/* 
	the test_pgm.h include must be loaded before WSU_lib.h
*/

#define MAIN_CLIENT_CODE
#include "test_pgm.h"

#include "WSU_lib.h"
#include "WSU_probe.h"


/* Function prototypes (if any) */

void printterms(char**,int);
void print_summary(char**);



/* Main routine for probe */
void main()
{
/*		These variable names are not important and can be changed from 
		program to program. 	*/
		
  	char* this_state;
  	int   i;

  	INIT_Probe_Vars();
  	
/*	   These are not needed, but can be uncommented for debugging purposes
	   If you use these, change the IP numbers to reflect your own client IP name
	   and number
	   
putenv("QUERY_STRING=USER=rford&PW=password&state=phase2&Session=Spring 1997");
putenv("HTTP_COOKIE=KEY=ticket4sam; path=/; kinit=done; path=/;");
putenv("REMOTE_ADDR=134.121.111.111");
putenv("REMOTE_HOST=134.121.111.111");
putenv("HTTP_USER_AGENT=Mozilla/2.0");
*/
  	INIT_Probe();

	logout_link = (char*)malloc(100);
	bzero(logout_link,sizeof(logout_link));
  	sprintf(logout_link,"https://%s/AIS/html/logout.htm",this_server);

	this_state = (char*)malloc(50);
	bzero(this_state,sizeof(this_state));
	
/*		If the state has not yet ben set, set it to "phase1"   */
  	if (!FormValue("state")) {
		strncpy(this_state,"phase1",6);
  	} else {
		this_state=(char*)FormValue("state"); 
  	}

  	if (strncmp(this_state,"phase1",6) == 0) {
		sumsel();
  	} else if (strncmp(this_state,"phase2",6) == 0) {
		sumrpt();
	} else {
	   HTML_Error("Problem with posted value",99,"There is a
		problem with the phase value. It must always be set 
		and for some reason this time it isn't.");
	}

	
	return;

} /* end main() */

/* 	sumsel lets them select which reporting period they want to query */

void sumsel() {
	HBAG bag;
	char **parmlist;
	int  number_of_parms;

/*		"ADAB1234" is the Adabas glue/action routine name as it is known on MVS */
	bag = (HBAG)InitBag("ADAB1234");
/*		fill the  bag with the student's wsu number which was set in INIT_Probe */
	FillStrings(bag,1,wsu_number_string);
/*		this statement sends the filled "bag" to MVS and returns the 
                        buffer into the parmlist array with number_of_parms
		elements in the array. If any error occured on the 
		MVS side, then we go to the error routine at this point */
	parmlist = (char**)CallServer(bag, &number_of_parms);

/*		since everything is ok, print out all of the terms returned from MVS */
	print_header("Financial Aid - Select Award Period");
        print_WSU_identity();  
        printterms(parmlist, number_of_parms);
 
        exitMain();
 
        return;
 
} /* end of sumsel */
 

/* Print out the list of terms. */  

void printterms(char **parmlist, int num) {  
        int i;

        printf("<h3 align=center>Summary of Financial Aid</h3> \
                     <form method=POST action=%s><b>Select Award Period:\
           </b>
<SELECT NAME=\"Session\">\n",probe_name);  
        for (i = 0; i < num; ++i) 
             printf("<OPTION>%s\n",parmlist[i]);
              printf("<OPTION></SELECT><p><center> \
                   <INPUT type=submit value=\"Show Summary of \
          Aid\">
</center>\n"); 
       PostStartTime(); /* added for performance monitoring reasons*/
   
              printf("<input type=hidden name=state value=\"phase2\">\
                      </form><p><br> Go to <a href=\"/AIS/SIC/sicintro.htm\"> \
                      Student Information Center Menu</a><br><br>\n");  
       return;
}  

/* sumrpt will report the financial aid for the selected term */  

void sumrpt() {  
     HBAG bag;
 
     char** parmlist;
 
     int number_of_parms;
 
     char* session;
 


     bag = (HBAG)InitBag("ADAB5678");
 
     session = (char*)FormValue("Session");
/* this time we are adding 2 
                elements to the bag to be sent to MVS */
     FillStrings(bag,2,wsu_number_string,session);
 
     parmlist = (char**)CallServer(bag,&number_of_parms);
  
       print_header("Financial Aid - SUmmary");  
     print_summary(parmlist);
 
     exitMain();
 
     return;
 
}
 

/* print out the financial aid summary */  

void print_summary(char **parms) {  
     int aid_cnt,i;
 
     int number_of_fields;
 
     char *as_of_date;
 
     char *award_total;
 
     char *credited_total;
 
     char** fields;
 
     aid_cnt = atoi(parms[0]);
 
     as_of_date = parms[1];
 
     award_total = parms[2];
 
     credited_total = parms[3];
 
     printf(" <CENTER> <table border>
<caption align=center>\
        <h3>Summary of Financial Aid </h3>
<align=center>\
        %s</caption><p>
<tr> <th>Type of Aid <th> Awarded \
        Amount
<th>Stafford or Plus Loans Less Fees <th> \
        Credited to
account as of %s</tr>\n",
        FormValue("Session"),as_of_date);
 
     if (aid_cnt > 0) {
 
        for (i = 4; i <= aid_cnt+3; ++i) {
 
            fields = split(":",parms[i],&number_of_fields);
 
            printf("<tr><td align=left> %s </td>
<td \
                align=right> %s </td>
<td align=right>\
                %s </td>
<td align=right> %s </td></tr>\n",  
                               fields[0],fields[1],fields[2],fields[3]);  
        }
 
        printf("<tr><td align=left><b>Totals for this \
            award period</b></td>
<td align=right><b>%s\
            </b></td>
<td align=right>&nbsp</td> \
            <td align=right><b>%s</b></td> </table>\
            </center><br>\n",
 
            award_total,credited_total);
 
      } else {
 
        printf("<tr><td align=center colspan=4> \
            <b>*** No Aid for this Award Period ***</b>\
            </td></tr>
</table></center><br>\n");  
      }
 
     printf ("<p><b>If you have not already registered \
           for classes, please do so on \
           <a href=\"/AIS/REG/cgi-bin/reg_info.cgi\"> \
           METRO </a> as soon as you are eligible to \
           avoid delays in the delivery of your financial \
           aid.</b><p>");
 
     printf("</center>Please contact the \
     <a href=\"http://%s/cgi-bin/Logout.cgi?script=http://www.wsu.edu/FINAID/contact.htm \"> 
        Office of Student Financial Aid</a>
if you \
        have questions about the above information. \
        <p>For information regarding your balance/checks,\
        see
<a href=\"/AIS/SIC/cgi-bin/balances_checks.cgi\"> \
        Student Balances/Checks</a>.\n",
        this_server);
 
     printf("<p>Select another <a href=%s>\n",probe_name);
 
     printf("Award Period?</a><br><br>
Go to \
        <a href=\"/AIS/SIC/sicintro.htm\">
Student \
        Information Center Menu</a><br><br>\n");
 
     return;
 
} /* END print_summary() */


Alphabetical List of Functions

alltrim (removes all leading and trailing blanks from a string)
CallServer (sends the bag to MVS)
CallTimeKeeper (used to add time of day to the performance log)
close_client (closes the html stream)
connect_port (open a socket to the requested port on the requested host)
Debug (used only in debugging to print out values of variables)
dir_list (returns a list of all files in a directory)
display_WSU_banner (prints the WSU standard identity)
escape_url (opposite of unescape_url)
exists (checks to see if a file exists)
ExitMain (ends the probe)
FillBag (adds strings and integers to the bag)
FillStrings (adds strings to the bag)
FormValue (array/function holding the POST and GET html form query values)
getenv (returns one of the environment variables)
get_groups (will return a list of groups for NID)
Get_Key (will return a cookie)
get_wsu_number (returns the wsu number in a string)
GetTime (return the current time of day in milliseconds)
HTML_Error (prints an html error message before loggin the client out)
INIT_Probe (this gets the probe started, calls authentication, etc.)
INIT_Probe_Vars (sets all kinds of variables)
InitBag (begins filling a bag to be sent to MVS)
in_group (see if the person is in that group)
itoa (converts and integer to a string)
Logout_FULL (gets rid of the kerberos tickets and user temporary files)
Logout_Public (similar to the above, but used for non specific authentications)
lowercase (converts a string of alpha characters to all lowercase)
ModFormValue (changes the value of an element in FormValue)
Non_Browser_Authentication (used if the probe is not driven by the web)
parseQuery (grabs the POST and GET form values and puts them into FormValue)
plustospace (converts plus signs to spaces)
PostStartTime (adds the time of day and processing cpu time into the html stream)
print_header (prints the html header)
print_meta_refresh_header (print html header and automatically redirects to another url)
putenv (sets one of the environment variables)
query_ups (query the User Profile Server)
Reauth (will let developers ask for reauth on the fly)
reverse (reverse a string)
spacetoplus (converts spaces to a plus sign)
split (similar to the perl function of the same name)
squish (replaces tabs and newlines with spaces and removes multiple occurances of spaces)
string_index (returns the index of a string in a string)
substr (returns a substring)
translate (translates all occurances of one character into another) 
unescape_url (converts a url to a straight ascii including meta characters)
uppercase (changes a string to all uppercase letters)
x2c (converts a hex string to its ascii equivalent)

alltrim

You can remove all leading and trailing blanks in a string with the alltrim function.

char *string;

string = (char*)strdup("  abcd  ");
string = alltrim(string); /* string ends up as "abcd" */

Return to the List of Functions

CallServer

After having initialized your "bag" with the InitBag function and then filling the "bag" with data using either the FillBag  
               or FillStrings functions, then you call CallServer to send the bag to MVS and receive data back from MVS. The format of this command is:

CallServer(bag,&number_of_parms);

where "bag" is the bag you initialized earlier, and "&number_of_parms" is the number of parameters you received back from MVS. Here is an example:

	HBAG bag;

	bag = (HBAG)InitBag("ADAB1234");

	FillStrings(bag,1,wsu_number_string);
	CallServer(bag,&number_of_parms);

 

The call to CallServer also verifies that a valid answer was received from MVS, and it also returns an array that has all of the parameter fields split into an array. For example,

	HBAG bag;
	char **parmlist;
	int  number_of_parms;

	bag = (HBAG)InitBag("ADAB1234");

	FillStrings(bag,1,wsu_number_string);

	parmlist = (char**)CallServer(bag, &number_of_parms);

After this call, parmlist is an array with number_of_parms number of entries in the array, beginning with zero: 
             parmlist[0], parmlist[1], parmlist[2], ... parmlist[number_of_parms].

Return to the List of Functions

CallTimeKeeper

This is used to establish the starting time of the program for performance monitoring. It is called in INIT_Probe, and you should never need to call it yourself. But if you do need to for some reason, then call this function between the begin and end FORM html tag.

Return to the List of Functions

close_client

This is called by exitMain to lo the socket and add a "</BODY></HTML>" to the end of the stream of html going to the client.

Return to the List of Functions

connect_port

If you ever need to open a socket to a port somewhere, use connect_port to do this. In the following example, the socket number is placed into the variable "socket".

int socket;
char *host = "my.host.wsu.edu";
int port = 1234;
char *buffer,*input_buf;

buffer=(char*)malloc(1024);
input_buf=(char*)malloc(1024);
buffer=(char*)strdup("something to send");
if (connect_port(&socket,host,port) < 0)
	HTML_Error("Can't connect",444,
	"For some reason, I can't connect to this host...");
if (write(*socket,buffer,strlen(buffer)<0)
        HTML_Error("problem writing",555,
        "For some reason, I can't write to this host...");
bzero(input_buf,sizeof(input_buf));
if ((ret=read(*socket,input_buf,sizeof(input_buf)))<0)
        HTML_Error("problem reading",666,
        "For some reason, I can't read from this host...");
close(*socket);

Return to the List of Functions

Debug

The Debug function is used to print running values of variables. The function is actually broken down into several other functions: Debug1 which prints a message and one variable, Debug2 which prints a message and 2 variables, Debug3 which prints 3 variables, Debug4 which prints 4 variables, and Debugmsg which prints a message without variables.

char *temp = "abcd";
int i,j;

Debugmsg(USEFUL,"we are starting the process....");
Debug2(USEFUL,"i=%d j=%d",i,j);
Debug1(USEFUL,"temp=%s",temp);

To view what you just sent to the debug file, you need to go to the directory that contains the debugging information:

cd /usr/local/winaccess/spool

and examine the end of the file which is called probe.debug. You could use an editor (pico, vi, dxnotepad, etc.) but this file tends to get very big rather quickly. A better idea is to use tail to type out the end of the file. For example, you could print the last 100 lines of the debug file with:

tail -100 probe.debug | more

 

Return to the List of Functions

dir_list

The dir_list function can be used to return a string that contains a delimiter separated list of files in a directory. The first parameter to dir_list is the path to be read. The second parameter is the delemiter that will be placed between each file in the directory in building the string that is returned. The third parameter is the max length of the string to be built. For example:

char *buf;
int MAX_BUF_SIZE=2048;
char **array;
int num;

buf = malloc(MAX_BUF_SIZE);
bzero(buf,MAX_BUF_SIZE);
buf = (char*)dir_list("/usr/local/bin",";",MAX_BUF_SIZE);
array = (char**)split(";",buf,&num);

After this call, "array" will be an array "num" long that holds all of the members of the directory "/usr/local/bin".

 

Return to the List of Functions

display_WSU_banner

You can print the standard WSU identity at the top of your page with this call:

display_WSU_banner("N");
The parameter being passed is the protocol being used. If it is "N" then the banner is setup for "http" and if "Y" is used, then the banner is setup for "https".

Return to the List of Functions

escape_url

Opposite of unescape_url. It takes a url and returns the url without any illegal meta characters converted.

Return to the List of Functions

exists

This will check to see if a file exists (returns 1) or does not exist (returns 0).

FILE *file;
char *temp_file;

temp_file = (char*)strdup("/tmp/my.temp.file");
file = fopen(temp_file,"r");
if (!exists(file))
	HTML_Error("Can't find the file",666,
	"The file should be there but it is gone!!!!");

Return to the List of Functions

exitMain

This function is used to end the html stream that is sent to the client. It simply calls close_client
CallTimeKeeper, and Logout_Public.

	print_header("Financial Aid - Select Award Period");
	printterms(parmlist, number_of_parms);
	exitMain();
	return;

Return to the List of Functions

FillBag

This function places one parameter value into the "bag" that is to be sent to MVS. For example,

char *param;
int len;
param = (char*)strdup("Send this string to the server....");
len = strlen(param);
bag = (HBAG)InitBag("ADAB1234");
FillBag(bag, "A", " ", param, len);

This will "add" param, which has the length "len" to the "bag".

The "A" in the second parameter indicates that string characters are being added. You could also have a "B" for binary data or "I" for integer data.

The third parameter passed, " " (blank) in the above example, indicates the delimeter value. You can also have "CR" or "TAB" in this third slot.

Before calling FillBag you must have already made a call to InitBag.

Return to the List of Functions

FillStrings

This function will add data to the "bag" that is to be sent to MVS. For example,

	HBAG bag;
	char *param;

	param = (char*)strdup("Send this string to the server....");

	bag = (HBAG)InitBag("ADAB1234");

	FillStrings(bag,1,wsu_number_string);
	FillStrings(bag,2, param, "Send this last...");

Before calling FillStrings you must have already made a call to InitBag.

Return to the List of Functions

 

 

FormValue

This function will return the character string passed from an html "form" statement to this cgi program. You can go here for an example using FormValue as described with the parseQuery function.

Return to the List of Functions

 

getenv

To find out the value of one of the Web server environment variables, you can use getenv to query that value and put it into a string. For example,

tempstring = (char*)getenv("REMOTE_HOST");

will place into tempstring the name of the host that the browser client is running on. Here is a list of environment variables you can query (if set).

 DOCUMENT_ROOT  GATEWAY_INTERFACE  HTTP_ACCEPT
 HTTP_ACCEPT_CHARSET HTTP_ACCEPT_ENCODING HTTP_ACCEPT_LANGUAGE
HTTP_CONNECTION HTTP_HOST HTTP_USER_AGENT
 PATH QUERY_STRING REMOTE_ADDR
REMOTE_HOST REMOTE_PORT REQUEST_METHOD
 REQUEST_URI SCRIPT_FILENAME SCRIPT_NAME
SERVER_PORT SERVER_PROTOCOL SERVER_ROOT
SERVER_SIGNATURE SERVER_SOFTWARE  

If you would like to see an example of how all of this looks, you can go to http://www.wsu.edu/cgi-bin/examples/env_vars.cgi

Return to the List of Functions

 

get_groups

This function is used to return a string that has a list of all groups that the logged in NID belongs to. This list is delimited with a semicolon. You'd use it like this:

char            **array;
int             num_groups;
char            *group_list;
  
group_list = (char*)strdup(get_groups());
array = (char**)split(";",group_list,&num_groups);
printf("first group is %s",array[0]);


Return to the List of Functions

Get_Key

Use this one to return the value of a cookie that have written to the client in a previous step. Get_Key must follow parseQuery or INIT_Probe. In this example, the cookie is named "KEY". What is placed into "cookie" is the value of the cookie called "KEY".

char *cookie;
cookie  = Get_Key("KEY");

Return to the List of Functions

get_wsu_number

If you want to find the wsu number for an NID, use get_wsu_number. Note that the WSU number for the person running the client is determined when running INIT_Probe and is stored in the variable wsu_number (integer) and wsu_number_string. However, you may want to find the WSU number for an NID other than the one running the probe. In this case, use get_wsu_number. This function returns a string, not an integer.

char *nid = "some_fellow";
int wsunumber;

wsunumber = atoi(get_wsu_number(nid));

Return to the List of Functions

GetTime

You can use the GetTime function to set a perl variable to the current time in milliseconds.

int current_time;
current_time = GetTime();

Return to the List of Functions

HTML_Error

This is used to stop processing and log the client out of the system. For example, if you always expected the client to send an html FORM value of "phase" indicating what phase of the process you are in, and if the client didn't return such a value, you'd want to log them out:

	   
if (!FormValue("phase"))
HTML_Error("Problem with posted value",99,"There is a
problem with the phase value. It must always be set
and for some reason this time it isn't.");

This particular example will also return an error code of 99.

Return to the List of Functions

INIT_Probe

If you are going to be doing authentication, then the second function must be INIT_Probe. This function is used to verify that the browser you are using is registered as being able to support SSL and Netscape cookies. Check out the supported browsers page for more information on what browsers are available. You should also read the page on Network ID (NID) security for more information on using your NID on the web at WSU. You would use this function like this:

INIT_Probe_Vars();
INIT_Probe();

After calling INIT_Probe, the following variables are set:

browser
the browser type of this client
cookie_KEY
the 13 character key that is unique for every client
netid
the Network ID the person used to get authenticated
StartTime
The time of day this probe started running
wsu_number
the 8 digit wsu number for this NID as an integer
wsu_number_string
the wsu number in a string form instead of integer
 

If you are passing any parameters to this cgi program, you will find them stored in the FormValue function/array.

Return to the List of Functions

INIT_Probe_Vars

This function initializes the following global variables which are described in the Alphabetical List of Macros and Variables
key_name, probe_name, probe_path, public_probe, probe_background, probe_bgcolor, probe_vlink, probe_link, 
probe_alink, probe_print_cookies, probe_developer_reauth, probe_doauthentication, probe_checkbrowser, 
probe_cookieinfo, probe_no_content_type, web_center, return_link, return_label, this_server, user_cache_timeout.

Return to the List of Functions

InitBag

This is the first function to call po omain a call to MVS. You send as the parameter to InitBag the Adabas glue/action routine name.

	HBAG bag;

	bag = (HBAG)InitBag("ADAB1234");

After this call, the array "bag" has the information necessary to make the call to MVS. InitBag does not actually place any dat th "bag". You must use FillStrings or FillBag to accomplish this.

Return to the List of Functions

in_group

This function is used to return whether or not the logged in NID is in the specified group or not. You'd use it like this:

 
  
        if (in_group("payroll")) {
                printf("this guy is in the payroll group");
        } else {printf("this guy is NOT in the payroll group");}


Return to the List of Functions

itoa

Used to convert an integer to a string.

char *string;
int i;

string = (char*)malloc(100);
i = 123456;
itoa(i,string); /* string is now "123456" */

Return to the List of Functions

Logout_FULL

It deletes the client's NID login by deleting the kerberos ticket and deleting all temporary user identification files. You will probably never need to do this since Logout_Full is called from Logout_Public which is called in exitMain.

Return to the List of Functions

Logout_Public

This is a milder form of Logout_FULL, which logs the client's NID login by deleting the kerberos ticket and deleting all temporary user identification files. You will probably never need to do this since Logout_Public is called in exitMain. The difference is that Logout_Publilc will see if you are using public authentication, which does not need an NID and password.

Return to the List of Functions

lowercase

Converts a string of alpha characters to all lowercase letters.

char *string = "AbCdEfG";
lowercase(string); /* string is now "abcdefg" */

Return to the List of Functions

ModFormValue

This function will modify the contents of an array element in FormValue.

parseQuery();
printf("The value of field1=%s",FormValue("field1"));
ModFormValue("field1","new value of this field...");
printf("Now print the new value of field1=(%s)",FormValue("field1"));

Return to the List of Functions

Non_Browser_Authentication

If you have a probe that is not going to be driven by the web, you need to so some fancy footwork to get by the browser police and the authentication check. This function does that. It is called in place of INIT_Probe. You pass the name of the probe you are running to Non_Browser_Authentication.

#define PROBENAME "tester"
INIT_Probe_Vars();
Non_Browser_Authentication(PROBENAME);

Return to the List of Functions

 

parseQuery

This function is called from INIT_Probe. You only need to call this macro yourself if you are not going to be using INIT_Probe for NID authentication. What the parseQuery function does is to read in all of the parameters passed from the client to this cgi program into an array which is controlled by the FormValue function.

For example, if in your client html code you want to pass the person's phone number to your program you could say:

<form method="POST" action="https://www.wsu.edu/~jones/cgi-bin/gather.cgi">
<b>Please enter your phone number and press SUBMIT:</b><br>
<center>
<table border=5 cellpadding=5 align=center> 
<tr><td>
<input type="text" name=phone_number size=8 maxlength=9>
</td></tr></table>
</p>
<input type="submit" value="SUBMIT">
<input type="reset" value="RESET">
</center>
</form>

In this example, the value of the parameter called "phone_number" is passed to the cgi program "gather.cgi" which resides on the www.wsu.edu server under the account "jones". Then in your cgi program you would say:

parseQuery();

And then the value of the "phone_number" would be kept in the array accessed by calling the FormValue function. You can access this value, after running parseQuery by setting a variable such as:

char *their_phone;

their_phone = (char*)strdup(FormValue("phone_number"));

You ought to use strdup or strcpy unless you've already used malloc. To do the same with malloc you'd say:

char *their_phone;
their_phone = (char*)malloc(50);
bzero(their_hone,sizeof(their_phone));
their_phone = FormValue("phone_number");

From then on, the variable their_phone contains the phone number that was passed.

Return to the List of Functions

plustospace

Its doubtful you'll ever need this one, it converts plus signs to spaces on POST/GET values that were sent from the html FORM statement. It is useful internally. If you ever need it yourself, you call it like:

char temp[10]="a+b";

plustospace(temp);
printf("this will only print 'a' and blank and 'b' [%s]",temp);

Return to the List of Functions

PostStartTime

This function is used to put the current time of day in milliseconds into the html stream to be used for performance monitoring. It must appear between the begin and end FORM tags. It is used like this:

	printf("<h3 align=center>Summary of Financial Aid</h3>
		<form method=POST action=%s><b>Select Award Period:</b>
		<SELECT NAME=\"Session\">\n",probe_name);
	for (i = 0; i < num; ++i) 
		printf("<OPTION>%s\n",parmlist[i]);
	printf("<OPTION></SELECT><p><center>
		<INPUT type=submit value=\"Show Summary of Aid\">
		</center>\n"); 
	PostStartTime(); /* added for performance monitoring reasons */
	printf("<input type=hidden name=state value=\"phase2\">
		</form><p><br>
		Go to <a href=\"/AIS/SIC/sicintro.htm\">
		Student Information Center Menu</a><br><br>\n");
	return;

Return to the List of Functions

print_header

After opening a connection to the client it is necessary to send some html information to the browser. This is done with print_header. By default, what is sent is simply

<html><head><title>...</title></head><body>

Where "..." is the title of the resulting html page. For example, if you said:

INIT_Probe();
print_header("Final Page");
printf("Goodbye %s!!!",netid);
exitMain();

Then the title that will appear at the top of of this html page will be "Final Page".

It is possible for print_header to also pass various page definitions in the <body> tag, such as background image (BACKGROUND), background color (BGCOLOR), link (LINK), alink (ALINK), and vlink (VLINK). These are defined in the List of Macros and Variables.

Return to the List of Functions

print_meta_refresh_header

This macro is similar to print_header. It can set the same values of background image (BACKGROUND), background color (BGCOLOR), link (LINK), alink (ALINK), and vlink (VLINK). The print_meta_refresh_header function has the additional ability to refresh (repaint) the browser screen after a set amount of time, and then branch to a new URL that you specify. For example,

print_meta_refresh_header("Page Title",60,"http://www.wsu.edu/");

After sixty seconds, this page will transfer to the WSU homepage at www.wsu.edu.

Return to the List of Functions

putenv

To set one of the Web server environment variables, you can use putenv . For example,

putenv("PATH=/usr/local/bin:/usr/bin:");

 

WARNING!! Using the putenv command can cause serious problems with your program. Use this only if you know what you are doing. Even if you know what you are doing, BEWARE!!

You can see a complete list of all of the variables in the documentation above for the getenv function.

If you would like to see an example of how all of this looks, you can go to http://www.wsu.edu/cgi-bin/examples/env_vars.cgi

Return to the List of Functions

 

 

query_ups

Call the User Profile Server (UPS) and return a value.

int rc;
char *nid = "some_nid";
char id[100];

rc = query_ups("alias",nid,"id",id);

After calling query_ups in the above example, rc will be 1 if there is a network id of "nid" which in this example was "some_nid". The valid entries to query are:

  • alias (the network id)
  • id (the WSU number)

The valid values to ask for are:

  • alias (the network id)
  • email (if this nid has an email set, you can return it here)
  • id (the WSU number)

Return to the List of Functions

Reauth

Use care with this one. You can force authentication in a cgi script a second time by saying as you leave your cgi script. This might be handy if you wanted to force reauthentication prior to updating some information for somebody, to be absolutely certain they are who they say the are. It willl ask for their password again, but may not ask for their NID, depending on when they last entered their password.

Reauth();
return;

Return to the List of Functions

reverse

This will reverse a string in place:

char *string = "edcba";
reverse(string);  /* ends up with "abcde" */

Return to the List of Functions

spacetoplus

This converts spaces to a plus sign. Its mostly used internally before writing info to the html stream that will appear on a url..

char temp[10]="a b";

spacetoplus(temp);
printf("this will print 'a', '+' and 'b' [%s]",temp);

Return to the List of Functions

split

This is a C equivalent of the perl split function:

              char **sarray, *s1, *s2;
			    char *delimiter, *string;
              int     num,i;
              s1 = (char*)strup("::");
              s2 = (char*)strup("This::is a:test::t");
              sarray = split(s1,s2,&num);
/*
        sarray[0] = "This"
        sarray[1] = "is a:test"
        sarray[2] = "t"
		   num = 3
*/
             delimiter = (char*)strup(",");
             string = (char*)strup("Testing,1,2,3,");
             sarray = split(delimiter,string,&num);
/*
                returns n = 5, and an array of pointers to the strings:

                Testing
                1
                2
                3
                NULL
     */

Return to the List of Functions

squish

You can remove all tabs and new line characters and remove multiple occurances of blanks in a string with the squish function.

char *string;

string = (char*)strdup("\t\t  abcd  \n");
string = squish(string); /* string ends up as " abcd " */

Return to the List of Functions


string_index

Uses the pascal method of determining the index of a string within a string.

int n;
char *string = "abcdef";
char *index = "cd";
n = string_index(string,index);  /* returns 2 */

Return to the List of Functions

substr

Uses the pascal method to return a string. The first parameter is the string itself. The second parameter is the beginning position (starts at zero). The third parameter is the length.

char *string = "abcdefg";
string = substr(string,2,3); /* set string to "cde" */

Return to the List of Functions

translate

Changes all occurances of a single character in a string to another single character.

char *y
char *string = "Ab/dEfGAb/dE\nfG";
y=(char*)malloc(128);
y=(char*)translate(string,'/',"_"); /* string becomes Ab_dEfGAb_dEfG */
To translate the newline character in "string" to a blank, you would do:
y=(char*)translate(string,'\n'," ");
Be sure to use single quotes so the character value is sent to the translate function.

Return to the List of Functions

 

unescape_url

You probably won't need this one, but if you are having trouble with metacharacters, you can create an unescaped string of metacharacters using the unescape_url function. The time this might happen is in passing parameters to the cgi script. If you aren't certain about the handling of metacharacters, and when they are translated, you likely don't need this macro.

char *new_string;
new_string = (char*)malloc(100);
new_string = (char*)strdup(unescape_url(FormValue("field1")));

Return to the List of Functions

uppercase

Changes a string of alpha characters to all upper case.

char *string = "AbCdEfG";
uppercase(string); /* string becomes ABCDEFG  */

Return to the List of Functions

 

 

x2c

This converts a hex string to its ascii equivalent. It is primarily used in unescape_url.

char *temp = "%26";
char *new;
new = (char*)malloc(5);
new = x2c(temp);
printf("this prints an ampersand %s",new);

Return to the List of Functions

Alphabetical List of Macros and Variables

Following is a list of all macros and variables in the C library that you can change before compile time. Probes should have an "include file" which is a *.h file. If the name of your probe is mypgm.c, then you should have a mypgm.h include file. The macros listed below should have their definition changes done in the include file (its a good C programming practice.)

ALINK (controls the color value of active links)
ALPHA_LIST (list of alphabetic letters used for string validation)
ALPHANUM_LIST (list of alphabetic letters and digits used for string validation)
BACKGROUND (the tile background used for this probe)
BGCOLOR (background color on all screens)
BODY_SRC (A way to add source to the BODY tag)
CHECKBROWSER (whether to verify a valid browser is used)
DOAUTHENTICATION (whether or not to force the client to login)
LINK (controls the color value of links you have not yet traversed)
MAIN_CLIENT_CODE (must be included at the top of the main C routine)
MAX_BUFFER_SIZE (Maximum buffer returned from MVS)
NUMBER_LIST (list of valid numbers used for string validation)
PRINT_COOKIES (whether or not to print cookies in the html header)
PROBE_PATH (where on the server the probe's program resides)
PRODUCTION (whether running development or production)
RETURN_LABEL (where to return when done)
RETURN_LINK (where to return when done)
SCRIPT (A way to insert Java and other code into the header)
SCRIPT_LANGUAGE (Obsolete way to indicate which language is in the STYLE)
SCRIPT_SRC (A way to dynamically link to SCRIPT source at another hyperlink)
SCRIPT_TYPE (Best way to indicate which language is in the SCRIPT -- don't use SCRIPT_LANGUAGE)
SCRIPT2 (A way to insert Java and other code into the header)
SCRIPT2_LANGUAGE (Obsolete way to indicate which language is in the STYLE)
SCRIPT2_SRC (A way to dynamically link to SCRIPT2 source at another hyperlink)
SCRIPT2_TYPE (Best way to indicate which language is in the SCRIPT2 -- don't use SCRIPT2_LANGUAGE)
SCRIPT3 (A way to insert Java and other code into the header)
SCRIPT3_LANGUAGE (Obsolete way to indicate which language is in the STYLE)
SCRIPT3_SRC (A way to dynamically link to SCRIPT3 source at another hyperlink)
SCRIPT3_TYPE (Best way to indicate which language is in the SCRIPT3 -- don't use SCRIPT2_LANGUAGE)
SCRIPT4 (A way to insert Java and other code into the header)
SCRIPT4_LANGUAGE (Obsolete way to indicate which language is in the STYLE)
SCRIPT4_SRC (A way to dynamically link to SCRIPT4 source at another hyperlink)
SCRIPT4_TYPE (Best way to indicate which language is in the SCRIPT4 -- don't use SCRIPT2_LANGUAGE)
SCRIPT5 (A way to insert Java and other code into the header)
SCRIPT5_LANGUAGE (Obsolete way to indicate which language is in the STYLE)
SCRIPT5_SRC (A way to dynamically link to SCRIPT5 source at another hyperlink)
SCRIPT5_TYPE (Best way to indicate which language is in the SCRIPT5 -- don't use SCRIPT2_LANGUAGE)
STYLE (Insert cascading style sheet information)
STYLE_TYPE (Insert cascading style sheet information)
THIS_SERVER (which server we are running on)
USER_CACHE_TIMEOUT (how long we'll keep the ticket cache)
VLINK (controls the color value of traversed links)
WEB_CENTER (the general service of this probe)

 

ALINK

This macro controls the color value of active links, the ones the user is currently point to. You can set it in your include file. By default, it is set to NULL, which means use the default set in your browser.

#define ALINK "yellow"

Return to the List of Macros

 

ALPHA_LIST

A list of alphabetic letters (a-z and A-Z) used for string validation.

Return to the List of Macros

ALPHANUM_LIST

A list of alphabetic letters (a-z and A-Z) and the digits (0-9) used for string validation.

Return to the List of Macros

BACKGROUND

The default background used for all probes is "back3.jpg". You can change this to whatever you want with the BACKGROUND macro. If you wanted to use "bg17.jpg" and it resides in the web server's images directory, you would say:

#define BACKGROUND "/images/bg17.jpg"

Return to the List of Macros

BGCOLOR

You can change the background to have a particular color with the BGCOLOR macro. By default, this is turned off.

#define BGCOLOR NULL

You can set it to a color by entering the macro in your includes file:

#define BGCOLOR "silver"

or the color value:

#define BGCOLOR "#C0C0C0"

 

Return to the List of Macros

BODY_SRC

You can use this macro to insert whatever text you need to into the opening BODY tag:

#define BODY_SRC "marginwidth=\"0\" marginheight=\"0\" \
          leftmargin=\"0\" topmargin=\"0\" style=\"margin:0\" "

Return to the List of Macros

 

CHECKBROWSER

Not all browsers can support what we are doing. In particular, we check to make certain the browser is one that supports SSL version 3 and netscape cookies. Check the browser page for more on this. You can turn off the browser check by putting in your include file:

#define CHECKBROWSER FALSE

Return to the List of Macros

 

DOAUTHENTICATION

Use care with this one. It is used if you do not want to do authentication but you do want the browser checking to be done, and you do want the default variables set in INIT_Probe. By default, this is turned on. If you do not want authentication, then in your include file you would have:

#define DOAUTHENTICATION FALSE

Return to the List of Macros

 

LINK

This macro controls the color value of links you have not yet traversed. You can set it in your include file. The default is NULL, or the default color of your browser.

#define LINK "red"

Return to the List of Macros

 

MAIN_CLIENT_CODE

This macro must occur in each C program. It looks like this:

#define MAIN_CLIENT_CODE

Return to the List of Macros

MAX_BUFFER_SIZE

The maximum buffer that can be received from MVS. This variable must not be modified.

Return to the List of Macros

 

NUMBER_LIST

List of valid numbers (0-9) used for string validation.

Return to the List of Macros

PRINT_COOKIES

By default, the function print_header will print any cookies that have been set. If for some reason you do not want print_header to pass the cookies, then you would say:

#define PRINT_COOKIES FALSE

 

Return to the List of Macros

PROBE_PATH

This is where the probe resides on the server. You should leave this alone. The probe path is determined by the PROBE_TYPE which is defined below.

The paths are predefined as:

 SIC  /AIS/SIC/cgi-bin
 ATMS /AIS/ATMS/cgi-bin
REG /AIS/REG/cgi-bin
ADM /AIS/ADM/cgi-bin
CCN /Consultants/cgi-bin

Return to the List of Macros

 

PRODUCTION

You should actually never need to set this macro. Instead, you should have the following in your include file so that PRODUCTION is set for you by running the Makefile.

#ifdef PROD
# define PRODUCTION TRUE
#else
# define PRODUCTION FALSE
#endif

Return to the List of Macros

RETURN_LABEL

Where to return when done processing. This is a label and not the actual link. By default this is the WSU home page. You change it in your include file.

#define RETURN_LABEL "WSU Home Page"

Return to the List of Macros

RETURN_LINK

Where to return when done processing. This is the actual link. By default this is the WSU home page. You change it in your include file.

#define RETURN_LABEL "www.wsu.edu"

Return to the List of Macros

SCRIPT

Used to include SCRIPT code within the SCRIPT tag in the head. For example, you could enter a Java function.

#define SCRIPT "<!-- \
function newWindow(url) { \
     window.open(url, \"NewWindow\",
     \"width=550,height=350,resizable,scrollbars,toolbar,left=200,
     top=90\") } // -->"

Return to the List of Macros

SCRIPT_LANGUAGE

This has been replaced by SCRIPT_TYPE (see below).

#define SCRIPT_LANGUAGE "JavaScript"

Return to the List of Macros

SCRIPT_SRC

This is used if you want to include some SCRIPT code from another hyperlink.

#define SCRIPT_SRC "http://www.wsu.edu/sample_scripts/simple.jsp"

Return to the List of Macros

SCRIPT_TYPE

This is the preferred method of indicating in the SCRIPT tag what language is being used.

#define SCRIPT_TYPE "text/javascript"
Some other types could be for TCL and cascading style sheets:
#define SCRIPT_TYPE "text/css"
#define SCRIPT_TYPE "text/tcl"

Return to the List of Macros

SCRIPT[2-5]

Used to include code within the SCRIPT tag in the head. This is essentially the same as the SCRIPT tag defined above but we are allowing you to use up to five of these SCRIPT tags.For example, you could enter a Java function.

#define SCRIPT5 "<!-- \
function newWindow(url) { \
     window.open(url, \"NewWindow\",
     \"width=550,height=350,resizable,scrollbars,toolbar,left=200,
     top=90\") } // -->"

Return to the List of Macros

SCRIPT[2-5]_LANGUAGE

This has been replaced by SCRIPT_TYPE (see above). If you really need to use this, you can use up to five of these.

#define SCRIPT_LANGUAGE4 "JavaScript"

Return to the List of Macros

SCRIPT[2-5]_SRC

This is used if you want to include some source code from another hyperlink. It is essentially the same as SCRIPT_SRC described above. We are providing up to 5 of these.

#define SCRIPT3_SRC "http://www.wsu.edu/sample_scripts/simple.jsp"

Return to the List of Macros

SCRIPT[2-5]_TYPE

This is the preferred method of indicating in the SCRIPT tag what language is being used. This is essentially the same as SCRIPT_TYPE described above. We are providing up to 5 of these.

#define SCRIPT2_TYPE "text/javascript"
Some other types could be for TCL and cascading style sheets:
#define SCRIPT3_TYPE "text/css"
#define SCRIPT5_TYPE "text/tcl"

Return to the List of Macros

 

STYLE

This is how you can add cascading style sheet info into the head.

#define STYLE "<!-- \
           A:hover.dressup {font-weight:bold;
           text-decoration:none; color:#800000} \
           -->"

Return to the List of Macros

STYLE_TYPE

This is how you can add cascading style sheet info into the head.

#define STYLE "type=\"txt/css\""

Return to the List of Macros

THIS_SERVER

This is the server you are running on. By default, it is "www.it.wsu.edu" in production and "www.develop.it.wsu.edu" for testing. You can access this string in your probe by using the lowercase variable:

char *myserver;
printf("we are running on %s",this_server);

Return to the List of Macros

 

USER_CACHE_TIMEOUT

How long we'll keep the ticket and user information before requiring the client to reauthenticate with the Network ID and password. The default is 1500 which is 15 minutes. If you wanted to shorten that timeout to 5 minutes, you would say:

#define USER_CACHE_TIMEOUT 500

Return to the List of Macros

VLINK

This macro controls the color value of traversed links. You can set it in your include file. The default is NULL, which uses the browser's default.

#define VLINK "purple"

Return to the List of Macros

WEB_CENTER

You can set the macro WEB_CENTER to be the name of your services. For example, if you were in the Registrar's office, you'd put into your include file:

#define WEB_CENTER "Registration System"

and then whenever you used the variable "web_center" (lowercase) in your html stream, you would get the above string.

printf("You are in the %s now",web_center);

 

Return to the List of Macros

 

Probe Types

The valid probe types are

  • SIC - Student Information Center
  • ATMS - Address/Telephone Maintenance System
  • REG - Registration System
  • CCN - Consultants
  • ADM - Admissions and/or Administrative

Sample Makefile

KERBEROS_LIBS = -lqiapi -lexc -lpthreads -lpthread -ldce
STD_LIBS =	$(LIB_PATH) -lwsuinfonet $(KERBEROS_LIBS) /usr/local/winsrc/AIS/SIC/sicutils/sicutils.o
INCLUDES =	$(INCLUDE_PATH)
CC =		gcc -DIDL_PROTOTYPES
CFLAGS = 	$(DEBUG) $(PRODUCTION) $(INCLUDES)
IF =      test_pgm
HDRS = 		$(IF)_c.h  $(IF)_aux.h  $(IF).h
LINKER = 	gcc
MAKEFILE = 	Makefile
OBJS =		$(IF).o 
PRINT = 	lpr -Pls1
PROGRAM = 	$(IF)
SRCS =		$(IF).c 


all: 
		@echo
		@echo "Do 'make dev' "
		@echo

prod-all: $(PROGRAM)
		@echo
		@echo "all done"
		@echo

prod: 
		@echo
		@echo "Making for production. Debug is excluded"
		@echo
		@make prod-all "PRODUCTION=-DPROD" "DEBUG=" "LIB_PATH=-L/usr/local/lib/wsuinfonet" \
                           "INCLUDE_PATH=-I/usr/local/include/wsuinfonet"

dev-all: $(PROGRAM)
		@echo
		@echo "all done"
		@echo

dev:
		@echo
		@echo "Making for development. Debug is included"
		@echo
		@make dev-all "DEBUG=-DDEBUG" "PRODUCTION=" "LIB_PATH=-L/usr/local/lib/wsuinfonet-test" \
                           "INCLUDE_PATH=-I/usr/local/include/wsuinfonet-test"

$(PROGRAM): 	$(OBJS)
		$(LINKER) $(OBJS) $(STD_LIBS) $(CLIENT_STUB) -o $(PROGRAM)

clean:;		rm -f $(PROGRAM) core
                @for i in $(OBJS); do \
                        (echo rm -f $$i; \
                        rm -f $$i); \
                done

depend:;	$(MAKEFILE) PROGRAM=$(PROGRAM) DEST=$(DEST)

index:;		ctags -wx $(HDRS) $(SRCS)

install:	
		@echo
		@echo use "make install-prod" or "make install-dev"
		@echo

install-dev:
		@make installit "WINLIB=/usr/local/www/htdocs/AIS/SIC/cgi-bin"
		@echo
		@echo done installing test_pgm into development
		@echo

install-prod:
		@make installit "WINLIB=/usr/local/depot/AIS/SIC/cgi-bin"
		@echo
		@echo done installing test_pgm into production
	    @echo "Notify Production control."
		@echo

installit:
		@touch $(WINLIB)/$(PROGRAM).cgi
		@echo "mv -f $(WINLIB)/$(PROGRAM).cgi $(WINLIB)/$(PROGRAM).old"
		@mv -f $(WINLIB)/$(PROGRAM).cgi $(WINLIB)/$(PROGRAM).old
		@echo "cp -p $(PROGRAM) $(WINLIB)/$(PROGRAM).cgi"
		@cp -p $(PROGRAM) $(WINLIB)/$(PROGRAM).cgi
		@echo



print:
	        @for i in $(HDRS) $(SRCS); do \
                        (echo $(PRINT) $$i; \
                        $(PRINT) $$i); \
                done
		@echo
		@echo Done printing test_pgm source files
		@echo

load:
		@for i in $(SRCS); do \
			(echo cp -i /usr/local/prod/cpgms/$$i $$i; \
			cp -ip /usr/local/prod/cpgms/$$i $$i); \
		done
		@echo
		@echo "Done loading all of the source files into this directory"
		@echo

program:	$(PROGRAM)

tags:		$(HDRS) $(SRCS); ctags $(HDRS) $(SRCS)

update:		$(DEST)/$(PROGRAM)

$(DEST)/$(PROGRAM): $(SRCS) $(STD_LIBS) $(HDRS) 
		@make -f $(MAKEFILE) DEST=$(DEST) install
#

Registering a DCE Service

Before you can compile your client, you must first register your new service using the web page httpd://www.wsu.edu/UNIX_Systems/cgi/register_DCE_service.html. On this page, you'll select the name of your service. This must be 13 characters or less in length. On this page you'll also need to enter the size of the buffer going to MVS and coming from MVS. These are non-zero values, and the sum of the to and from buffers must not exceed 32,000 bytes.

 


 

| WSU Home | IT UNIX Home | Search | Software List | IT Help Desk |

Questions and Help from: helpdesk@wsu.edu
Comments to: usgwww@wsu.edu
Copyright © 1996-2000 Washington State University.
Disclaimer