store.c

Go to the documentation of this file.
00001 /* Implementation of the Data Store. */
00002 
00003 #include "inc.h"
00004 
00005 /* Allocate space for the data store. */
00006 PRIVATE struct data_store ds_store[NR_DS_KEYS];
00007 PRIVATE int nr_in_use;
00008 
00009 PRIVATE _PROTOTYPE(int find_key, (int key, struct data_store **dsp));
00010 PRIVATE _PROTOTYPE(int set_owner, (struct data_store *dsp, void *auth_ptr));
00011 PRIVATE _PROTOTYPE(int is_authorized, (struct data_store *dsp, void *auth_ptr));
00012 
00013 
00014 PRIVATE int set_owner(dsp, ap)
00015 struct data_store *dsp;                         /* data store structure */
00016 void *ap;                                       /* authorization pointer */
00017 {
00018   /* Authorize the caller. */
00019   return(TRUE);
00020 }
00021 
00022 
00023 PRIVATE int is_authorized(dsp, ap)
00024 struct data_store *dsp;                         /* data store structure */
00025 void *ap;                                       /* authorization pointer */
00026 {
00027   /* Authorize the caller. */
00028   return(TRUE);
00029 }
00030 
00031 
00032 PRIVATE int find_key(key, dsp)
00033 int key;                                        /* key to look up */
00034 struct data_store **dsp;                        /* store pointer here */
00035 {
00036   register int i;
00037 
00038   *dsp = NULL;
00039   for (i=0; i<NR_DS_KEYS; i++) {
00040       if ((ds_store[i].ds_flags & DS_IN_USE) && ds_store[i].ds_key == key) {
00041           *dsp = &ds_store[i];
00042           return(TRUE);                         /* report success */
00043       }
00044   }
00045   return(FALSE);                                /* report not found */
00046 }
00047 
00048 
00049 PUBLIC int do_publish(m_ptr)
00050 message *m_ptr;                                 /* request message */
00051 {
00052   struct data_store *dsp;
00053 
00054   /* Store (key,value)-pair. First see if key already exists. If so, 
00055    * check if the caller is allowed to overwrite the value. Otherwise
00056    * find a new slot and store the new value. 
00057    */
00058   if (find_key(m_ptr->DS_KEY, &dsp)) {                  /* look up key */
00059       if (! is_authorized(dsp,m_ptr->DS_AUTH)) {        /* check if owner */
00060           return(EPERM);
00061       }
00062   } 
00063   else {                                                /* find a new slot */
00064       if (nr_in_use >= NR_DS_KEYS) {
00065           return(EAGAIN);                               /* store is full */
00066       } else {
00067           dsp = &ds_store[nr_in_use];                   /* new slot found */
00068           dsp->ds_key = m_ptr->DS_KEY;
00069           if (! set_owner(dsp,m_ptr->DS_AUTH)) {        /* associate owner */
00070               return(EINVAL);
00071           }
00072           dsp->ds_nr_subs = 0;                          /* nr of subscribers */
00073           dsp->ds_flags = DS_IN_USE;                    /* initialize slot */
00074           nr_in_use ++;
00075       }
00076   }
00077 
00078   /* At this point we have a data store pointer and know the caller is 
00079    * authorize to write to it. Set all fields as requested.
00080    */
00081   dsp->ds_val_l1 = m_ptr->DS_VAL_L1;            /* store all data */
00082   dsp->ds_val_l2 = m_ptr->DS_VAL_L2;    
00083 
00084   /* If the data is public. Check if there are any subscribers to this key. 
00085    * If so, notify all subscribers so that they can retrieve the data, if 
00086    * they're still interested.
00087    */
00088   if ((dsp->ds_flags & DS_PUBLIC) && dsp->ds_nr_subs > 0) {
00089 
00090       /* Subscriptions are not yet implemented. */
00091   }
00092 
00093   return(OK);
00094 }
00095 
00096 
00097 PUBLIC int do_retrieve(m_ptr)
00098 message *m_ptr;                                 /* request message */
00099 {
00100   struct data_store *dsp;
00101 
00102   /* Retrieve data. Look up the key in the data store. Return an error if it
00103    * is not found. If this data is private, only the owner may retrieve it.
00104    */ 
00105   if (find_key(m_ptr->DS_KEY, &dsp)) {                  /* look up key */
00106 
00107       /* If the data is not public, the caller must be authorized. */
00108       if (! dsp->ds_flags & DS_PUBLIC) {                /* check if private */
00109           if (! is_authorized(dsp,m_ptr->DS_AUTH)) {    /* authorize call */
00110               return(EPERM);                            /* not allowed */
00111           }
00112       }
00113 
00114       /* Data is public or the caller is authorized to retrieve it. */
00115       printf("DS retrieves data: key %d (found %d), l1 %u, l2 %u\n",
00116                 m_ptr->DS_KEY, dsp->ds_key, dsp->ds_val_l1, dsp->ds_val_l2);
00117       m_ptr->DS_VAL_L1 = dsp->ds_val_l1;                /* return value */
00118       m_ptr->DS_VAL_L2 = dsp->ds_val_l2;                /* return value */
00119       return(OK);                                       /* report success */
00120   }
00121   return(ESRCH);                                        /* key not found */
00122 }
00123 
00124 
00125 PUBLIC int do_subscribe(m_ptr)
00126 message *m_ptr;                                 /* request message */
00127 {
00128   /* Subscribe to a key of interest. Only existing and public keys can be
00129    * subscribed to. All updates to the key will cause a notification message
00130    * to be sent to the subscribed. On success, directly return a copy of the
00131    * data for the given key. 
00132    */
00133   return(ENOSYS);
00134 }
00135 
00136 
00137 /*===========================================================================*
00138  *                              do_getsysinfo                                *
00139  *===========================================================================*/
00140 PUBLIC int do_getsysinfo(m_ptr)
00141 message *m_ptr;
00142 {
00143   vir_bytes src_addr, dst_addr;
00144   int dst_proc;
00145   size_t len;
00146   int s;
00147 
00148   switch(m_ptr->m1_i1) {
00149   case SI_DATA_STORE:
00150         src_addr = (vir_bytes) ds_store;
00151         len = sizeof(struct data_store) * NR_DS_KEYS;
00152         break; 
00153   default:
00154         return(EINVAL);
00155   }
00156 
00157   dst_proc = m_ptr->m_source;
00158   dst_addr = (vir_bytes) m_ptr->m1_p1;
00159   if (OK != (s=sys_datacopy(SELF, src_addr, dst_proc, dst_addr, len)))
00160         return(s);
00161   return(OK);
00162 }
00163 

Generated on Fri Apr 14 22:56:46 2006 for minix by  doxygen 1.4.6