Add serialization support for profile
authorPaul Park <pjpark@mit.edu>
Tue, 29 Aug 1995 18:45:36 +0000 (18:45 +0000)
committerPaul Park <pjpark@mit.edu>
Tue, 29 Aug 1995 18:45:36 +0000 (18:45 +0000)
git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@6631 dc483132-0cff-0310-8789-dd5450dbe970

src/util/profile/ChangeLog
src/util/profile/configure.in
src/util/profile/prof_init.c

index 2c53cbad2bf133b61800051da9fed20fb9fbf9c8..bf68985a3d07762bf526a56a46595b8d98a7e735 100644 (file)
@@ -1,3 +1,8 @@
+
+Tue Aug 29 14:23:16 EDT 1995   Paul Park       (pjpark@mit.edu)
+       * configure.in - Add checks for size of short, int and long.
+       * prof_init.c - Add routines to serialize profile context.
+
 Tue Aug 15 17:17:40 1995  Ezra Peisach  <epeisach@kangaroo.mit.edu>
 
        * prof_parse.c (strip_line,parse_line): Declare as static.
index 08e7315984c4f97fe95b0fc2cd6420a2e0705f2a..f58fe61a89a30ce5bed8b6b4e1825a582a3f652e 100644 (file)
@@ -4,6 +4,9 @@ AC_CONST
 AC_PROG_ARCHIVE
 AC_PROG_ARCHIVE_ADD
 AC_PROG_RANLIB
+AC_CHECK_SIZEOF(short)
+AC_CHECK_SIZEOF(int)
+AC_CHECK_SIZEOF(long)
 ET_RULES
 V5_SHARED_LIB_OBJS
 CopyHeader(profile.h,$(BUILDTOP)/include)
index 5dcc84e5350bafd85d7a2e7b899e77b3430e72b9..d8e1c6bd17a1366ff84d0e29cbf0d6e204240d98 100644 (file)
 
 #include "prof_int.h"
 
+/* Find a 4-byte integer type */
+#if    (SIZEOF_SHORT == 4)
+typedef short  prof_int32;
+#elif  (SIZEOF_INT == 4)
+typedef int    prof_int32;
+#elif  (SIZEOF_LONG == 4)
+typedef        int     prof_int32;
+#else  /* SIZEOF_LONG == 4 */
+error(do not have a 4-byte integer type)
+#endif /* SIZEOF_LONG == 4 */
+
 errcode_t profile_init(filenames, ret_profile)
        const char **filenames;
        profile_t *ret_profile;
@@ -272,3 +283,167 @@ errcode_t profile_get_integer(profile, name, subname, subsubname,
    *ret_int = atoi(value);
    return 0;
 }
