Back to index

lightning-sunbird  0.9+nobinonly
Classes | Defines | Typedefs | Enumerations | Functions | Variables
javascript.c File Reference
#include "signtool.h"
#include <prmem.h>
#include <prio.h>
#include <prenv.h>

Go to the source code of this file.

Classes

struct  AVPair_Str
struct  TagItem
struct  HTMLItem_Str
struct  FileBuffer
union  HTMLItem_Str.item

Defines

#define FILE_BUFFER_BUFSIZE   512

Typedefs

typedef struct AVPair_Str AVPair
typedef struct HTMLItem_Str HTMLItem

Enumerations

enum  HTML_STATE { TEXT_HTML_STATE = 0, SCRIPT_HTML_STATE, TEXT_HTML_STATE = 0, SCRIPT_HTML_STATE }
enum  TAG_STATE {
  START_STATE, GET_ATT_STATE, PRE_ATT_WS_STATE, POST_ATT_WS_STATE,
  PRE_VAL_WS_STATE, GET_VALUE_STATE, GET_QUOTED_VAL_STATE, DONE_STATE,
  ERR_STATE, START_STATE, GET_ATT_STATE, PRE_ATT_WS_STATE,
  POST_ATT_WS_STATE, PRE_VAL_WS_STATE, GET_VALUE_STATE, GET_QUOTED_VAL_STATE,
  DONE_STATE, ERR_STATE
}
enum  TAG_TYPE {
  APPLET_TAG, SCRIPT_TAG, LINK_TAG, STYLE_TAG,
  COMMENT_TAG, OTHER_TAG, APPLET_TAG, SCRIPT_TAG,
  LINK_TAG, STYLE_TAG, COMMENT_TAG, OTHER_TAG
}
enum  ITEM_TYPE { TAG_ITEM, TEXT_ITEM, TAG_ITEM, TEXT_ITEM }

Functions

static int javascript_fn (char *relpath, char *basedir, char *reldir, char *filename, void *arg)
static int extract_js (char *filename)
static int copyinto (char *from, char *to)
static PRStatus ensureExists (char *base, char *path)
static int make_dirs (char *path, PRInt32 file_perms)
int InlineJavaScript (char *dir, PRBool recurse)
static HTMLItemCreateTextItem (char *text, unsigned int startline, unsigned int endline)
static HTMLItemCreateTagItem (TagItem *ti, unsigned int startline, unsigned int endline)
static TagItemProcessTag (FileBuffer *fb, char **errStr)
static void DestroyHTMLItem (HTMLItem *item)
static void DestroyTagItem (TagItem *ti)
static TAG_TYPE GetTagType (char *att)
static FileBufferFB_Create (PRFileDesc *fd)
static int FB_GetChar (FileBuffer *fb)
static PRInt32 FB_GetPointer (FileBuffer *fb)
static PRInt32 FB_GetRange (FileBuffer *fb, PRInt32 start, PRInt32 end, char **buf)
static unsigned int FB_GetLineNum (FileBuffer *fb)
static void FB_Destroy (FileBuffer *fb)
static void PrintTagItem (PRFileDesc *fd, TagItem *ti)
static void PrintHTMLStream (PRFileDesc *fd, HTMLItem *head)
static PRBool isAttChar (int c)
static int SaveInlineScript (char *text, char *id, char *basedir, char *archiveDir)
static int SaveUnnamableScript (char *text, char *basedir, char *archiveDir, char *HTMLfilename)
static int SaveSource (char *src, char *codebase, char *basedir, char *archiveDir)
char * TagTypeToString (TAG_TYPE type)

Variables

static char * jartree = NULL
static int idOrdinal
static PRBool dumpParse = PR_FALSE
static char * event_handlers []
static int num_handlers = 23

Class Documentation

struct AVPair_Str

Definition at line 196 of file javascript.c.

Collaboration diagram for AVPair_Str:
Class Members
char * attribute
struct AVPair_Str * next
char * value
unsigned int valueLine
struct TagItem

Definition at line 215 of file javascript.c.

Collaboration diagram for TagItem:
Class Members
AVPair * attList
AVPair * attListTail
char * text
TAG_TYPE type
struct HTMLItem_Str

Definition at line 230 of file javascript.c.

Collaboration diagram for HTMLItem_Str:
Class Members
unsigned int endLine
union HTMLItem_Str item
union HTMLItem_Str item
struct HTMLItem_Str * next
unsigned int startLine
ITEM_TYPE type
struct FileBuffer

Definition at line 241 of file javascript.c.

Collaboration diagram for FileBuffer:
Class Members
char buf
PRInt32 curIndex
PRFileDesc * fd
PRBool IsEOF
unsigned int lineNum
PRInt32 maxIndex
PRInt32 startOffset
union HTMLItem_Str.item

Definition at line 234 of file javascript.c.

Class Members
TagItem * tag
char * text

Define Documentation

Definition at line 245 of file javascript.c.


Typedef Documentation

typedef struct AVPair_Str AVPair
typedef struct HTMLItem_Str HTMLItem

Enumeration Type Documentation

enum HTML_STATE
Enumerator:
TEXT_HTML_STATE 
SCRIPT_HTML_STATE 
TEXT_HTML_STATE 
SCRIPT_HTML_STATE 

Definition at line 156 of file javascript.c.

enum ITEM_TYPE
Enumerator:
TAG_ITEM 
TEXT_ITEM 
TAG_ITEM 
TEXT_ITEM 

Definition at line 222 of file javascript.c.

enum TAG_STATE
Enumerator:
START_STATE 
GET_ATT_STATE 
PRE_ATT_WS_STATE 
POST_ATT_WS_STATE 
PRE_VAL_WS_STATE 
GET_VALUE_STATE 
GET_QUOTED_VAL_STATE 
DONE_STATE 
ERR_STATE 
START_STATE 
GET_ATT_STATE 
PRE_ATT_WS_STATE 
POST_ATT_WS_STATE 
PRE_VAL_WS_STATE 
GET_VALUE_STATE 
GET_QUOTED_VAL_STATE 
DONE_STATE 
ERR_STATE 

Definition at line 164 of file javascript.c.

             {
    /* we start in the start state */
    START_STATE,

    /* We are looking for or reading in an attribute */
    GET_ATT_STATE,

    /* We're burning ws before finding an attribute */
    PRE_ATT_WS_STATE,

    /* We're burning ws after an attribute.  Looking for an '='. */
    POST_ATT_WS_STATE,

    /* We're burning ws after an '=', waiting for a value */
    PRE_VAL_WS_STATE,

    /* We're reading in a value */
    GET_VALUE_STATE,

    /* We're reading in a value that's inside quotes */
    GET_QUOTED_VAL_STATE,

    /* We've encountered the closing '>' */
    DONE_STATE,

    /* Error state */
    ERR_STATE
} 
enum TAG_TYPE
Enumerator:
APPLET_TAG 
SCRIPT_TAG 
LINK_TAG 
STYLE_TAG 
COMMENT_TAG 
OTHER_TAG 
APPLET_TAG 
SCRIPT_TAG 
LINK_TAG 
STYLE_TAG 
COMMENT_TAG 
OTHER_TAG 

