Logo Search packages:      
Sourcecode: ksh version File versions

msgblast.c

/***********************************************************************
*                                                                      *
*               This software is part of the ast package               *
*           Copyright (c) 1990-2007 AT&T Knowledge Ventures            *
*                      and is licensed under the                       *
*                  Common Public License, Version 1.0                  *
*                      by AT&T Knowledge Ventures                      *
*                                                                      *
*                A copy of the License is available at                 *
*            http://www.opensource.org/licenses/cpl1.0.txt             *
*         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         *
*                                                                      *
*              Information and Software Systems Research               *
*                            AT&T Research                             *
*                           Florham Park NJ                            *
*                                                                      *
*                 Glenn Fowler <gsf@research.att.com>                  *
*                                                                      *
***********************************************************************/
#pragma prototyped

/*
 * syscall message server side receipt
 */

#include "msglib.h"

/*
 * blast message from msg->data,msg->size into msg->argv
 */

ssize_t
msgblast(register Msg_call_t* msg)
{
      register long           n;
      register unsigned long  at;
      register Msg_arg_t*     ap;
      long              r;
      char*             b;
      char*             e;
      long*             np;
      Msg_file_t*       ip;
      struct dirent*          dp;
      struct statvfs*         fp;
      struct stat*            sp;
      char**                  vp = (char**)msg->value;

      b = msg->data + MSG_SIZE_SIZE;
      e = msg->data + msg->size;
      if ((msg->version = msggetu(&b, e)) != MSG_VERSION)
            return -1;
      msg->channel = msggetu(&b, e);
      msg->call = msggetu(&b, e);
      msg->stamp = msggetu(&b, e);
      if (msg->call & MSG_ACK)
      {
            msg->ack.addr = msggetu(&b, e);
            msg->ack.port = msggetu(&b, e);
      }
      at = msg->call >> MSG_ARG_CALL;
      if (msg->call & MSG_VALUE) switch (at & ((1 << MSG_ARG_TYPE) - 1))
      {
      case 0:
            break;
      case MSG_ARG_file:
            for (n = 0; n < sizeof(msg->ret.file) / sizeof(msg->ret.file.fid[0]); n++)
                  msg->ret.file.fid[n] = msggetu(&b, e);
            break;
      default:
            msg->ret.number = msggetu(&b, e);
            break;
      }
      ap = msg->argv;
      while (ap < msg->argv + elementsof(msg->argv))
      {
            switch ((at >>= MSG_ARG_TYPE) & ((1 << MSG_ARG_TYPE) - 1))
            {
            case MSG_ARG_array:
                  (ap++)->number = r = msggetu(&b, e);
                  (ap++)->array = np = (long*)vp;
                  while (r-- > 0)
                  {
                        n = msggetu(&b, e);
                        if (np < (((long*)&msg->value[sizeof(msg->value)]) - 1))
                              *np++ = n;
                        if (e - b >= n) b += n;
                  }
                  if (np < (((long*)&msg->value[sizeof(msg->value)]) - 1)) np++;
                  vp = (char**)np;
                  continue;
            case MSG_ARG_file:
                  (ap++)->file = ip = (Msg_file_t*)vp;
                  for (n = 0; n < sizeof(*ip) / sizeof(ip->fid[0]); n++)
                        ip->fid[n] = msggetu(&b, e);
                  vp = (char**)(((char*)ip) + sizeof(*ip));
                  continue;
            case MSG_ARG_input:
                  n = msggetu(&b, e);
                  (ap++)->pointer = b;
                  (ap++)->number = n;
                  if (e - b >= n) b += n;
                  at >>= MSG_ARG_TYPE;
                  continue;
            case MSG_ARG_number:
                  (ap++)->number = msggetu(&b, e);
                  continue;
            case MSG_ARG_output:
                  if (msg->call & MSG_VALUE) switch (MSG_CALL(msg->call))
                  {
                  case MSG_CALL(MSG_getdents):
                        (ap++)->pointer = (void*)(dp = (struct dirent*)vp);
                        while (n = msggetz(&b, e, dp->d_name, sizeof(dp->d_name)))
                        {
                              n--;
#if _mem_d_namlen_dirent
                              dp->d_namlen = n;
#endif
#if _mem_d_fileno_dirent
                              dp->d_fileno =
#endif
                              msggetu(&b, e);
#if _mem_d_off_dirent
                              dp->d_off = 0;
#endif
                              n = D_RECSIZ(dp, n);
#if _mem_d_reclen_dirent
                              dp->d_reclen = n;
#endif
                              dp = (struct dirent*)((char*)dp + n);
                        }
                        (ap++)->number = (char*)dp - (char*)vp;
                        msggetu(&b, e);
                        at >>= MSG_ARG_TYPE;
                        break;
                  case MSG_CALL(MSG_pipe):
                        (ap++)->file = ip = (Msg_file_t*)vp;
                        for (r = 0; r < 2; r++)
                        {
                              for (n = 0; n < sizeof(*ip) / sizeof(ip->fid[0]); n++)
                                    ip->fid[n] = msggetu(&b, e);
                              ip++;
                        }
                        vp = (char**)ip;
                        break;
                  case MSG_CALL(MSG_stat):
                        (ap++)->pointer = (void*)(sp = (struct stat*)vp);
                        sp->st_dev = msggetu(&b, e);
                        sp->st_ino = msggetu(&b, e);
                        sp->st_mode = msggetu(&b, e);
                        sp->st_nlink = msggetu(&b, e);
                        sp->st_uid = msggetu(&b, e);
                        sp->st_gid = msggetu(&b, e);
                        sp->st_size = msggetu(&b, e);
                        sp->st_atime = msggetu(&b, e);
                        sp->st_mtime = msggetu(&b, e);
                        sp->st_ctime = msggetu(&b, e);
#if _mem_st_blksize_stat
                        sp->st_blksize =
#endif
                              msggetu(&b, e);
#if _mem_st_blocks_stat
                        sp->st_blocks =
#endif
                              msggetu(&b, e);
                        break;
                  case MSG_CALL(MSG_statfs):
                        (ap++)->pointer = (void*)(fp = (struct statvfs*)vp);
                        fp->f_bsize = msggetu(&b, e);
                        fp->f_frsize = msggetu(&b, e);
                        fp->f_blocks = msggetu(&b, e);
                        fp->f_bfree = msggetu(&b, e);
                        fp->f_bavail = msggetu(&b, e);
                        fp->f_files = msggetu(&b, e);
                        fp->f_ffree = msggetu(&b, e);
                        fp->f_favail = msggetu(&b, e);
#if _mem_f_fsid_statvfs
                        fp->f_fsid =
#endif
                              msggetu(&b, e);
#if _mem_f_basetype_statvfs
                        msggetz(&b, e, fp->f_basetype, sizeof(fp->f_basetype));
#else
                        msggetz(&b, e, NiL, 0);
#endif
                        fp->f_flag = msggetu(&b, e);
                        fp->f_namemax = msggetu(&b, e);
#if _mem_f_fstr_statvfs
                        msggetz(&b, e, fp->f_fstr, sizeof(fp->f_fstr));
#endif
                        break;
                  default:
                        n = msggetu(&b, e);
                        (ap++)->pointer = (void*)b;
                        (ap++)->number = n;
                        at >>= MSG_ARG_TYPE;
                        if (e - b >= n) b += n;
                        break;
                  }
                  else (ap++)->pointer = 0;
                  continue;
            case MSG_ARG_string:
                  if (n = msggetu(&b, e))
                  {
                        (ap++)->string = b;
                        if (e - b >= n) b += n;
                  }
                  else (ap++)->string = 0;
                  continue;
            case MSG_ARG_vector:
                  (ap++)->vector = vp;
                  while (n = msggetu(&b, e))
                  {
                        if (vp < (((char**)&msg->value[sizeof(msg->value)]) - 1))
                              *vp++ = b;
                        if (e - b >= n) b += n;
                  }
                  *vp = 0;
                  if (vp < (((char**)&msg->value[sizeof(msg->value)]) - 1)) vp++;
                  continue;
            }
            break;
      }
      msg->argc = ap - msg->argv;
      return msg->size;
}

Generated by  Doxygen 1.6.0   Back to index