+
+errcode_t profile_ser_size(unused, profile, sizep)
+    const char *unused;
+    profile_t  profile;
+    size_t     *sizep;
+{
+    size_t     required;
+    prf_file_t pfp;
+
+    /*
+     * ARGH - We want to avoid having to include k5-int.h.  We ASSuME that
+     * krb5_int32 is 4 bytes in length.
+     *
+     * krb5_int32 for header
+     * krb5_int32 for number of files.
+     * krb5_int32 for trailer
+     */
+    required = 3*sizeof(prof_int32);
+    for (pfp = profile->first_file; pfp; pfp = pfp->next) {
+       required += sizeof(prof_int32);
+       if (pfp->filename)
+           required += strlen(pfp->filename);
+    }
+    *sizep += required;
+    return 0;
+}
+
+static void pack_int32(oval, bufpp, remainp)
+    prof_int32         oval;
+    unsigned char      **bufpp;
+    size_t             *remainp;
+{
+    (*bufpp)[0] = (unsigned char) ((oval >> 24) & 0xff);
+    (*bufpp)[1] = (unsigned char) ((oval >> 16) & 0xff);
+    (*bufpp)[2] = (unsigned char) ((oval >> 8) & 0xff);
+    (*bufpp)[3] = (unsigned char) (oval & 0xff);
+    *bufpp += sizeof(prof_int32);
+    *remainp -= sizeof(prof_int32);
+}
+
+errcode_t profile_ser_externalize(unused, profile, bufpp, remainp)
+    const char         *unused;
+    profile_t          profile;
+    unsigned char      **bufpp;
+    size_t             *remainp;
+{
+    errcode_t          retval;
+    size_t             required;
+    unsigned char      *bp;
+    size_t             remain;
+    prf_file_t         pfp;
+    prof_int32         fcount, slen;
+
+    required = 0;
+    bp = *bufpp;
+    remain = *remainp;
+    retval = EINVAL;
+    if (profile) {
+       retval = ENOMEM;
+       (void) profile_ser_size(unused, profile, &required);
+       if (required <= remain) {
+           fcount = 0;
+           for (pfp = profile->first_file; pfp; pfp = pfp->next)
+               fcount++;
+           pack_int32(PROF_MAGIC_PROFILE, &bp, &remain);
+           pack_int32(fcount, &bp, &remain);
+           for (pfp = profile->first_file; pfp; pfp = pfp->next) {
+               slen = (pfp->filename) ?
+                   (prof_int32) strlen(pfp->filename) : 0;
+               pack_int32(slen, &bp, &remain);
+               if (slen) {
+                   memcpy(bp, pfp->filename, (size_t) slen);
+                   bp += slen;
+                   remain -= (size_t) slen;
+               }
+           }
+           pack_int32(PROF_MAGIC_PROFILE, &bp, &remain);
+           retval = 0;
+           *bufpp = bp;
+           *remainp = remain;
+       }
+    }
+    return(retval);
+}
+
+static int unpack_int32(intp, bufpp, remainp)
+    prof_int32         *intp;
+    unsigned char      **bufpp;
+    size_t             *remainp;
+{
+    if (*remainp >= sizeof(prof_int32)) {
+       *intp = (((prof_int32) (*bufpp)[0] << 24) |
+                ((prof_int32) (*bufpp)[1] << 16) |
+                ((prof_int32) (*bufpp)[2] << 8) |
+                ((prof_int32) (*bufpp)[3]));
+       *bufpp += sizeof(prof_int32);
+       *remainp -= sizeof(prof_int32);
+       return 0;
+    }
+    else
+       return 1;
+}
+
+errcode_t profile_ser_internalize(unused, profilep, bufpp, remainp)
+    const char         *unused;
+    profile_t          *profilep;
+    unsigned char      **bufpp;
+    size_t             *remainp;
+{
+    errcode_t          retval;
+    unsigned char      *bp;
+    size_t             remain;
+    int                        i;
+    prof_int32         fcount, tmp;
+    char               **flist;
+
+    bp = *bufpp;
+    remain = *remainp;
+    retval = EINVAL;
+
+    if (remain >= 12)
+       (void) unpack_int32(&tmp, &bp, &remain);
+    else
+       tmp = 0;
+    if (tmp == PROF_MAGIC_PROFILE) {
+       (void) unpack_int32(&fcount, &bp, &remain);
+       retval = ENOMEM;
+       if (!fcount ||
+           (flist = (char **) malloc(sizeof(char *) * (fcount + 1)))) {
+           memset(flist, 0, sizeof(char *) * (fcount+1));
+           for (i=0; i<fcount; i++) {
+               if (!unpack_int32(&tmp, &bp, &remain)) {
+                   if ((flist[i] = (char *) malloc((size_t) (tmp+1)))) {
+                       memcpy(flist[i], bp, (size_t) tmp);
+                       flist[i][tmp] = '\0';
+                       bp += tmp;
+                       remain -= (size_t) tmp;
+                   }
+                   else
+                       break;
+               }
+               else
+                   break;
+           }
+           if ((i == fcount) &&
+               !unpack_int32(&tmp, &bp, &remain) &&
+               (tmp == PROF_MAGIC_PROFILE))
+               retval = profile_init((const char **)flist, profilep);
+
+           if (!retval) {
+               *bufpp = bp;
+               *remainp = remain;
+           }
+
+           for (i=0; i<fcount; i++) {
+               if (flist[i])
+                   free(flist[i]);
+           }
+           free(flist);
+       }
+    }
+    return(retval);
+}
+