Definition at line 203 of file javascript.c.


Function Documentation

static int copyinto ( char *  from,
char *  to 
) [static]

Definition at line 1807 of file javascript.c.

{
    PRInt32 num;
    char      buf [BUFSIZ];
    PRFileDesc * infp = NULL, *outfp = NULL;
    int       retval = -1;

    if ((infp = PR_Open(from, PR_RDONLY, 0777)) == NULL) {
       PR_fprintf(errorFD, "ERROR: Unable to open \"%s\" for reading.\n",
                            from);
       errorCount++;
       goto finish;
    }

    /* If to already exists, print a warning before deleting it */
    if (PR_Access(to, PR_ACCESS_EXISTS) == PR_SUCCESS) {
       PR_fprintf(errorFD, "warning: %s already exists--will overwrite\n", to);
       warningCount++;
       if (rm_dash_r(to)) {
           PR_fprintf(errorFD,
               "ERROR: Unable to remove %s.\n", to);
           errorCount++;
           goto finish;
       }
    }

    if ((outfp = PR_Open(to, PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE, 0777))
         == NULL) {
       char   *errBuf = NULL;

       errBuf = PR_Malloc(PR_GetErrorTextLength());
       PR_fprintf(errorFD, "ERROR: Unable to open \"%s\" for writing.\n", to);
       if (PR_GetErrorText(errBuf)) {
           PR_fprintf(errorFD, "Cause: %s\n", errBuf);
       }
       if (errBuf) {
           PR_Free(errBuf);
       }
       errorCount++;
       goto finish;
    }

    while ( (num = PR_Read(infp, buf, BUFSIZ)) > 0) {
       if (PR_Write(outfp, buf, num) != num) {
           PR_fprintf(errorFD, "ERROR: Error writing to %s.\n", to);
           errorCount++;
           goto finish;
       }
    }

    retval = 0;
finish:
    if (infp) 
       PR_Close(infp);
    if (outfp) 
       PR_Close(outfp);

    return retval;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static HTMLItem * CreateTagItem ( TagItem ti,
unsigned int  startline,
unsigned int  endline 
) [static]

Definition at line 304 of file javascript.c.

{
    HTMLItem * item;

    item = PR_Malloc(sizeof(HTMLItem));
    if (!item) {
       return NULL;
    }

    item->type = TAG_ITEM;
    item->item.tag = ti;
    item->next = NULL;
    item->startLine = startline;
    item->endLine = endline;

    return item;
}

Here is the caller graph for this function:

static HTMLItem * CreateTextItem ( char *  text,
unsigned int  startline,
unsigned int  endline 
) [static]

Definition at line 280 of file javascript.c.

{
    HTMLItem * item;

    item = PR_Malloc(sizeof(HTMLItem));
    if (!item) {
       return NULL;
    }

    item->type = TEXT_ITEM;
    item->item.text = text;
    item->next = NULL;
    item->startLine = startline;
    item->endLine = endline;

    return item;
}

Here is the caller graph for this function:

static void DestroyHTMLItem ( HTMLItem item) [static]

Definition at line 622 of file javascript.c.

{
    if (item->type == TAG_ITEM) {
       DestroyTagItem(item->item.tag);
    } else {
       if (item->item.text) {
           PR_Free(item->item.text);
       }
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void DestroyTagItem ( TagItem ti) [static]

Definition at line 639 of file javascript.c.

{
    AVPair * temp;

    if (ti->text) {
       PR_Free(ti->text); 
       ti->text = NULL;
    }

    while (ti->attList) {
       temp = ti->attList;
       ti->attList = ti->attList->next;

       if (temp->attribute) {
           PR_Free(temp->attribute); 
           temp->attribute = NULL;
       }
       if (temp->value) {
           PR_Free(temp->value); 
           temp->value = NULL;
       }
       PR_Free(temp);
    }

    PR_Free(ti);
}

Here is the caller graph for this function:

static PRStatus ensureExists ( char *  base,
char *  path 
) [static]

Definition at line 1723 of file javascript.c.

{
    char      fn [FNSIZE];
    PRDir * dir;
    sprintf (fn, "%s/%s", base, path);

    /*PR_fprintf(outputFD, "Trying to open directory %s.\n", fn);*/

    if ( (dir = PR_OpenDir(fn)) ) {
       PR_CloseDir(dir);
       return PR_SUCCESS;
    }
    return PR_MkDir(fn, 0777);
}

Here is the caller graph for this function:

static int extract_js ( char *  filename) [static]

!!XXX Change PORT to PL all over this code !!!

Definition at line 1116 of file javascript.c.

{
    PRFileDesc * fd = NULL;
    FileBuffer * fb = NULL;
    HTMLItem * head = NULL;
    HTMLItem * tail = NULL;
    HTMLItem * curitem = NULL;
    HTMLItem * styleList    = NULL;
    HTMLItem * styleListTail       = NULL;
    HTMLItem * entityList   = NULL;
    HTMLItem * entityListTail      = NULL;
    TagItem * tagp = NULL;
    char      *text = NULL;
    char      *tagerr = NULL;
    char      *archiveDir = NULL;
    char      *firstArchiveDir = NULL;
    char      *basedir = NULL;
    PRInt32    textStart;
    PRInt32    curOffset;
    HTML_STATE state;
    int              curchar;
    int              retval = -1;
    unsigned int linenum, startLine;

    /* Initialize the implicit ID counter for each file */
    idOrdinal = 0;

    /*
     * First, parse the HTML into a stream of tags and text.
     */

    fd = PR_Open(filename, PR_RDONLY, 0);
    if (!fd) {
       PR_fprintf(errorFD, "Unable to open %s for reading.\n", filename);
       errorCount++;
       return - 1;
    }

    /* Construct base directory of filename. */
     {
       char   *cp;

       basedir = PL_strdup(filename);

       /* Remove trailing slashes */
       while ( (cp = PL_strprbrk(basedir, "/\\")) == 
           (basedir + strlen(basedir) - 1)) {
           *cp = '\0';
       }

       /* Now remove everything from the last slash (which will be followed
        * by a filename) to the end */
       cp = PL_strprbrk(basedir, "/\\");
       if (cp) {
           *cp = '\0';
       }
    }

    state = TEXT_HTML_STATE;

    fb = FB_Create(fd);

    textStart = 0;
    startLine = 0;
    while (linenum = FB_GetLineNum(fb), (curchar = FB_GetChar(fb)) !=
        EOF) {
       switch (state) {
       case TEXT_HTML_STATE:
           if (curchar == '<') {
              /*
               * Found a tag
               */
              /* Save the text so far to a new text item */
              curOffset = FB_GetPointer(fb) - 2;
              if (curOffset >= textStart) {
                  if (FB_GetRange(fb, textStart, curOffset,
                       &text) != 
                      curOffset - textStart + 1)  {
                     PR_fprintf(errorFD,
                         "Unable to read from %s.\n",
                          filename);
                     errorCount++;
                     goto loser;
                  }
                  /* little fudge here.  If the first character on a line
                   * is '<', meaning a new tag, the preceding text item
                   * actually ends on the previous line.  In this case
                   * we will be saying that the text segment ends on the
                   * next line. I don't think this matters for text items. */
                  curitem = CreateTextItem(text, startLine,
                       linenum);
                  text = NULL;
                  if (tail == NULL) {
                     head = tail = curitem;
                  } else {
                     tail->next = curitem;
                     tail = curitem;
                  }
              }

              /* Process the tag */
              tagp = ProcessTag(fb, &tagerr);
              if (!tagp) {
                  if (tagerr) {
                     PR_fprintf(errorFD, "Error in file %s: %s\n",
                                            filename, tagerr);
                     errorCount++;
                  } else {
                     PR_fprintf(errorFD,
                         "Error in file %s, in tag starting at line %d\n",
                                            filename, linenum);
                     errorCount++;
                  }
                  goto loser;
              }
              /* Add the tag to the list */
              curitem = CreateTagItem(tagp, linenum, FB_GetLineNum(fb));
              if (tail == NULL) {
                  head = tail = curitem;
              } else {
                  tail->next = curitem;
                  tail = curitem;
              }

              /* What's the next state */
              if (tagp->type == SCRIPT_TAG) {
                  state = SCRIPT_HTML_STATE;
              }

              /* Start recording text from the new offset */
              textStart = FB_GetPointer(fb);
              startLine = FB_GetLineNum(fb);
           } else {
              /* regular character.  Next! */
           }
           break;
       case SCRIPT_HTML_STATE:
           if (curchar == '<') {
              char   *cp;
              /*
               * If this is a </script> tag, then we're at the end of the
               * script.  Otherwise, ignore
               */
              curOffset = FB_GetPointer(fb) - 1;
              cp = NULL;
              if (FB_GetRange(fb, curOffset, curOffset + 8, &cp) != 9) {
                  if (cp) { 
                     PR_Free(cp); 
                     cp = NULL; 
                  }
              } else {
                  /* compare the strings */
                  if ( !PORT_Strncasecmp(cp, "</script>", 9) ) {
                     /* This is the end of the script. Record the text. */
                     curOffset--;
                     if (curOffset >= textStart) {
                         if (FB_GetRange(fb, textStart, curOffset, &text) != 
                             curOffset - textStart + 1) {
                            PR_fprintf(errorFD, "Unable to read from %s.\n",
                                 filename);
                            errorCount++;
                            goto loser;
                         }
                         curitem = CreateTextItem(text, startLine, linenum);
                         text = NULL;
                         if (tail == NULL) {
                            head = tail = curitem;
                         } else {
                            tail->next = curitem;
                            tail = curitem;
                         }
                     }

                     /* Now parse the /script tag and put it on the list */
                     tagp = ProcessTag(fb, &tagerr);
                     if (!tagp) {
                         if (tagerr) {
                            PR_fprintf(errorFD, "Error in file %s: %s\n",
                                 filename, tagerr);
                         } else {
                            PR_fprintf(errorFD, 
                                "Error in file %s, in tag starting at"
                                " line %d\n", filename, linenum);
                         }
                         errorCount++;
                         goto loser;
                     }
                     curitem = CreateTagItem(tagp, linenum,
                                          FB_GetLineNum(fb));
                     if (tail == NULL) {
                         head = tail = curitem;
                     } else {
                         tail->next = curitem;
                         tail = curitem;
                     }

                     /* go back to text state */
                     state = TEXT_HTML_STATE;

                     textStart = FB_GetPointer(fb);
                     startLine = FB_GetLineNum(fb);
                  }
              }
           }
           break;
       }
    }

    /* End of the file.  Wrap up any remaining text */
    if (state == SCRIPT_HTML_STATE) {
       if (tail && tail->type == TAG_ITEM) {
           PR_fprintf(errorFD, "ERROR: <SCRIPT> tag at %s:%d is not followed "
               "by a </SCRIPT> tag.\n", filename, tail->startLine);
       } else {
           PR_fprintf(errorFD, "ERROR: <SCRIPT> tag in file %s is not followed"
               " by a </SCRIPT tag.\n", filename);
       }
       errorCount++;
       goto loser;
    }
    curOffset = FB_GetPointer(fb) - 1;
    if (curOffset >= textStart) {
       text = NULL;
       if ( FB_GetRange(fb, textStart, curOffset, &text) != 
           curOffset - textStart + 1) {
           PR_fprintf(errorFD, "Unable to read from %s.\n", filename);
           errorCount++;
           goto loser;
       }
       curitem = CreateTextItem(text, startLine, linenum);
       text = NULL;
       if (tail == NULL) {
           head = tail = curitem;
       } else {
           tail->next = curitem;
           tail = curitem;
       }
    }

    if (dumpParse) {
       PrintHTMLStream(outputFD, head);
    }

    /*
     * Now we have a stream of tags and text.  Go through and deal with each.
     */
    for (curitem = head; curitem; curitem = curitem->next) {
       TagItem * tagp = NULL;
       AVPair * pairp = NULL;
       char   *src = NULL, *id = NULL, *codebase = NULL;
       PRBool hasEventHandler = PR_FALSE;
       int    i;

       /* Reset archive directory for each tag */
       if (archiveDir) {
           PR_Free(archiveDir); 
           archiveDir = NULL;
       }

       /* We only analyze tags */
       if (curitem->type != TAG_ITEM) {
           continue;
       }

       tagp = curitem->item.tag;

       /* go through the attributes to get information */
       for (pairp = tagp->attList; pairp; pairp = pairp->next) {

           /* ARCHIVE= */
           if ( !PL_strcasecmp(pairp->attribute, "archive")) {
              if (archiveDir) {
                  /* Duplicate attribute.  Print warning */
                  PR_fprintf(errorFD,
                      "warning: \"%s\" attribute overwrites previous attribute"
                      " in tag starting at %s:%d.\n",
                      pairp->attribute, filename, curitem->startLine);
                  warningCount++;
                  PR_Free(archiveDir);
              }
              archiveDir = PL_strdup(pairp->value);

              /* Substiture ".arc" for ".jar" */
              if ( (PL_strlen(archiveDir) < 4) || 
                  PL_strcasecmp((archiveDir + strlen(archiveDir) -4), 
                     ".jar")) {
                  PR_fprintf(errorFD,
                      "warning: ARCHIVE attribute should end in \".jar\" in tag"
                      " starting on %s:%d.\n", filename, curitem->startLine);
                  warningCount++;
                  PR_Free(archiveDir);
                  archiveDir = PR_smprintf("%s.arc", archiveDir);
              } else {
                  PL_strcpy(archiveDir + strlen(archiveDir) -4, ".arc");
              }

              /* Record the first archive.  This will be used later if
               * the archive is not specified */
              if (firstArchiveDir == NULL) {
                  firstArchiveDir = PL_strdup(archiveDir);
              }
           } 
           /* CODEBASE= */
           else if ( !PL_strcasecmp(pairp->attribute, "codebase")) {
              if (codebase) {
                  /* Duplicate attribute.  Print warning */
                  PR_fprintf(errorFD,
                      "warning: \"%s\" attribute overwrites previous attribute"
                      " in tag staring at %s:%d.\n",
                      pairp->attribute, filename, curitem->startLine);
                  warningCount++;
              }
              codebase = pairp->value;
           } 
           /* SRC= and HREF= */
           else if ( !PORT_Strcasecmp(pairp->attribute, "src") ||
               !PORT_Strcasecmp(pairp->attribute, "href") ) {
              if (src) {
                  /* Duplicate attribute.  Print warning */
                  PR_fprintf(errorFD,
                      "warning: \"%s\" attribute overwrites previous attribute"
                      " in tag staring at %s:%d.\n",
                      pairp->attribute, filename, curitem->startLine);
                  warningCount++;
              }
              src = pairp->value;
           } 
           /* CODE= */
           else if (!PORT_Strcasecmp(pairp->attribute, "code") ) {
              if (src) {
                  /* Duplicate attribute.  Print warning */
                  PR_fprintf(errorFD,
                      "warning: \"%s\" attribute overwrites previous attribute"
                      " ,in tag staring at %s:%d.\n",
                      pairp->attribute, filename, curitem->startLine);
                  warningCount++;
              }
              src = pairp->value;

              /* Append a .class if one is not already present */
              if ( (PL_strlen(src) < 6) || 
                  PL_strcasecmp( (src + PL_strlen(src) - 6), ".class") ) {
                  src = PR_smprintf("%s.class", src);
                  /* Put this string back into the data structure so it
                   * will be deallocated properly */
                  PR_Free(pairp->value);
                  pairp->value = src;
              }
           } 
           /* ID= */
           else if (!PL_strcasecmp(pairp->attribute, "id") ) {
              if (id) {
                  /* Duplicate attribute.  Print warning */
                  PR_fprintf(errorFD,
                      "warning: \"%s\" attribute overwrites previous attribute"
                      " in tag staring at %s:%d.\n",
                      pairp->attribute, filename, curitem->startLine);
                  warningCount++;
              }
              id = pairp->value;
           }

           /* STYLE= */
           /* style= attributes, along with JS entities, are stored into
            * files with dynamically generated names. The filenames are
            * based on the order in which the text is found in the file.
            * All JS entities on all lines up to and including the line
            * containing the end of the tag that has this style= attribute
            * will be processed before this style=attribute.  So we need
            * to record the line that this _tag_ (not the attribute) ends on.
            */
           else if (!PL_strcasecmp(pairp->attribute, "style") && pairp->value) 
           {
              HTMLItem * styleItem;
              /* Put this item on the style list */
              styleItem = CreateTextItem(PL_strdup(pairp->value),
                  curitem->startLine, curitem->endLine);
              if (styleListTail == NULL) {
                  styleList = styleListTail = styleItem;
              } else {
                  styleListTail->next = styleItem;
                  styleListTail = styleItem;
              }
           } 
           /* Event handlers */
           else {
              for (i = 0; i < num_handlers; i++) {
                  if (!PL_strcasecmp(event_handlers[i], pairp->attribute)) {
                     hasEventHandler = PR_TRUE;
                     break;
                  }
              }
           }


           /* JS Entity */
           {
              char   *entityStart, *entityEnd;
              HTMLItem * entityItem;

              /* go through each JavaScript entity ( &{...}; ) and store it
               * in the entityList.  The important thing is to record what
               * line number it's on, so we can get it in the right order
               * in relation to style= attributes.
               * Apparently, these can't flow across lines, so the start and
               * end line will be the same.  That helps matters.
               */
              entityEnd = pairp->value;
              while ( entityEnd && 
                  (entityStart = PL_strstr(entityEnd, "&{")) /*}*/ != NULL) {
                  entityStart += 2; /* point at beginning of actual entity */
                  entityEnd = PL_strstr(entityStart, /*{*/ "}");
                  if (entityEnd) {
                     /* Put this item on the entity list */
                     *entityEnd = '\0';
                     entityItem = CreateTextItem(PL_strdup(entityStart),
                                       pairp->valueLine, pairp->valueLine);
                     *entityEnd = /* { */ '}';
                     if (entityListTail) {
                         entityListTail->next = entityItem;
                         entityListTail = entityItem;
                     } else {
                         entityList = entityListTail = entityItem;
                     }
                  }
              }
           }
       }

       /* If no archive was supplied, we use the first one of the file */
       if (!archiveDir && firstArchiveDir) {
           archiveDir = PL_strdup(firstArchiveDir);
       }

       /* If we have an event handler, we need to archive this tag */
       if (hasEventHandler) {
           if (!id) {
              PR_fprintf(errorFD,
                  "warning: tag starting at %s:%d has event handler but"
                  " no ID attribute.  The tag will not be signed.\n",
                                   filename, curitem->startLine);
              warningCount++;
           } else if (!archiveDir) {
              PR_fprintf(errorFD,
                  "warning: tag starting at %s:%d has event handler but"
                  " no ARCHIVE attribute.  The tag will not be signed.\n",
                                       filename, curitem->startLine);
              warningCount++;
           } else {
              if (SaveInlineScript(tagp->text, id, basedir, archiveDir)) {
                  goto loser;
              }
           }
       }

       switch (tagp->type) {
       case APPLET_TAG:
           if (!src) {
              PR_fprintf(errorFD,
                  "error: APPLET tag starting on %s:%d has no CODE "
                  "attribute.\n", filename, curitem->startLine);
              errorCount++;
              goto loser;
           } else if (!archiveDir) {
              PR_fprintf(errorFD,
                  "error: APPLET tag starting on %s:%d has no ARCHIVE "
                  "attribute.\n", filename, curitem->startLine);
              errorCount++;
              goto loser;
           } else {
              if (SaveSource(src, codebase, basedir, archiveDir)) {
                  goto loser;
              }
           }
           break;
       case SCRIPT_TAG:
       case LINK_TAG:
       case STYLE_TAG:
           if (!archiveDir) {
              PR_fprintf(errorFD,
                  "error: %s tag starting on %s:%d has no ARCHIVE "
                  "attribute.\n", TagTypeToString(tagp->type),
                                       filename, curitem->startLine);
              errorCount++;
              goto loser;
           } else if (src) {
              if (SaveSource(src, codebase, basedir, archiveDir)) {
                  goto loser;
              }
           } else if (id) {
              /* Save the next text item */
              if (!curitem->next || (curitem->next->type !=
                  TEXT_ITEM)) {
                  PR_fprintf(errorFD,
                      "warning: %s tag starting on %s:%d is not followed"
                      " by script text.\n", TagTypeToString(tagp->type),
                                       filename, curitem->startLine);
                  warningCount++;
                  /* just create empty file */
                  if (SaveInlineScript("", id, basedir, archiveDir)) {
                     goto loser;
                  }
              } else {
                  curitem = curitem->next;
                  if (SaveInlineScript(curitem->item.text,
                       id, basedir,
                      archiveDir)) {
                     goto loser;
                  }
              }
           } else {
              /* No src or id tag--warning */
              PR_fprintf(errorFD,
                  "warning: %s tag starting on %s:%d has no SRC or"
                  " ID attributes.  Will not sign.\n",
                  TagTypeToString(tagp->type), filename, curitem->startLine);
              warningCount++;
           }
           break;
       default:
           /* do nothing for other tags */
           break;
       }

    }

    /* Now deal with all the unnamable scripts */
    if (firstArchiveDir) {
       HTMLItem * style, *entity;

       /* Go through the lists of JS entities and style attributes.  Do them
        * in chronological order within a list.  Pick the list with the lower
        * endLine. In case of a tie, entities come first.
        */
       style = styleList; 
       entity = entityList;
       while (style || entity) {
           if (!entity || (style && (style->endLine < entity->endLine))) {
              /* Process style */
              SaveUnnamableScript(style->item.text, basedir, firstArchiveDir,
                                filename);
              style = style->next;
           } else {
              /* Process entity */
              SaveUnnamableScript(entity->item.text, basedir, firstArchiveDir,
                                filename);
              entity = entity->next;
           }
       }
    }


    retval = 0;
loser:
    /* Blow away the stream */
    while (head) {
       curitem = head;
       head = head->next;
       DestroyHTMLItem(curitem);
    }
    while (styleList) {
       curitem = styleList;
       styleList = styleList->next;
       DestroyHTMLItem(curitem);
    }
    while (entityList) {
       curitem = entityList;
       entityList = entityList->next;
       DestroyHTMLItem(curitem);
    }
    if (text) {
       PR_Free(text); 
       text = NULL;
    }
    if (fb) {
       FB_Destroy(fb); 
       fb = NULL;
    }
    if (fd) {
       PR_Close(fd);
    }
    if (tagerr) {
       PR_smprintf_free(tagerr); 
       tagerr = NULL;
    }
    if (archiveDir) {
       PR_Free(archiveDir); 
       archiveDir = NULL;
    }
    if (firstArchiveDir) {
       PR_Free(firstArchiveDir); 
       firstArchiveDir = NULL;
    }
    return retval;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static FileBuffer * FB_Create ( PRFileDesc fd) [static]

Definition at line 695 of file javascript.c.

{
    FileBuffer * fb;
    PRInt32 amountRead;
    PRInt32 storedOffset;

    fb = (FileBuffer * ) PR_Malloc(sizeof(FileBuffer));
    fb->fd = fd;
    storedOffset = PR_Seek(fd, 0, PR_SEEK_CUR);
    PR_Seek(fd, 0, PR_SEEK_SET);
    fb->startOffset = 0;
    amountRead = PR_Read(fd, fb->buf, FILE_BUFFER_BUFSIZE);
    if (amountRead == -1) 
       goto loser;
    fb->maxIndex = amountRead - 1;
    fb->curIndex = 0;
    fb->IsEOF = (fb->curIndex > fb->maxIndex) ? PR_TRUE : PR_FALSE;
    fb->lineNum = 1;

    PR_Seek(fd, storedOffset, PR_SEEK_SET);
    return fb;
loser:
    PR_Seek(fd, storedOffset, PR_SEEK_SET);
    PR_Free(fb);
    return NULL;
}

Here is the caller graph for this function:

static void FB_Destroy ( FileBuffer fb) [static]

Definition at line 825 of file javascript.c.

{
    if (fb) {
       PR_Free(fb);
    }
}

Here is the caller graph for this function:

static int FB_GetChar ( FileBuffer fb) [static]

Definition at line 728 of file javascript.c.

{
    PRInt32 storedOffset;
    PRInt32 amountRead;
    int       retval = -1;

    if (fb->IsEOF) {
       return EOF;
    }

    storedOffset = PR_Seek(fb->fd, 0, PR_SEEK_CUR);

    retval = (unsigned char) fb->buf[fb->curIndex++];
    if (retval == '\n') 
       fb->lineNum++;

    if (fb->curIndex > fb->maxIndex) {
       /* We're at the end of the buffer. Try to get some new data from the
               * file */
       fb->startOffset += fb->maxIndex + 1;
       PR_Seek(fb->fd, fb->startOffset, PR_SEEK_SET);
       amountRead = PR_Read(fb->fd, fb->buf, FILE_BUFFER_BUFSIZE);
       if (amountRead == -1)  
           goto loser;
       fb->maxIndex = amountRead - 1;
       fb->curIndex = 0;
    }

    fb->IsEOF = (fb->curIndex > fb->maxIndex) ? PR_TRUE : PR_FALSE;

loser:
    PR_Seek(fb->fd, storedOffset, PR_SEEK_SET);
    return retval;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static unsigned int FB_GetLineNum ( FileBuffer fb) [static]

Definition at line 770 of file javascript.c.

{
    return fb->lineNum;
}

Here is the caller graph for this function:

static PRInt32 FB_GetPointer ( FileBuffer fb) [static]

Definition at line 782 of file javascript.c.

{
    return fb->startOffset + fb->curIndex;
}

Here is the caller graph for this function:

static PRInt32 FB_GetRange ( FileBuffer fb,
PRInt32  start,
PRInt32  end,
char **  buf 
) [static]

Definition at line 794 of file javascript.c.

{
    PRInt32 amountRead;
    PRInt32 storedOffset;

    *buf = PR_Malloc(end - start + 2);
    if (*buf == NULL) {
       return 0;
    }

    storedOffset = PR_Seek(fb->fd, 0, PR_SEEK_CUR);
    PR_Seek(fb->fd, start, PR_SEEK_SET);
    amountRead = PR_Read(fb->fd, *buf, end - start + 1);
    PR_Seek(fb->fd, storedOffset, PR_SEEK_SET);
    if (amountRead == -1) {
       PR_Free(*buf);
       *buf = NULL;
       return 0;
    }

    (*buf)[end-start+1] = '\0';
    return amountRead;
}

Here is the caller graph for this function:

static TAG_TYPE GetTagType ( char *  att) [static]

Definition at line 672 of file javascript.c.

{
    if (!PORT_Strcasecmp(att, "APPLET")) {
       return APPLET_TAG;
    }
    if (!PORT_Strcasecmp(att, "SCRIPT")) {
       return SCRIPT_TAG;
    }
    if (!PORT_Strcasecmp(att, "LINK")) {
       return LINK_TAG;
    }
    if (!PORT_Strcasecmp(att, "STYLE")) {
       return STYLE_TAG;
    }
    return OTHER_TAG;
}

Here is the caller graph for this function:

int InlineJavaScript ( char *  dir,
PRBool  recurse 
)

Definition at line 92 of file javascript.c.

{
    jartree = dir;
    if (verbosity >= 0) {
       PR_fprintf(outputFD, "\nGenerating inline signatures from HTML files in: %s\n",
            dir);
    }
    if (PR_GetEnv("SIGNTOOL_DUMP_PARSE")) {
       dumpParse = PR_TRUE;
    }

    return foreach(dir, "", javascript_fn, recurse, PR_FALSE /*include dirs*/,
                     (void * )NULL);

}

Here is the call graph for this function:

static PRBool isAttChar ( int  c) [static]

Definition at line 324 of file javascript.c.

{
    return (isalnum(c) || c == '/' || c == '-');
}

Here is the caller graph for this function:

static int javascript_fn ( char *  relpath,
char *  basedir,
char *  reldir,
char *  filename,
void arg 
) [static]

Definition at line 114 of file javascript.c.

{
    char      fullname [FNSIZE];

    /* only process inline scripts from .htm, .html, and .shtml*/

    if (!(PL_strcaserstr(filename, ".htm") == filename + strlen(filename) -
        4) && 
        !(PL_strcaserstr(filename, ".html") == filename + strlen(filename) -
        5) && 
        !(PL_strcaserstr(filename, ".shtml") == filename + strlen(filename)
        -6)) {
       return 0;
    }

    /* don't process scripts that signtool has already
     extracted (those that are inside .arc directories) */

    if (PL_strcaserstr(filename, ".arc") == filename + strlen(filename) - 4)
       return 0;

    if (verbosity >= 0) {
       PR_fprintf(outputFD, "Processing HTML file: %s\n", relpath);
    }

    /* reset firstArchive at top of each HTML file */

    /* skip directories that contain extracted scripts */

    if (PL_strcaserstr(reldir, ".arc") == reldir + strlen(reldir) - 4)
       return 0;

    sprintf (fullname, "%s/%s", basedir, relpath);
    return extract_js (fullname);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int make_dirs ( char *  path,
PRInt32  file_perms 
) [static]

Definition at line 1747 of file javascript.c.

{
    char      *Path;
    char      *start;
    char      *sep;
    int       ret = 0;
    PRFileInfo info;

    if (!path) {
       return 0;
    }

    Path = PL_strdup(path);
    start = strpbrk(Path, "/\\");
    if (!start) {
       return 0;
    }
    start++; /* start right after first slash */

    /* Each time through the loop add one more directory. */
    while ( (sep = strpbrk(start, "/\\")) ) {
       *sep = '\0';

       if ( PR_GetFileInfo(Path, &info) != PR_SUCCESS) {
           /* No such dir, we have to create it */
           if ( PR_MkDir(Path, file_perms) != PR_SUCCESS) {
              PR_fprintf(errorFD, "ERROR: Unable to create directory %s.\n",
                                                 Path);
              errorCount++;
              ret = -1;
              goto loser;
           }
       } else {
           /* something exists by this name, make sure it's a directory */
           if ( info.type != PR_FILE_DIRECTORY ) {
              PR_fprintf(errorFD, "ERROR: Unable to create directory %s.\n",
                                                 Path);
              errorCount++;
              ret = -1;
              goto loser;
           }
       }

       start = sep + 1; /* start after the next slash */
       *sep = '/';
    }

loser:
    PR_Free(Path);
    return ret;
}

Here is the caller graph for this function:

static void PrintHTMLStream ( PRFileDesc fd,
HTMLItem head 
) [static]

Definition at line 883 of file javascript.c.

{
    while (head) {
       if (head->type == TAG_ITEM) {
           PrintTagItem(fd, head->item.tag);
       } else {
           PR_fprintf(fd, "\nTEXT:\n-----\n%s\n-----\n\n", head->item.text);
       }
       head = head->next;
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void PrintTagItem ( PRFileDesc fd,
TagItem ti 
) [static]

Definition at line 839 of file javascript.c.

{
    AVPair * pair;

    PR_fprintf(fd, "TAG:\n----\nType: ");
    switch (ti->type) {
    case APPLET_TAG:
       PR_fprintf(fd, "applet\n");
       break;
    case SCRIPT_TAG:
       PR_fprintf(fd, "script\n");
       break;
    case LINK_TAG:
       PR_fprintf(fd, "link\n");
       break;
    case STYLE_TAG:
       PR_fprintf(fd, "style\n");
       break;
    case COMMENT_TAG:
       PR_fprintf(fd, "comment\n");
       break;
    case OTHER_TAG:
    default:
       PR_fprintf(fd, "other\n");
       break;
    }

    PR_fprintf(fd, "Attributes:\n");
    for (pair = ti->attList; pair; pair = pair->next) {
       PR_fprintf(fd, "\t%s=%s\n", pair->attribute,
           pair->value ? pair->value : "");
    }
    PR_fprintf(fd, "Text:%s\n", ti->text ? ti->text : "");

    PR_fprintf(fd, "---End of tag---\n");
}

Here is the caller graph for this function:

static TagItem * ProcessTag ( FileBuffer fb,
char **  errStr 
) [static]

Definition at line 335 of file javascript.c.

{
    TAG_STATE state;
    PRInt32 startText, startID, curPos;
    PRBool firstAtt;
    int       curchar;
    TagItem * ti = NULL;
    AVPair * curPair = NULL;
    char      quotechar = '\0';
    unsigned int     linenum;
    unsigned int     startline;

    state = START_STATE;

    startID = FB_GetPointer(fb);
    startText = startID;
    firstAtt = PR_TRUE;

    ti = (TagItem * ) PR_Malloc(sizeof(TagItem));
    if (!ti) 
       out_of_memory();
    ti->type = OTHER_TAG;
    ti->attList = NULL;
    ti->attListTail = NULL;
    ti->text = NULL;

    startline = FB_GetLineNum(fb);

    while (state != DONE_STATE && state != ERR_STATE) {
       linenum = FB_GetLineNum(fb);
       curchar = FB_GetChar(fb);
       if (curchar == EOF) {
           *errStr = PR_smprintf(
               "line %d: Unexpected end-of-file while parsing tag starting at line %d.\n",
                linenum, startline);
           state = ERR_STATE;
           continue;
       }

       switch (state) {
       case START_STATE:
           if (curchar == '!') {
              /*
               * SGML tag or comment
               * Here's the general rule for SGML tags.  Everything from
               * <! to > is the tag.  Inside the tag, comments are
               * delimited with --.  So we are looking for the first '>'
               * that is not commented out, that is, not inside a pair
               * of --: <!DOCTYPE --this is a comment >(psyche!)   -->
               */

              PRBool inComment = PR_FALSE;
              short  hyphenCount = 0; /* number of consecutive hyphens */

              while (1) {
                  linenum = FB_GetLineNum(fb);
                  curchar = FB_GetChar(fb);
                  if (curchar == EOF) {
                     /* Uh oh, EOF inside comment */
                     *errStr = PR_smprintf(
    "line %d: Unexpected end-of-file inside comment starting at line %d.\n",
                                          linenum, startline);
                     state = ERR_STATE;
                     break;
                  }
                  if (curchar == '-') {
                     if (hyphenCount == 1) {
                         /* This is a comment delimiter */
                         inComment = !inComment;
                         hyphenCount = 0;
                     } else {
                         /* beginning of a comment delimiter? */
                         hyphenCount = 1;
                     }
                  } else if (curchar == '>') {
                     if (!inComment) {
                         /* This is the end of the tag */
                         state = DONE_STATE;
                         break;
                     } else {
                         /* The > is inside a comment, so it's not
                                                  * really the end of the tag */
                         hyphenCount = 0;
                     }
                  } else {
                     hyphenCount = 0;
                  }
              }
              ti->type = COMMENT_TAG;
              break;
           }
           /* fall through */
       case GET_ATT_STATE:
           if (isspace(curchar) || curchar == '=' || curchar
               == '>') {
              /* end of the current attribute */
              curPos = FB_GetPointer(fb) - 2;
              if (curPos >= startID) {
                  /* We have an attribute */
                  curPair = (AVPair * )PR_Malloc(sizeof(AVPair));
                  if (!curPair) 
                     out_of_memory();
                  curPair->value = NULL;
                  curPair->next = NULL;
                  FB_GetRange(fb, startID, curPos,
                      &curPair->attribute);

                  /* Stick this attribute on the list */
                  if (ti->attListTail) {
                     ti->attListTail->next = curPair;
                     ti->attListTail = curPair;
                  } else {
                     ti->attList = ti->attListTail =
                         curPair;
                  }

                  /* If this is the first attribute, find the type of tag
                   * based on it. Also, start saving the text of the tag. */
                  if (firstAtt) {
                     ti->type = GetTagType(curPair->attribute);
                     startText = FB_GetPointer(fb)
                         -1;
                     firstAtt = PR_FALSE;
                  }
              } else {
                  if (curchar == '=') {
                     /* If we don't have any attribute but we do have an
                      * equal sign, that's an error */
                     *errStr = PR_smprintf("line %d: Malformed tag starting at line %d.\n",
                          linenum, startline);
                     state = ERR_STATE;
                     break;
                  }
              }

              /* Compute next state */
              if (curchar == '=') {
                  startID = FB_GetPointer(fb);
                  state = PRE_VAL_WS_STATE;
              } else if (curchar == '>') {
                  state = DONE_STATE;
              } else if (curPair) {
                  state = POST_ATT_WS_STATE;
              } else {
                  state = PRE_ATT_WS_STATE;
              }
           } else if (isAttChar(curchar)) {
              /* Just another char in the attribute. Do nothing */
              state = GET_ATT_STATE;
           } else {
              /* bogus char */
              *errStr = PR_smprintf("line %d: Bogus chararacter '%c' in tag.\n",
                                   linenum, curchar);
              state = ERR_STATE;
              break;
           }
           break;
       case PRE_ATT_WS_STATE:
           if (curchar == '>') {
              state = DONE_STATE;
           } else if (isspace(curchar)) {
              /* more whitespace, do nothing */
           } else if (isAttChar(curchar)) {
              /* starting another attribute */
              startID = FB_GetPointer(fb) - 1;
              state = GET_ATT_STATE;
           } else {
              /* bogus char */
              *errStr = PR_smprintf("line %d: Bogus character '%c' in tag.\n",
                                   linenum, curchar);
              state = ERR_STATE;
              break;
           }
           break;
       case POST_ATT_WS_STATE:
           if (curchar == '>') {
              state = DONE_STATE;
           } else if (isspace(curchar)) {
              /* more whitespace, do nothing */
           } else if (isAttChar(curchar)) {
              /* starting another attribute */
              startID = FB_GetPointer(fb) - 1;
              state = GET_ATT_STATE;
           } else if (curchar == '=') {
              /* there was whitespace between the attribute and its equal
               * sign, which means there's a value coming up */
              state = PRE_VAL_WS_STATE;
           } else {
              /* bogus char */
              *errStr = PR_smprintf("line %d: Bogus character '%c' in tag.\n",
                                                 linenum, curchar);
              state = ERR_STATE;
              break;
           }
           break;
       case PRE_VAL_WS_STATE:
           if (curchar == '>') {
              /* premature end-of-tag (sounds like a personal problem). */
              *errStr = PR_smprintf(
                  "line %d: End of tag while waiting for value.\n",
                   linenum);
              state = ERR_STATE;
              break;
           } else if (isspace(curchar)) {
              /* more whitespace, do nothing */
              break;
           } else {
              /* this must be some sort of value. Fall through
                             * to GET_VALUE_STATE */
              startID = FB_GetPointer(fb) - 1;
              state = GET_VALUE_STATE;
           }
           /* Fall through if we didn't break on '>' or whitespace */
       case GET_VALUE_STATE:
           if (isspace(curchar) || curchar == '>') {
              /* end of value */
              curPos = FB_GetPointer(fb) - 2;
              if (curPos >= startID) {
                  /* Grab the value */
                  FB_GetRange(fb, startID, curPos,
                      &curPair->value);
                  curPair->valueLine = linenum;
              } else {
                  /* empty value, leave as NULL */
              }
              if (isspace(curchar)) {
                  state = PRE_ATT_WS_STATE;
              } else {
                  state = DONE_STATE;
              }
           } else if (curchar == '\"' || curchar == '\'') {
              /* quoted value.  Start recording the value inside the quote*/
              startID = FB_GetPointer(fb);
              state = GET_QUOTED_VAL_STATE;
              PORT_Assert(quotechar == '\0');
              quotechar = curchar; /* look for matching quote type */
           } else {
              /* just more value */
           }
           break;
       case GET_QUOTED_VAL_STATE:
           PORT_Assert(quotechar != '\0');
           if (curchar == quotechar) {
              /* end of quoted value */
              curPos = FB_GetPointer(fb) - 2;
              if (curPos >= startID) {
                  /* Grab the value */
                  FB_GetRange(fb, startID, curPos,
                      &curPair->value);
                  curPair->valueLine = linenum;
              } else {
                  /* empty value, leave it as NULL */
              }
              state = GET_ATT_STATE;
              quotechar = '\0';
              startID = FB_GetPointer(fb);
           } else {
              /* more quoted value, continue */
           }
           break;
       case DONE_STATE:
       case ERR_STATE:
       default:
           ; /* should never get here */
       }
    }

    if (state == DONE_STATE) {
       /* Get the text of the tag */
       curPos = FB_GetPointer(fb) - 1;
       FB_GetRange(fb, startText, curPos, &ti->text);

       /* Return the tag */
       return ti;
    }

    /* Uh oh, an error.  Kill the tag item*/
    DestroyTagItem(ti);
    return NULL;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int SaveInlineScript ( char *  text,
char *  id,
char *  basedir,
char *  archiveDir 
) [static]

Definition at line 902 of file javascript.c.

{
    char      *filename = NULL;
    PRFileDesc * fd = NULL;
    int       retval = -1;
    PRInt32 writeLen;
    char      *ilDir = NULL;

    if (!text || !id || !archiveDir) {
       return - 1;
    }

    if (dumpParse) {
       PR_fprintf(outputFD, "SaveInlineScript: text=%s, id=%s, \n"
           "basedir=%s, archiveDir=%s\n",
           text, id, basedir, archiveDir);
    }

    /* Make sure the archive directory is around */
    if (ensureExists(basedir, archiveDir) != PR_SUCCESS) {
       PR_fprintf(errorFD,
           "ERROR: Unable to create archive directory %s.\n", archiveDir);
       errorCount++;
       return - 1;
    }

    /* Make sure the inline script directory is around */
    ilDir = PR_smprintf("%s/inlineScripts", archiveDir);
    scriptdir = "inlineScripts";
    if (ensureExists(basedir, ilDir) != PR_SUCCESS) {
       PR_fprintf(errorFD,
           "ERROR: Unable to create directory %s.\n", ilDir);
       errorCount++;
       return - 1;
    }

    filename = PR_smprintf("%s/%s/%s", basedir, ilDir, id);

    /* If the file already exists, give a warning, then blow it away */
    if (PR_Access(filename, PR_ACCESS_EXISTS) == PR_SUCCESS) {
       PR_fprintf(errorFD,
           "warning: file \"%s\" already exists--will overwrite.\n",
                            filename);
       warningCount++;
       if (rm_dash_r(filename)) {
           PR_fprintf(errorFD, "ERROR: Unable to delete %s.\n", filename);
           errorCount++;
           goto finish;
       }
    }

    /* Write text into file with name id */
    fd = PR_Open(filename, PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE, 0777);
    if (!fd) {
       PR_fprintf(errorFD, "ERROR: Unable to create file \"%s\".\n",
                            filename);
       errorCount++;
       goto finish;
    }
    writeLen = strlen(text);
    if ( PR_Write(fd, text, writeLen) != writeLen) {
       PR_fprintf(errorFD, "ERROR: Unable to write to file \"%s\".\n",
                            filename);
       errorCount++;
       goto finish;
    }

    retval = 0;
finish:
    if (filename) {
       PR_smprintf_free(filename);
    }
    if (ilDir) {
       PR_smprintf_free(ilDir);
    }
    if (fd) {
       PR_Close(fd);
    }
    return retval;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int SaveSource ( char *  src,
char *  codebase,
char *  basedir,
char *  archiveDir 
) [static]

Definition at line 1038 of file javascript.c.

{
    char      *from = NULL, *to = NULL;
    int       retval = -1;
    char      *arcDir = NULL;

    if (!src || !archiveDir) {
       return - 1;
    }

    if (dumpParse) {
       PR_fprintf(outputFD, "SaveSource: src=%s, codebase=%s, basedir=%s,\n"
           "archiveDir=%s\n", src, codebase, basedir, archiveDir);
    }

    if (codebase) {
       arcDir = PR_smprintf("%s/%s/%s/", basedir, codebase, archiveDir);
    } else {
       arcDir = PR_smprintf("%s/%s/", basedir, archiveDir);
    }

    if (codebase) {
       from = PR_smprintf("%s/%s/%s", basedir, codebase, src);
       to = PR_smprintf("%s%s", arcDir, src);
    } else {
       from = PR_smprintf("%s/%s", basedir, src);
       to = PR_smprintf("%s%s", arcDir, src);
    }

    if (make_dirs(to, 0777)) {
       PR_fprintf(errorFD,
           "ERROR: Unable to create archive directory %s.\n", archiveDir);
       errorCount++;
       goto finish;
    }

    retval = copyinto(from, to);
finish:
    if (from) 
       PR_Free(from);
    if (to) 
       PR_Free(to);
    if (arcDir) 
       PR_Free(arcDir);
    return retval;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int SaveUnnamableScript ( char *  text,
char *  basedir,
char *  archiveDir,
char *  HTMLfilename 
) [static]

Definition at line 990 of file javascript.c.

{
    char      *id = NULL;
    char      *ext = NULL;
    char      *start = NULL;
    int       retval = -1;

    if (!text || !archiveDir || !HTMLfilename) {
       return - 1;
    }

    if (dumpParse) {
       PR_fprintf(outputFD, "SaveUnnamableScript: text=%s, basedir=%s,\n"
           "archiveDir=%s, filename=%s\n", text, basedir, archiveDir,
                            HTMLfilename);
    }

    /* Construct the filename */
    ext = PL_strrchr(HTMLfilename, '.');
    if (ext) {
       *ext = '\0';
    }
    for (start = HTMLfilename; strpbrk(start, "/\\"); 
         start = strpbrk(start, "/\\") + 1)
       /* do nothing */;
    if (*start == '\0') 
       start = HTMLfilename;
    id = PR_smprintf("_%s%d", start, idOrdinal++);
    if (ext) {
       *ext = '.';
    }

    /* Now call SaveInlineScript to do the work */
    retval = SaveInlineScript(text, id, basedir, archiveDir);

    PR_Free(id);

    return retval;
}

Here is the call graph for this function:

Here is the caller graph for this function:

char* TagTypeToString ( TAG_TYPE  type)

Definition at line 1092 of file javascript.c.

{
    switch (type) {
    case APPLET_TAG:
       return "APPLET";
    case SCRIPT_TAG:
       return "SCRIPT";
    case LINK_TAG:
       return "LINK";
    case STYLE_TAG:
       return "STYLE";
    default:
       break;
    }
    return "unknown";
}

Variable Documentation

Definition at line 51 of file javascript.c.

char* event_handlers[] [static]
Initial value:
 {
    "onAbort",
    "onBlur",
    "onChange",
    "onClick",
    "onDblClick",
    "onDragDrop",
    "onError",
    "onFocus",
    "onKeyDown",
    "onKeyPress",
    "onKeyUp",
    "onLoad",
    "onMouseDown",
    "onMouseMove",
    "onMouseOut",
    "onMouseOver",
    "onMouseUp",
    "onMove",
    "onReset",
    "onResize",
    "onSelect",
    "onSubmit",
    "onUnload"
}

Definition at line 53 of file javascript.c.

int idOrdinal [static]

Definition at line 50 of file javascript.c.

char* jartree = NULL [static]

Definition at line 49 of file javascript.c.

int num_handlers = 23 [static]

Definition at line 80 of file javascript.c.