#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;
*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);
+}
+