Main Page | Namespace List | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

manifest.c

Go to the documentation of this file.
00001 /*!
00002  * @file manifest.c
00003  *
00004  * @brief Read JAR manifest file.
00005  *
00006  *
00007  * @section Control
00008  *
00009  * \$URL: https://svn.apache.org/path/name/manifest.c $ \$Id: manifest.c 0 09/28/2005 dlydick $
00010  *
00011  * Copyright 2005 The Apache Software Foundation
00012  * or its licensors, as applicable.
00013  *
00014  * Licensed under the Apache License, Version 2.0 ("the License");
00015  * you may not use this file except in compliance with the License.
00016  * You may obtain a copy of the License at
00017  *
00018  *     http://www.apache.org/licenses/LICENSE-2.0
00019  *
00020  * Unless required by applicable law or agreed to in writing,
00021  * software distributed under the License is distributed on an
00022  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
00023  * either express or implied.
00024  *
00025  * See the License for the specific language governing permissions
00026  * and limitations under the License.
00027  *
00028  * @version \$LastChangedRevision: 0 $
00029  *
00030  * @date \$LastChangedDate: 09/28/2005 $
00031  *
00032  * @author \$LastChangedBy: dlydick $
00033  *         Original code contributed by Daniel Lydick on 09/28/2005.
00034  *
00035  * @section Reference
00036  *
00037  */
00038 
00039 #include "arch.h"
00040 ARCH_COPYRIGHT_APACHE(manifest, c, "$URL: https://svn.apache.org/path/name/manifest.c $ $Id: manifest.c 0 09/28/2005 dlydick $");
00041 
00042 
00043 #include <stdio.h>
00044 #include <ctype.h>
00045 #include <strings.h>
00046 
00047 #include "jvmcfg.h"
00048 #include "heap.h" 
00049 #include "exit.h"
00050 #include "util.h"
00051 
00052 /*!
00053  * @brief Search a JAR manifest file for a main class attribute.
00054  *
00055  * This attribute MUST be all on one line and without any
00056  * line continuations breaking up the class name.  Look for
00057  * a line of text like this, where @b | indicates that the
00058  * following character is the first one on the line:
00059  *
00060  * @verbatim
00061       |
00062       |Main-Class: name.of.start.class\n
00063       |
00064   
00065    WITHOUT any line continuations,
00066   
00067       |
00068       |Main-Class: name.of.sta\n
00069       | rt.class\n
00070       |
00071   
00072    @endverbatim
00073  *
00074  * @todo  Although such a continuation is supported by the JAR file,
00075  * this implementation does not support it (yet).  With this
00076  * restriction, the if only one single space separates the name of
00077  * the attribute and the class name, then since a line may be up
00078  * to 72 characters long (that is JVMCFG_JARFILE_MANIFEST_LINE_MAX
00079  * characters), then the class name may be 61 characters long.
00080  *
00081  *
00082  * @param  mnfname   JAR manifest file name, /absolute/path/name
00083  *         
00084  *
00085  * @returns Heap pointer to null-terminated class name, or
00086  *          @link #rnull rnull@endlink if not found.
00087  *          Call HEAP_FREE_DATA() when done.
00088  *
00089  */
00090 rchar *manifest_get_main(rchar *mnfname)
00091 {
00092     FILE *mf = fopen(mnfname, "r");
00093 
00094     if (rnull == mf)
00095     {
00096         return((rchar *) rnull);
00097     }
00098 
00099     rchar *mnfdata = HEAP_GET_DATA(JVMCFG_STDIO_BFR, rfalse);
00100 
00101     int mclen =  strlen(JVMCFG_JARFILE_MANIFEST_MAIN_CLASS);
00102 
00103     /* Read until end of file or match located */
00104     while (mnfdata == (rchar *) fgets(mnfdata, JVMCFG_STDIO_BFR, mf))
00105     {
00106         /*
00107          * Scan for ^Main-Class: attribute name (text starting
00108          * at beginnin of line)
00109          */
00110         if (0 != strncmp(mnfdata,
00111                          JVMCFG_JARFILE_MANIFEST_MAIN_CLASS,
00112                          mclen))
00113         {
00114             continue;
00115         }
00116 
00117         /*
00118          * Attribute name found.
00119          *
00120          * Scan for first non-white character after attribute name.
00121          * This will be the start of the class name.
00122          */
00123         rint i;
00124         for (i = mclen; i < strlen(mnfdata); i++)
00125         {
00126             /* if <b>white space</b> is rfalse */
00127             if (0 == isspace((int) mnfdata[i]))
00128             {
00129                 break; /* Found first non-white-space character */
00130             }
00131         }
00132         /* If nothing else, the \n at end of line is white space */
00133 
00134         /*
00135          * Class name found.
00136          *
00137          * Scan for first white character after class name.
00138          * This will be the end of the class name.
00139          */
00140         rint j;
00141         for (j = i; j < strlen(mnfdata); j++)
00142         {
00143             /* if <b>white space</b> is @link #rtrue rtrue@endlink */
00144             if (0 != isspace((int) mnfdata[j]))
00145             {
00146                 break;  /* Found first white-space character */
00147             }
00148         }
00149         /* If nothing else, the \n at end of line is white space */
00150 
00151         fclose(mf);
00152 
00153         /* Allocate space for non-empty class name plus NUL byte */
00154         rchar *mnfresult;
00155         if (i != j)
00156         { 
00157             mnfresult = HEAP_GET_DATA(j - i + sizeof(rchar), rfalse);
00158 
00159             /* If failure above, HEAP_FREE_DATA(mnfdata) is never run */
00160         }
00161         else
00162         {
00163             /* Do not process empty class name, declare error instead */
00164             HEAP_FREE_DATA(mnfdata);
00165 
00166             sysErrMsg("manifest_get_main",
00167                       "Missing class name in manifest file %s",
00168                       mnfname);
00169             exit_jvm(EXIT_MANIFEST_JAR);
00170 /*NOTREACHED*/
00171         }
00172 
00173         memcpy(mnfresult, &mnfdata[i], j - i);
00174         mnfresult[j - i] = '\0';
00175 
00176         HEAP_FREE_DATA(mnfdata);
00177         return(mnfresult);
00178     }
00179 
00180     fclose(mf);
00181 
00182     HEAP_FREE_DATA(mnfdata);
00183 
00184     return((rchar *) rnull);
00185 
00186 } /* END of manifest_get_main() */
00187 
00188 
00189 /* EOF */
00190 

Generated on Fri Sep 30 18:49:05 2005 by  doxygen 1.4.4