#include "dazuko_platform.h"
#include "dazuko_xp.h"
#include "dazukoio.h"
#include "dazuko_call.h"
Go to the source code of this file.
Data Structures | |
struct | path |
struct | daemon_id |
struct | slot |
struct | slot_list |
struct | slot_list_container |
struct | one_slot_state_not_condition_param |
struct | two_slot_state_not_condition_param |
struct | get_ready_slot_condition_param |
Defines | |
#define | NUM_SLOT_LISTS 5 |
#define | NUM_SLOTS 25 |
#define | SCAN_ON_OPEN (access_mask & DAZUKO_ON_OPEN) |
#define | SCAN_ON_CLOSE (access_mask & DAZUKO_ON_CLOSE) |
#define | SCAN_ON_EXEC (access_mask & DAZUKO_ON_EXEC) |
#define | SCAN_ON_CLOSE_MODIFIED (access_mask & DAZUKO_ON_CLOSE_MODIFIED) |
#define | DAZUKO_VSNPRINTF_PRINTSTRING |
#define | DAZUKO_VSNPRINT(type, name) dazuko_snprintf(request->reply_buffer + request->reply_buffer_size_used, (request->reply_buffer_size - request->reply_buffer_size_used) - 1, "%s%" #type , key, *((name *)value)) |
Functions | |
int | dazuko_vsnprintf (char *str, size_t size, const char *format, va_list ap) |
int | dazuko_snprintf (char *str, size_t size, const char *format,...) |
void | dazuko_bzero (void *p, int len) |
static int | dazuko_get_new_unique (void) |
static int | dazuko_slot_state (struct slot *s) |
static int | one_slot_state_not_condition (void *param) |
static int | two_slot_state_not_condition (void *param) |
static int | __dazuko_change_slot_state (struct slot *s, int from_state, int to_state) |
static int | dazuko_change_slot_state (struct slot *s, int from_state, int to_state, int release) |
static struct slot * | _dazuko_find_slot (struct daemon_id *did, int release, struct slot_list *sl) |
static struct slot * | dazuko_find_slot_and_slotlist (struct daemon_id *did, int release, struct slot_list *slist, struct slot_list **sl_result) |
static struct slot * | dazuko_find_slot (struct daemon_id *did, int release, struct slot_list *slist) |
static int | dazuko_insert_path_fs (struct path **list, char *fs_path, int fs_len) |
static void | dazuko_remove_all_hash (void) |
static void | dazuko_remove_all_paths (void) |
static int | _dazuko_unregister_daemon (struct daemon_id *did) |
int | dazuko_unregister_daemon (struct xp_daemon_id *xp_id) |
static int | dazuko_state_error (struct slot *s, int current_state) |
static int | dazuko_register_daemon (struct daemon_id *did, const char *reg_name, int string_length, int write_mode) |
static struct slot * | dazuko_get_an_access (struct daemon_id *did) |
static int | dazuko_return_access (struct daemon_id *did, int response, struct slot *s) |
static int | dazuko_isdigit (const char c) |
static long | dazuko_strtol (const char *string) |
static int | dazuko_strlen (const char *string) |
static const char * | dazuko_strchr (const char *haystack, char needle) |
static const char * | dazuko_strstr (const char *haystack, const char *needle) |
int | dazuko_get_value (const char *key, const char *string, char **value) |
static void | dazuko_clear_replybuffer (struct dazuko_request *request) |
static void | dazuko_close_replybuffer (struct dazuko_request *request) |
static void | dazuko_add_keyvalue_to_replybuffer (struct dazuko_request *request, const char *key, void *value, char vtype) |
static int | dazuko_printable (char c) |
static void | dazuko_add_esc_to_replybuffer (struct dazuko_request *request, const char *key, char **filename) |
static int | dazuko_set_option (struct daemon_id *did, int opt, void *param, int len) |
static int | dazuko_handle_request (struct dazuko_request *request, struct xp_daemon_id *xp_id) |
int | dazuko_handle_user_request (struct dazuko_request *user_request, struct xp_daemon_id *xp_id) |
int | dazuko_handle_user_request_compat12 (void *ptr, int cmd, struct xp_daemon_id *xp_id) |
static struct slot * | dazuko_get_and_hold_ready_slot (struct slot_list *sl) |
static int | get_ready_slot_condition (void *param) |
static int | dazuko_run_daemon_on_slotlist (int event, char *filename, int filenamelength, struct event_properties *event_p, struct file_properties *file_p, int prev_response, struct slot_list *sl) |
static int | dazuko_run_daemon (int event, char *filename, int filenamelength, struct event_properties *event_p, struct file_properties *file_p) |
int | dazuko_is_our_daemon (struct xp_daemon_id *xp_id) |
static int | dazuko_is_selected (struct dazuko_file_struct *kfs) |
static int | dazuko_add_hash (struct xp_file *file, char *filename, int len) |
static void | dazuko_mark_hash_dirty (struct xp_file *file) |
static struct hash * | dazuko_get_hash (struct xp_file *file) |
int | dazuko_get_filename_length (char *filename) |
static int | dazuko_should_scan (struct dazuko_file_struct *kfs) |
int | dazuko_sys_check (unsigned long event, int daemon_is_allowed, struct xp_daemon_id *xp_id) |
int | dazuko_sys_pre (unsigned long event, struct dazuko_file_struct *kfs, struct xp_file *file, struct event_properties *event_p) |
int | dazuko_sys_post (unsigned long event, struct dazuko_file_struct *kfs, struct xp_file *file, struct event_properties *event_p) |
int | dazuko_init (void) |
int | dazuko_exit (void) |
Variables | |
static int | unique_count = 1 |
static char | access_mask = 7 |
static struct slot_list_container | slot_lists [NUM_SLOT_LISTS] |
static struct path * | incl_paths = NULL |
static struct path * | excl_paths = NULL |
static struct hash * | hash = NULL |
static struct xp_rwlock | lock_hash |
static struct xp_rwlock | lock_lists |
static struct xp_atomic | active |
static struct xp_mutex | mutex_unique_count |
static struct xp_queue | wait_kernel_waiting_for_free_slot |
static struct xp_queue | wait_daemon_waiting_for_work |
static struct xp_queue | wait_kernel_waiting_while_daemon_works |
static struct xp_queue | wait_daemon_waiting_for_free |
|
|
|
Value: for ( ; *s ; s++) \ { \ if (target == end) \ { \ overflow = 1; \ goto dazuko_vsnprintf_out; \ } \ *target = *s; \ target++; \ } |
|
Definition at line 42 of file dazuko_xp.c. |
|
Definition at line 43 of file dazuko_xp.c. |
|
Definition at line 46 of file dazuko_xp.c. Referenced by dazuko_sys_check(), and dazuko_sys_post(). |
|
Definition at line 48 of file dazuko_xp.c. Referenced by dazuko_sys_check(), and dazuko_sys_post(). |
|
Definition at line 47 of file dazuko_xp.c. |
|
Definition at line 45 of file dazuko_xp.c. Referenced by dazuko_sys_check(), dazuko_sys_post(), and dazuko_sys_pre(). |
|
Definition at line 329 of file dazuko_xp.c. References call_xp_notify(), DAZUKO_FREE, and DAZUKO_READY. 00330 { 00331 /* Make a predicted state transition. We fail if it 00332 * is an unpredicted change. We can ALWAYS go to the 00333 * to_state if it is the same as from_state. Not SMP safe! */ 00334 00335 if (to_state != from_state) 00336 { 00337 /* make sure this is a predicted transition and there 00338 * is a daemon on this slot (unique != 0)*/ 00339 if (s->state != from_state || s->did.unique == 0) 00340 return 0; 00341 } 00342 00343 s->state = to_state; 00344 00345 /* handle appropriate wake_up's for basic 00346 * state changes */ 00347 00348 if (to_state == DAZUKO_READY) 00349 { 00350 call_xp_notify(&wait_kernel_waiting_for_free_slot); 00351 } 00352 else if (to_state == DAZUKO_FREE) 00353 { 00354 call_xp_notify(&wait_kernel_waiting_while_daemon_works); 00355 call_xp_notify(&wait_daemon_waiting_for_free); 00356 } 00357 00358 return 1; 00359 }
|
|
Definition at line 387 of file dazuko_xp.c. References call_xp_down(), call_xp_id_compare(), call_xp_print, call_xp_up(), slot::did, slot::mutex, NULL, NUM_SLOTS, slot_list::slots, daemon_id::unique, and daemon_id::xp_id. 00388 { 00389 /* Find the first slot with the same given 00390 * pid number. SMP safe. Use this function 00391 * with CAUTION, since the mutex may or may not 00392 * be released depending on the return value AND 00393 * on the value of the "release" argument. */ 00394 00395 int i; 00396 struct slot *s = NULL; 00397 00398 if (sl == NULL) 00399 { 00400 call_xp_print("dazuko: invalid slot_list given (bug!)\n"); 00401 return NULL; 00402 } 00403 00404 for (i=0 ; i<NUM_SLOTS ; i++) 00405 { 00406 s = &(sl->slots[i]); 00407 /* DOWN */ 00408 /* if we are interrupted, we say that no 00409 * slot was found */ 00410 if (call_xp_down(&(s->mutex)) != 0) 00411 return NULL; 00412 00413 if (did == NULL) 00414 { 00415 /* we are looking for an empty slot */ 00416 if (s->did.unique == 0 && s->did.xp_id == NULL) 00417 { 00418 /* we release the mutex only if the 00419 * called wanted us to */ 00420 if (release) 00421 call_xp_up(&(s->mutex)); 00422 /* UP */ 00423 return s; 00424 } 00425 } 00426 else if (s->did.unique == 0 && s->did.xp_id == NULL) 00427 { 00428 /* this slot is emtpy, so it can't match */ 00429 00430 /* do nothing */ 00431 } 00432 /* xp_id's must match! */ 00433 else if (call_xp_id_compare(s->did.xp_id, did->xp_id) == 0) 00434 { 00435 /* unique's must also match (unless unique is negative, 00436 * in which case we will trust xp_id) */ 00437 if (did->unique < 0 || (s->did.unique == did->unique)) 00438 { 00439 /* we release the mutex only if the 00440 * called wanted us to */ 00441 if (release) 00442 call_xp_up(&(s->mutex)); 00443 /* UP */ 00444 return s; 00445 } 00446 } 00447 00448 call_xp_up(&(s->mutex)); 00449 /* UP */ 00450 } 00451 00452 return NULL; 00453 }
|
|
Definition at line 632 of file dazuko_xp.c. References __dazuko_change_slot_state(), call_xp_atomic_dec(), call_xp_atomic_read(), call_xp_id_free(), call_xp_notify(), call_xp_print, call_xp_up(), dazuko_find_slot_and_slotlist(), DAZUKO_FREE, dazuko_remove_all_hash(), dazuko_remove_all_paths(), slot::did, DPRINT, slot::mutex, NULL, daemon_id::unique, slot_list::use_count, and daemon_id::xp_id. 00633 { 00634 /* We unregister the daemon by finding the 00635 * slot with the same slot->pid as the the 00636 * current process id, the daemon. */ 00637 00638 struct slot *s; 00639 struct slot_list *sl; 00640 00641 DPRINT(("dazuko: dazuko_unregister_daemon() [%d]\n", did->unique)); 00642 00643 /* find our slot and hold the mutex 00644 * if we find it */ 00645 /* DOWN? */ 00646 s = dazuko_find_slot_and_slotlist(did, 0, NULL, &sl); 00647 00648 if (s == NULL) 00649 { 00650 /* this daemon was not registered */ 00651 return 0; 00652 } 00653 00654 /* DOWN */ 00655 00656 /* clearing the unique and pid makes the slot available */ 00657 s->did.unique = 0; 00658 call_xp_id_free(s->did.xp_id); 00659 s->did.xp_id = NULL; 00660 00661 /* reset slot state */ 00662 __dazuko_change_slot_state(s, DAZUKO_FREE, DAZUKO_FREE); 00663 00664 call_xp_atomic_dec(&(sl->use_count)); 00665 00666 call_xp_up(&(s->mutex)); 00667 /* UP */ 00668 00669 /* active should always be positive here, but 00670 * let's check just to be sure. ;) */ 00671 if (call_xp_atomic_read(&active) > 0) 00672 { 00673 /* active and the kernel usage counter 00674 * should always reflect how many daemons 00675 * are active */ 00676 00677 call_xp_atomic_dec(&active); 00678 } 00679 else 00680 { 00681 call_xp_print("dazuko: active count error (possible bug)\n"); 00682 } 00683 00684 /* Wake up any kernel processes that are 00685 * waiting for an available slot. Remove 00686 * all the include and exclude paths 00687 * if there are no more daemons */ 00688 00689 if (call_xp_atomic_read(&active) == 0) 00690 { 00691 /* clear out include and exclude paths */ 00692 /* are we sure we want to do this? */ 00693 dazuko_remove_all_paths(); 00694 00695 /* clear out hash nodes */ 00696 dazuko_remove_all_hash(); 00697 } 00698 00699 call_xp_notify(&wait_kernel_waiting_for_free_slot); 00700 call_xp_notify(&wait_kernel_waiting_while_daemon_works); 00701 00702 return 0; 00703 }
|
|
Definition at line 1223 of file dazuko_xp.c. References dazuko_add_keyvalue_to_replybuffer(), dazuko_printable(), dazuko_snprintf(), dazuko_request::reply_buffer, dazuko_request::reply_buffer_size, and dazuko_request::reply_buffer_size_used. 01224 { 01225 int found = 0; 01226 char *p_rq; 01227 const char *limit; 01228 const char *p_fn; 01229 unsigned char c; 01230 01231 /* check for escape characters in filename */ 01232 for (p_fn=*filename ; *p_fn ; p_fn++) 01233 { 01234 if (!dazuko_printable(*p_fn)) 01235 { 01236 found = 1; 01237 break; 01238 } 01239 } 01240 01241 if (found) 01242 { 01243 /* this is expensive, but it will also almost never occur */ 01244 01245 p_rq = request->reply_buffer + request->reply_buffer_size_used; 01246 limit = request->reply_buffer + request->reply_buffer_size - 1; 01247 01248 dazuko_snprintf(p_rq, limit - p_rq, "%s", key); 01249 p_rq += strlen(p_rq); 01250 01251 for (p_fn=*filename ; *p_fn && (p_rq<limit) ; p_fn++) 01252 { 01253 if (dazuko_printable(*p_fn)) 01254 { 01255 *p_rq = *p_fn; 01256 p_rq++; 01257 } 01258 else 01259 { 01260 c = *p_fn & 0xFF; 01261 dazuko_snprintf(p_rq, limit - p_rq, "\\x%02x", c); 01262 p_rq += strlen(p_rq); 01263 } 01264 } 01265 01266 request->reply_buffer_size_used += strlen(request->reply_buffer + request->reply_buffer_size_used); 01267 } 01268 else 01269 { 01270 /* no escape characters found */ 01271 01272 dazuko_add_keyvalue_to_replybuffer(request, key, filename, 's'); 01273 } 01274 }
|
|
Definition at line 2341 of file dazuko_xp.c. References call_xp_copy_file(), call_xp_malloc(), call_xp_write_lock(), call_xp_write_unlock(), hash::dirty, hash::file, hash::name, hash::namelen, hash::next, NULL, and XP_ERROR_FAULT. Referenced by dazuko_sys_post(). 02342 { 02343 /* Add the given file and filename to the linked list 02344 * of files to scan once they are closed. */ 02345 02346 struct hash *h; 02347 02348 /* create a new struct hash structure making room for name also */ 02349 h = (struct hash *)call_xp_malloc(sizeof(struct hash) + len); 02350 if (h == NULL) 02351 return XP_ERROR_FAULT; 02352 02353 /* fill in structure items */ 02354 02355 call_xp_copy_file(&(h->file), file); 02356 h->dirty = 0; 02357 h->namelen = len; 02358 memcpy(h->name, filename, len); 02359 h->name[len] = 0; 02360 02361 /* add the new struct hash item to the head of the 02362 * struct hash linked list */ 02363 02364 /* LOCK */ 02365 call_xp_write_lock(&lock_hash); 02366 h->next = hash; 02367 hash = h; 02368 call_xp_write_unlock(&lock_hash); 02369 /* UNLOCK */ 02370 return 0; 02371 }
|
|
Definition at line 1187 of file dazuko_xp.c. References DAZUKO_VSNPRINT, dazuko_request::reply_buffer, and dazuko_request::reply_buffer_size_used. 01188 { 01189 01190 #define DAZUKO_VSNPRINT(type, name) dazuko_snprintf(request->reply_buffer + request->reply_buffer_size_used, (request->reply_buffer_size - request->reply_buffer_size_used) - 1, "%s%" #type , key, *((name *)value)) 01191 01192 switch (vtype) 01193 { 01194 case 'd': 01195 DAZUKO_VSNPRINT(d, const int); 01196 break; 01197 01198 case 's': 01199 DAZUKO_VSNPRINT(s, const char *); 01200 break; 01201 01202 case 'l': 01203 DAZUKO_VSNPRINT(lu, const unsigned long); 01204 break; 01205 01206 default: 01207 /* all other types treated as chars */ 01208 DAZUKO_VSNPRINT(c, const char); 01209 break; 01210 } 01211 01212 /* update how much buffer we have used */ 01213 request->reply_buffer_size_used += strlen(request->reply_buffer + request->reply_buffer_size_used); 01214 }
|
|
Definition at line 273 of file dazuko_xp.c. 00274 { 00275 /* "zero out" len bytes starting with p */ 00276 00277 char *ptr = (char *)p; 00278 00279 while (len--) 00280 *ptr++ = 0; 00281 }
|
|
Definition at line 361 of file dazuko_xp.c. References __dazuko_change_slot_state(), call_xp_down(), call_xp_up(), and slot::mutex. 00362 { 00363 /* SMP safe version of __dazuko_change_slot_state(). 00364 * This should only be used if we haven't 00365 * already aquired slot.mutex. Use this function 00366 * with CAUTION, since the mutex may or may not 00367 * be released depending on the return value AND 00368 * on the value of the "release" argument. */ 00369 00370 int success; 00371 00372 /* if we are interrupted, report the state as unpredicted */ 00373 /* DOWN */ 00374 if (call_xp_down(&(s->mutex)) != 0) 00375 return 0; 00376 00377 success = __dazuko_change_slot_state(s, from_state, to_state); 00378 00379 /* the mutex is released if the state change was 00380 * unpredicted or if the called wants it released */ 00381 if (!success || release) 00382 call_xp_up(&(s->mutex)); 00383 /* UP */ 00384 return success; 00385 }
|
|
Definition at line 1175 of file dazuko_xp.c. References dazuko_bzero(), dazuko_request::reply_buffer, dazuko_request::reply_buffer_size, and dazuko_request::reply_buffer_size_used. 01176 { 01177 dazuko_bzero(request->reply_buffer, request->reply_buffer_size); 01178 request->reply_buffer_size_used = 0; 01179 }
|
|
Definition at line 1181 of file dazuko_xp.c. References dazuko_request::reply_buffer, and dazuko_request::reply_buffer_size_used. 01182 { 01183 request->reply_buffer[request->reply_buffer_size_used] = 0; 01184 request->reply_buffer_size_used++; 01185 }
|
|
|
Definition at line 498 of file dazuko_xp.c. References dazuko_find_slot_and_slotlist(), and NULL. 00499 { 00500 return dazuko_find_slot_and_slotlist(did, release, slist, NULL); 00501 }
|
|
Definition at line 455 of file dazuko_xp.c. References _dazuko_find_slot(), call_xp_down(), call_xp_up(), NULL, and slot_list_container::slot_list. 00456 { 00457 struct slot *s; 00458 int i; 00459 struct slot_list *sl; 00460 00461 if (slist == NULL) 00462 { 00463 for (i=0 ; i<NUM_SLOT_LISTS ; i++) 00464 { 00465 /* DOWN */ 00466 /* if we are interrupted, we say that no 00467 * slot was found */ 00468 if (call_xp_down(&(slot_lists[i].mutex)) != 0) 00469 return NULL; 00470 00471 sl = slot_lists[i].slot_list; 00472 00473 call_xp_up(&(slot_lists[i].mutex)); 00474 /* UP */ 00475 00476 if (sl != NULL) 00477 { 00478 s = _dazuko_find_slot(did, release, sl); 00479 if (s != NULL) 00480 { 00481 /* set the current slot_list */ 00482 if (sl_result != NULL) 00483 *sl_result = sl; 00484 00485 return s; 00486 } 00487 } 00488 } 00489 } 00490 else 00491 { 00492 return _dazuko_find_slot(did, release, slist); 00493 } 00494 00495 return NULL; 00496 }
|
|
Definition at line 894 of file dazuko_xp.c. References call_xp_notify(), call_xp_print, call_xp_wait_until_condition(), DAZUKO_BROKEN, dazuko_change_slot_state(), dazuko_find_slot(), DAZUKO_READY, dazuko_register_daemon(), DAZUKO_WAITING, DAZUKO_WORKING, DPRINT, NULL, one_slot_state_not_condition(), one_slot_state_not_condition_param::slot, one_slot_state_not_condition_param::state, and daemon_id::unique. 00895 { 00896 /* The daemon is requesting a filename of a file 00897 * to scan. This code will wait until a filename 00898 * is available, or until we should be killed. 00899 * (killing is done if any errors occur as well 00900 * as when the user kills us) */ 00901 00902 /* If a slot is returned, it will be already locked! */ 00903 00904 int i; 00905 struct slot *s; 00906 struct one_slot_state_not_condition_param cond_p; 00907 00908 tryagain: 00909 /* find our slot */ 00910 s = dazuko_find_slot(did, 1, NULL); 00911 00912 if (s == NULL) 00913 { 00914 i = dazuko_register_daemon(did, "_COMPAT", 7, 1); 00915 if (i != 0) 00916 { 00917 call_xp_print("dazuko: unregistered daemon %d attempted to get access\n", did->unique); 00918 return NULL; 00919 } 00920 00921 s = dazuko_find_slot(did, 1, NULL); 00922 if (s == NULL) 00923 { 00924 call_xp_print("dazuko: unregistered daemon %d attempted to get access\n", did->unique); 00925 return NULL; 00926 } 00927 00928 call_xp_print("dazuko: warning: daemon %d is using a deprecated protocol\n", did->unique); 00929 } 00930 00931 /* the daemon is now ready to receive a file */ 00932 dazuko_change_slot_state(s, DAZUKO_READY, DAZUKO_READY, 1); 00933 00934 cond_p.slot = s; 00935 cond_p.state = DAZUKO_READY; 00936 if (call_xp_wait_until_condition(&wait_daemon_waiting_for_work, one_slot_state_not_condition, &cond_p, 1) != 0) 00937 { 00938 /* The user has issued an interrupt. 00939 * Return an error. The daemon should 00940 * unregister itself. */ 00941 00942 DPRINT(("dazuko: daemon %d killed while waiting for work\n", did->unique)); 00943 00944 if (dazuko_change_slot_state(s, DAZUKO_READY, DAZUKO_BROKEN, 1) || dazuko_change_slot_state(s, DAZUKO_WAITING, DAZUKO_BROKEN, 1)) 00945 { 00946 call_xp_notify(&wait_kernel_waiting_for_free_slot); 00947 call_xp_notify(&wait_kernel_waiting_while_daemon_works); 00948 } 00949 00950 return NULL; 00951 } 00952 00953 /* slot SHOULD now be in DAZUKO_WAITING state */ 00954 00955 /* we will be working with the slot, so 00956 * we need to lock it */ 00957 00958 /* DOWN? */ 00959 if (!dazuko_change_slot_state(s, DAZUKO_WAITING, DAZUKO_WORKING, 0)) 00960 { 00961 /* State transition error. Try again., */ 00962 00963 goto tryagain; 00964 } 00965 00966 /* DOWN */ 00967 00968 /* Slot IS in DAZUKO_WORKING state. Copy all the 00969 * necessary information to userspace structure. */ 00970 00971 /* IMPORTANT: slot is still locked! */ 00972 00973 return s; /* access is available */ 00974 }
|
|
Definition at line 1991 of file dazuko_xp.c. References dazuko_change_slot_state(), DAZUKO_READY, DAZUKO_WAITING, NULL, NUM_SLOTS, and slot_list::slots. 01992 { 01993 /* This is a simple search to find a 01994 * slot whose state is DAZUKO_READY. This means 01995 * it is able to accept work. If a slot 01996 * is found, the slot.mutex is held so 01997 * it can be filled with work by the caller. 01998 * It is the responsibility of the caller 01999 * to RELEASE THE MUTEX. */ 02000 02001 int i; 02002 struct slot *s; 02003 02004 for (i=0 ; i<NUM_SLOTS ; i++) 02005 { 02006 s = &(sl->slots[i]); 02007 /* DOWN? */ 02008 if (dazuko_change_slot_state(s, DAZUKO_READY, DAZUKO_WAITING, 0)) 02009 { 02010 /* DOWN */ 02011 return s; 02012 } 02013 } 02014 02015 /* we didn't find a slot that is ready for work */ 02016 02017 return NULL; 02018 }
|
|
Definition at line 2499 of file dazuko_xp.c. 02500 { 02501 int len; 02502 02503 for (len=0 ; filename[len] ; len++); 02504 02505 return len; 02506 }
|
|
Definition at line 2461 of file dazuko_xp.c. References call_xp_compare_file(), call_xp_write_lock(), call_xp_write_unlock(), hash::file, hash::next, and NULL. Referenced by dazuko_sys_post(). 02462 { 02463 /* Find the given file within our list 02464 * and then remove it from the list and 02465 * return it. */ 02466 02467 struct hash *prev; 02468 struct hash *cur; 02469 02470 /* LOCK */ 02471 call_xp_write_lock(&lock_hash); 02472 02473 prev = NULL; 02474 cur = hash; 02475 while (cur) 02476 { 02477 if (call_xp_compare_file(&(cur->file), file) == 0) 02478 { 02479 /* we found the entry */ 02480 02481 /* remove the item from the list */ 02482 if (!prev) 02483 hash = cur->next; 02484 else 02485 prev->next = cur->next; 02486 break; 02487 } 02488 02489 prev = cur; 02490 cur = cur->next; 02491 } 02492 02493 call_xp_write_unlock(&lock_hash); 02494 /* UNLOCK */ 02495 02496 return cur; 02497 }
|
|
Definition at line 283 of file dazuko_xp.c. References call_xp_down(), call_xp_up(), and unique_count. 00284 { 00285 int unique; 00286 00287 /* DOWN */ 00288 call_xp_down(&mutex_unique_count); 00289 00290 unique = unique_count; 00291 unique_count++; 00292 00293 call_xp_up(&mutex_unique_count); 00294 /* UP */ 00295 00296 return unique; 00297 }
|
|
Definition at line 1141 of file dazuko_xp.c. References call_xp_malloc(), dazuko_strlen(), dazuko_strstr(), and NULL. 01142 { 01143 const char *p1; 01144 const char *p2; 01145 int size; 01146 01147 if (value == NULL) 01148 return -1; 01149 01150 *value = NULL; 01151 01152 if (key == NULL || string == NULL) 01153 return -1; 01154 01155 p1 = dazuko_strstr(string, key); 01156 if (p1 == NULL) 01157 return -1; 01158 01159 p1 += dazuko_strlen(key); 01160 01161 for (p2=p1 ; *p2 && *p2!='\n' ; p2++) 01162 continue; 01163 01164 size = (p2 - p1) + 1; 01165 *value = call_xp_malloc(size); 01166 if (*value == NULL) 01167 return -1; 01168 01169 memcpy(*value, p1, size - 1); 01170 (*value)[size - 1] = 0; 01171 01172 return 0; 01173 }
|
|
Definition at line 1368 of file dazuko_xp.c. References access_mask, ADD_EXCLUDE_PATH, ADD_INCLUDE_PATH, dazuko_request::buffer, dazuko_request::buffer_size, call_xp_free(), call_xp_id_copy(), call_xp_id_free(), call_xp_print, call_xp_up(), dazuko_add_esc_to_replybuffer(), dazuko_add_keyvalue_to_replybuffer(), dazuko_clear_replybuffer(), dazuko_close_replybuffer(), dazuko_get_an_access(), dazuko_get_value(), dazuko_register_daemon(), dazuko_return_access(), dazuko_set_option(), dazuko_strchr(), dazuko_strlen(), dazuko_strtol(), file_properties::device_type, slot::event, slot::event_p, slot::file_p, slot::filename, event_properties::flags, GET_AN_ACCESS, file_properties::gid, file_properties::mode, event_properties::mode, slot::mutex, NULL, event_properties::pid, REGISTER, REMOVE_ALL_PATHS, dazuko_request::reply_buffer_size, RETURN_AN_ACCESS, SET_ACCESS_MASK, file_properties::set_device_type, event_properties::set_flags, file_properties::set_gid, file_properties::set_mode, event_properties::set_mode, event_properties::set_pid, file_properties::set_size, file_properties::set_uid, event_properties::set_uid, file_properties::size, dazuko_request::type, file_properties::uid, event_properties::uid, daemon_id::unique, UNREGISTER, slot::write_mode, XP_ERROR_INTERRUPT, and daemon_id::xp_id. 01369 { 01370 char *value1; 01371 char *value2; 01372 int error = 0; 01373 int type; 01374 struct slot *s; 01375 struct daemon_id did; 01376 01377 if (request == NULL || xp_id == NULL) 01378 return -1; 01379 01380 type = request->type[0] + (256 * request->type[1]); 01381 01382 switch (type) 01383 { 01384 case REGISTER: 01385 /* read "\nRM=regmode\nGN=group" */ 01386 /* send "\nID=id" */ 01387 01388 if (request->buffer_size <= 0) 01389 return -1; 01390 01391 if (request->reply_buffer_size <= 0) 01392 return -1; 01393 01394 if (dazuko_get_value("\nGN=", request->buffer, &value1) != 0) 01395 return -1; 01396 01397 if (dazuko_get_value("\nRM=", request->buffer, &value2) != 0) 01398 { 01399 call_xp_free(value1); 01400 return -1; 01401 } 01402 01403 did.xp_id = call_xp_id_copy(xp_id); 01404 did.unique = 0; /* a unique is not yet assigned */ 01405 01406 error = dazuko_register_daemon(&did, value1, dazuko_strlen(value1), dazuko_strchr(value2, 'W') != NULL); 01407 01408 dazuko_clear_replybuffer(request); 01409 dazuko_add_keyvalue_to_replybuffer(request, "\nID=", &(did.unique), 'd'); 01410 dazuko_close_replybuffer(request); 01411 01412 call_xp_free(value1); 01413 call_xp_free(value2); 01414 call_xp_id_free(did.xp_id); 01415 01416 break; 01417 01418 case UNREGISTER: 01419 /* read "\nID=id" */ 01420 01421 if (request->buffer_size <= 0) 01422 return -1; 01423 01424 if (dazuko_get_value("\nID=", request->buffer, &value1) != 0) 01425 return -1; 01426 01427 did.xp_id = call_xp_id_copy(xp_id); 01428 did.unique = dazuko_strtol(value1); 01429 01430 error = dazuko_set_option(&did, UNREGISTER, NULL, 0); 01431 01432 call_xp_free(value1); 01433 call_xp_id_free(did.xp_id); 01434 01435 break; 01436 01437 case SET_ACCESS_MASK: 01438 /* read "\nID=id\nAM=mask" */ 01439 01440 if (request->buffer_size <= 0) 01441 return -1; 01442 01443 if (dazuko_get_value("\nID=", request->buffer, &value1) != 0) 01444 return -1; 01445 01446 if (dazuko_get_value("\nAM=", request->buffer, &value2) != 0) 01447 { 01448 call_xp_free(value1); 01449 return -1; 01450 } 01451 01452 access_mask = (char)dazuko_strtol(value2); 01453 01454 call_xp_free(value1); 01455 call_xp_free(value2); 01456 01457 break; 01458 01459 case ADD_INCLUDE_PATH: 01460 /* read "\nID=id\nPT=path" */ 01461 01462 if (request->buffer_size <= 0) 01463 return -1; 01464 01465 if (dazuko_get_value("\nID=", request->buffer, &value1) != 0) 01466 return -1; 01467 01468 if (dazuko_get_value("\nPT=", request->buffer, &value2) != 0) 01469 { 01470 call_xp_free(value1); 01471 return -1; 01472 } 01473 01474 did.xp_id = call_xp_id_copy(xp_id); 01475 did.unique = dazuko_strtol(value1); 01476 01477 error = dazuko_set_option(&did, ADD_INCLUDE_PATH, value2, dazuko_strlen(value2)); 01478 01479 call_xp_free(value1); 01480 call_xp_free(value2); 01481 call_xp_id_free(did.xp_id); 01482 01483 break; 01484 01485 case ADD_EXCLUDE_PATH: 01486 /* read "\nID=id\nPT=path" */ 01487 01488 if (request->buffer_size <= 0) 01489 return -1; 01490 01491 if (dazuko_get_value("\nID=", request->buffer, &value1) != 0) 01492 return -1; 01493 01494 if (dazuko_get_value("\nPT=", request->buffer, &value2) != 0) 01495 { 01496 call_xp_free(value1); 01497 return -1; 01498 } 01499 01500 did.xp_id = call_xp_id_copy(xp_id); 01501 did.unique = dazuko_strtol(value1); 01502 01503 error = dazuko_set_option(&did, ADD_EXCLUDE_PATH, value2, dazuko_strlen(value2)); 01504 01505 call_xp_free(value1); 01506 call_xp_free(value2); 01507 call_xp_id_free(did.xp_id); 01508 01509 break; 01510 01511 case REMOVE_ALL_PATHS: 01512 /* read "\nID=id" */ 01513 01514 if (request->buffer_size <= 0) 01515 return -1; 01516 01517 if (dazuko_get_value("\nID=", request->buffer, &value1) != 0) 01518 return -1; 01519 01520 did.xp_id = call_xp_id_copy(xp_id); 01521 did.unique = dazuko_strtol(value1); 01522 01523 error = dazuko_set_option(&did, REMOVE_ALL_PATHS, NULL, 0); 01524 01525 call_xp_free(value1); 01526 call_xp_id_free(did.xp_id); 01527 01528 break; 01529 01530 case GET_AN_ACCESS: 01531 /* read "\nID=id" */ 01532 /* send "\nFN=file\nFL=flags\nMD=mode\nUI=uid\nPI=pid" */ 01533 01534 if (request->buffer_size <= 0) 01535 return -1; 01536 01537 if (request->reply_buffer_size <= 0) 01538 return -1; 01539 01540 if (dazuko_get_value("\nID=", request->buffer, &value1) != 0) 01541 return -1; 01542 01543 did.xp_id = call_xp_id_copy(xp_id); 01544 did.unique = dazuko_strtol(value1); 01545 01546 call_xp_free(value1); 01547 01548 /* DOWN? */ 01549 s = dazuko_get_an_access(&did); 01550 01551 if (s == NULL) 01552 { 01553 call_xp_id_free(did.xp_id); 01554 return XP_ERROR_INTERRUPT; 01555 } 01556 /* DOWN */ 01557 01558 /* Slot IS in DAZUKO_WORKING state. Copy all the 01559 * necessary information to userspace structure. */ 01560 01561 dazuko_clear_replybuffer(request); 01562 dazuko_add_keyvalue_to_replybuffer(request, "\nEV=", &(s->event), 'd'); 01563 dazuko_add_esc_to_replybuffer(request, "\nFN=", &(s->filename)); 01564 01565 if (s->event_p.set_uid) 01566 dazuko_add_keyvalue_to_replybuffer(request, "\nUI=", &(s->event_p.uid), 'd'); 01567 01568 if (s->event_p.set_pid) 01569 dazuko_add_keyvalue_to_replybuffer(request, "\nPI=", &(s->event_p.pid), 'd'); 01570 01571 if (s->event_p.set_flags) 01572 dazuko_add_keyvalue_to_replybuffer(request, "\nFL=", &(s->event_p.flags), 'd'); 01573 01574 if (s->event_p.set_mode) 01575 dazuko_add_keyvalue_to_replybuffer(request, "\nMD=", &(s->event_p.mode), 'd'); 01576 01577 if (s->file_p.set_size) 01578 dazuko_add_keyvalue_to_replybuffer(request, "\nFS=", &(s->file_p.size), 'l'); 01579 01580 if (s->file_p.set_uid) 01581 dazuko_add_keyvalue_to_replybuffer(request, "\nFU=", &(s->file_p.uid), 'd'); 01582 01583 if (s->file_p.set_gid) 01584 dazuko_add_keyvalue_to_replybuffer(request, "\nFG=", &(s->file_p.gid), 'd'); 01585 01586 if (s->file_p.set_mode) 01587 dazuko_add_keyvalue_to_replybuffer(request, "\nFM=", &(s->file_p.mode), 'd'); 01588 01589 if (s->file_p.set_device_type) 01590 dazuko_add_keyvalue_to_replybuffer(request, "\nDT=", &(s->file_p.device_type), 'd'); 01591 01592 dazuko_close_replybuffer(request); 01593 01594 /* XXX: What do we do if there is a problem copying back to userspace?! */ 01595 /* dazuko_state_error(s, DAZUKO_WORKING); */ 01596 01597 /* are we in read_only mode? */ 01598 if (!(s->write_mode)) 01599 { 01600 /* the access is immediately (and at the kernel level) 01601 * returned */ 01602 01603 call_xp_up(&(s->mutex)); 01604 /* UP */ 01605 01606 dazuko_return_access(&did, 0, s); 01607 } 01608 else 01609 { 01610 call_xp_up(&(s->mutex)); 01611 /* UP */ 01612 } 01613 01614 call_xp_id_free(did.xp_id); 01615 01616 break; 01617 01618 case RETURN_AN_ACCESS: 01619 /* read "\nID=id\nDN=deny" */ 01620 01621 if (request->buffer_size <= 0) 01622 return -1; 01623 01624 if (dazuko_get_value("\nID=", request->buffer, &value1) != 0) 01625 return -1; 01626 01627 if (dazuko_get_value("\nDN=", request->buffer, &value2) != 0) 01628 { 01629 call_xp_free(value1); 01630 return -1; 01631 } 01632 01633 did.xp_id = call_xp_id_copy(xp_id); 01634 did.unique = dazuko_strtol(value1); 01635 01636 error = dazuko_return_access(&did, dazuko_strtol(value2), NULL); 01637 01638 call_xp_free(value1); 01639 call_xp_free(value2); 01640 call_xp_id_free(did.xp_id); 01641 01642 break; 01643 01644 default: 01645 call_xp_print("dazuko: daemon made unknown request %d (possible bug)\n", type); 01646 01647 break; 01648 } 01649 01650 return error; 01651 }
|
|
Definition at line 1653 of file dazuko_xp.c. References dazuko_request::buffer, dazuko_request::buffer_size, call_xp_copyin(), call_xp_copyout(), call_xp_free(), call_xp_malloc(), dazuko_handle_request(), NULL, dazuko_request::reply_buffer, dazuko_request::reply_buffer_size, dazuko_request::reply_buffer_size_used, dazuko_request::type, XP_ERROR_FAULT, and XP_ERROR_PERMISSION. 01654 { 01655 int error = 0; 01656 struct dazuko_request *request; 01657 struct dazuko_request *temp_request; 01658 01659 if (user_request == NULL || xp_id == NULL) 01660 return XP_ERROR_FAULT; 01661 01662 /* allocate kernel request */ 01663 request = (struct dazuko_request *)call_xp_malloc(sizeof(struct dazuko_request)); 01664 if (request == NULL) 01665 return XP_ERROR_FAULT; 01666 01667 /* use out0 now */ 01668 01669 /* allocate temp kernel request */ 01670 temp_request = (struct dazuko_request *)call_xp_malloc(sizeof(struct dazuko_request)); 01671 if (temp_request == NULL) 01672 { 01673 error = XP_ERROR_FAULT; 01674 goto dazuko_handle_user_request_out0; 01675 } 01676 01677 /* use out1 now */ 01678 01679 /* copy in the request */ 01680 if (call_xp_copyin(user_request, temp_request, sizeof(struct dazuko_request)) != 0) 01681 { 01682 error = XP_ERROR_FAULT; 01683 goto dazuko_handle_user_request_out1; 01684 } 01685 01686 memcpy(request->type, temp_request->type, sizeof(char[2])); 01687 request->buffer_size = temp_request->buffer_size; 01688 01689 /* sanity check */ 01690 if (request->buffer_size < 0 || request->buffer_size > 8192) 01691 { 01692 error = XP_ERROR_FAULT; 01693 goto dazuko_handle_user_request_out1; 01694 } 01695 01696 request->reply_buffer_size = temp_request->reply_buffer_size; 01697 01698 /* sanity check */ 01699 if (request->reply_buffer_size < 0 || request->reply_buffer_size > 8192) 01700 { 01701 error = XP_ERROR_PERMISSION; 01702 goto dazuko_handle_user_request_out1; 01703 } 01704 01705 /* allocate buffer */ 01706 request->buffer = (char *)call_xp_malloc(request->buffer_size + 1); 01707 if (request->buffer == NULL) 01708 { 01709 error = XP_ERROR_FAULT; 01710 goto dazuko_handle_user_request_out1; 01711 } 01712 01713 /* use out2 now */ 01714 01715 if (request->reply_buffer_size > 0) 01716 { 01717 /* allocate reply buffer */ 01718 request->reply_buffer = (char *)call_xp_malloc(request->reply_buffer_size + 1); 01719 if (request->reply_buffer == NULL) 01720 { 01721 error = XP_ERROR_FAULT; 01722 goto dazuko_handle_user_request_out2; 01723 } 01724 01725 /* use out3 now */ 01726 01727 request->reply_buffer_size_used = 0; 01728 } 01729 01730 /* copy the buffer from userspace to kernelspace */ 01731 if (call_xp_copyin(temp_request->buffer, request->buffer, request->buffer_size) != 0) 01732 { 01733 error = XP_ERROR_FAULT; 01734 goto dazuko_handle_user_request_out3; 01735 } 01736 01737 request->buffer[request->buffer_size] = 0; 01738 01739 error = dazuko_handle_request(request, xp_id); 01740 01741 if (error == 0 && request->reply_buffer_size > 0) 01742 { 01743 request->reply_buffer[request->reply_buffer_size] = 0; 01744 01745 temp_request->reply_buffer_size_used = request->reply_buffer_size_used; 01746 01747 if (call_xp_copyout(temp_request, user_request, sizeof(struct dazuko_request)) != 0) 01748 { 01749 error = XP_ERROR_FAULT; 01750 goto dazuko_handle_user_request_out3; 01751 } 01752 01753 if (request->reply_buffer_size_used > 0) 01754 { 01755 if (call_xp_copyout(request->reply_buffer, temp_request->reply_buffer, request->reply_buffer_size_used) != 0) 01756 { 01757 error = XP_ERROR_FAULT; 01758 goto dazuko_handle_user_request_out3; 01759 } 01760 } 01761 } 01762 01763 dazuko_handle_user_request_out3: 01764 if (request->reply_buffer_size > 0) 01765 call_xp_free(request->reply_buffer); 01766 dazuko_handle_user_request_out2: 01767 call_xp_free(request->buffer); 01768 dazuko_handle_user_request_out1: 01769 call_xp_free(temp_request); 01770 dazuko_handle_user_request_out0: 01771 call_xp_free(request); 01772 01773 return error; 01774 }
|
|
Definition at line 1776 of file dazuko_xp.c. References call_xp_copyin(), call_xp_copyout(), call_xp_free(), call_xp_id_copy(), call_xp_id_free(), call_xp_malloc(), call_xp_print, call_xp_up(), call_xp_verify_user_readable(), call_xp_verify_user_writable(), DAZUKO_FILENAME_MAX_LENGTH_COMPAT12, dazuko_get_an_access(), dazuko_register_daemon(), dazuko_return_access(), dazuko_set_option(), dazuko_state_error(), DAZUKO_WORKING, access_compat12::deny, access_compat12::event, slot::event, slot::event_p, slot::filename, access_compat12::filename, slot::filenamelength, event_properties::flags, IOCTL_GET_AN_ACCESS, IOCTL_RETURN_ACCESS, IOCTL_SET_OPTION, event_properties::mode, slot::mutex, NULL, access_compat12::o_flags, access_compat12::o_mode, access_compat12::pid, event_properties::pid, REGISTER, access_compat12::uid, event_properties::uid, daemon_id::unique, XP_ERROR_FAULT, XP_ERROR_INTERRUPT, XP_ERROR_INVALID, and daemon_id::xp_id. Referenced by linux_dazuko_device_ioctl(). 01777 { 01778 struct access_compat12 *user_request12; 01779 struct access_compat12 *temp_request12; 01780 int error = 0; 01781 struct slot *s; 01782 char *k_param; 01783 struct daemon_id did; 01784 int temp_length; 01785 int temp_int; 01786 01787 if (ptr == NULL || xp_id == NULL) 01788 return XP_ERROR_FAULT; 01789 01790 did.xp_id = call_xp_id_copy(xp_id); 01791 did.unique = -1; 01792 01793 switch (cmd) 01794 { 01795 case IOCTL_GET_AN_ACCESS: 01796 /* The daemon is requesting a filename of a file 01797 * to scan. This code will wait until a filename 01798 * is available, or until we should be killed. 01799 * (killing is done if any errors occur as well 01800 * as when the user kills us) */ 01801 01802 user_request12 = (struct access_compat12 *)ptr; 01803 01804 error = call_xp_verify_user_writable(user_request12, sizeof(struct access_compat12)); 01805 if (error) 01806 { 01807 error = XP_ERROR_FAULT; 01808 break; 01809 } 01810 01811 /* DOWN? */ 01812 s = dazuko_get_an_access(&did); 01813 01814 if (s == NULL) 01815 { 01816 error = XP_ERROR_INTERRUPT; 01817 break; 01818 } 01819 01820 /* DOWN */ 01821 01822 /* Slot IS in WORKING state. Copy all the 01823 * necessary information to userspace structure. */ 01824 01825 if (s->filenamelength >= DAZUKO_FILENAME_MAX_LENGTH_COMPAT12) 01826 { 01827 /* filename length overflow :( */ 01828 01829 s->filename[DAZUKO_FILENAME_MAX_LENGTH_COMPAT12 - 1] = 0; 01830 temp_length = DAZUKO_FILENAME_MAX_LENGTH_COMPAT12; 01831 } 01832 else 01833 { 01834 temp_length = s->filenamelength + 1; 01835 } 01836 01837 temp_request12 = (struct access_compat12 *)call_xp_malloc(sizeof(struct access_compat12)); 01838 if (temp_request12 == NULL) 01839 { 01840 error = XP_ERROR_FAULT; 01841 } 01842 else if (call_xp_copyin(user_request12, temp_request12, sizeof(struct access_compat12)) != 0) 01843 { 01844 error = XP_ERROR_FAULT; 01845 } 01846 01847 if (error == 0) 01848 { 01849 temp_request12->event = s->event; 01850 temp_request12->o_flags = s->event_p.flags; 01851 temp_request12->o_mode = s->event_p.mode; 01852 temp_request12->uid = s->event_p.uid; 01853 temp_request12->pid = s->event_p.pid; 01854 memcpy(temp_request12->filename, s->filename, temp_length); 01855 01856 if (call_xp_copyout(temp_request12, user_request12, sizeof(struct access_compat12)) != 0) 01857 { 01858 error = XP_ERROR_FAULT; 01859 } 01860 } 01861 01862 call_xp_up(&(s->mutex)); 01863 /* UP */ 01864 01865 if (error) 01866 { 01867 dazuko_state_error(s, DAZUKO_WORKING); 01868 } 01869 01870 if (temp_request12 != NULL) 01871 { 01872 call_xp_free(temp_request12); 01873 } 01874 01875 break; 01876 01877 case IOCTL_RETURN_ACCESS: 01878 /* The daemon has finished scanning a file 01879 * and has the response to give. The daemon's 01880 * slot should be in the WORKING state. */ 01881 01882 user_request12 = (struct access_compat12 *)ptr; 01883 01884 error = call_xp_verify_user_readable(user_request12, sizeof(struct access_compat12)); 01885 if (error) 01886 { 01887 error = XP_ERROR_FAULT; 01888 break; 01889 } 01890 01891 temp_request12 = (struct access_compat12 *)call_xp_malloc(sizeof(struct access_compat12)); 01892 if (temp_request12 == NULL) 01893 { 01894 error = XP_ERROR_FAULT; 01895 break; 01896 } 01897 01898 if (call_xp_copyin(user_request12, temp_request12, sizeof(struct access_compat12)) != 0) 01899 { 01900 error = XP_ERROR_FAULT; 01901 } 01902 01903 temp_int = temp_request12->deny; 01904 01905 call_xp_free(temp_request12); 01906 01907 error = dazuko_return_access(&did, temp_int, NULL); 01908 break; 01909 01910 case IOCTL_SET_OPTION: 01911 /* The daemon wants to set a configuration 01912 * option in the kernel. */ 01913 01914 error = call_xp_verify_user_readable(ptr, 2*sizeof(int)); 01915 if (error) 01916 { 01917 error = XP_ERROR_FAULT; 01918 break; 01919 } 01920 01921 /* copy option type from userspace */ 01922 if (call_xp_copyin(ptr, &temp_int, sizeof(int)) != 0) 01923 { 01924 error = XP_ERROR_FAULT; 01925 break; 01926 } 01927 01928 ptr = ((char *)ptr + sizeof(int)); 01929 01930 /* copy path length from userspace */ 01931 if (call_xp_copyin(ptr, &temp_length, sizeof(int)) != 0) 01932 { 01933 error = XP_ERROR_FAULT; 01934 break; 01935 } 01936 01937 /* sanity check */ 01938 if (temp_length < 0 || temp_length > 4096) 01939 { 01940 error = XP_ERROR_INVALID; 01941 break; 01942 } 01943 01944 ptr = ((char *)ptr + sizeof(int)); 01945 01946 error = call_xp_verify_user_readable(ptr, temp_length); 01947 if (error) 01948 { 01949 error = XP_ERROR_FAULT; 01950 break; 01951 } 01952 01953 k_param = (char *)call_xp_malloc(temp_length + 1); 01954 if (k_param == NULL) 01955 { 01956 error = XP_ERROR_FAULT; 01957 break; 01958 } 01959 01960 /* We must copy the param from userspace to kernelspace. */ 01961 01962 if (call_xp_copyin(ptr, k_param, temp_length) != 0) 01963 { 01964 call_xp_free(k_param); 01965 error = XP_ERROR_FAULT; 01966 break; 01967 } 01968 01969 k_param[temp_length] = 0; 01970 01971 if (temp_int == REGISTER) 01972 error = dazuko_register_daemon(&did, k_param, temp_length, 1); 01973 else 01974 error = dazuko_set_option(&did, temp_int, k_param, temp_length); 01975 01976 call_xp_free(k_param); 01977 01978 break; 01979 01980 default: 01981 call_xp_print("dazuko: daemon requested unknown device_ioctl %d (possible bug)\n", cmd); 01982 01983 break; 01984 } 01985 01986 call_xp_id_free(did.xp_id); 01987 01988 return error; 01989 }
|
|
|
Definition at line 503 of file dazuko_xp.c. References call_xp_free(), call_xp_is_absolute_path(), call_xp_malloc(), call_xp_write_lock(), call_xp_write_unlock(), DPRINT, path::len, path::next, NULL, path::path, XP_ERROR_FAULT, and XP_ERROR_INVALID. 00504 { 00505 /* Create a new struct path structure and insert it 00506 * into the linked list given (list argument). 00507 * The fs_len argument is to help speed things 00508 * up so we don't have to calculate the length 00509 * of fs_path. */ 00510 00511 struct path *newitem; 00512 struct path *tmp; 00513 00514 if (fs_path == NULL || fs_len < 1) 00515 return XP_ERROR_INVALID; 00516 00517 /* we want only absolute paths */ 00518 if (!call_xp_is_absolute_path(fs_path)) 00519 return XP_ERROR_INVALID; 00520 00521 /* create a new struct path structure making room for path also */ 00522 newitem = (struct path *)call_xp_malloc(sizeof(struct path) + fs_len); 00523 if (newitem == NULL) 00524 return XP_ERROR_FAULT; 00525 00526 /* fs_path is already in kernelspace */ 00527 memcpy(newitem->path, fs_path, fs_len); 00528 00529 newitem->path[fs_len] = 0; 00530 00531 while (newitem->path[fs_len-1] == 0) 00532 { 00533 fs_len--; 00534 if (fs_len == 0) 00535 break; 00536 } 00537 00538 if (fs_len < 1) 00539 { 00540 call_xp_free(newitem); 00541 return XP_ERROR_INVALID; 00542 } 00543 00544 newitem->len = fs_len; 00545 00546 /* check if this path already exists in the list */ 00547 for (tmp=*list ; tmp ; tmp=tmp->next) 00548 { 00549 if (newitem->len == tmp->len) 00550 { 00551 if (memcmp(newitem->path, tmp->path, tmp->len) == 0) 00552 { 00553 /* we already have this path */ 00554 00555 call_xp_free(newitem); 00556 00557 return 0; 00558 } 00559 } 00560 } 00561 00562 DPRINT(("dazuko: adding %s %s\n", (list == &incl_paths) ? "incl" : "excl", newitem->path)); 00563 00564 /* add struct path to head of linked list */ 00565 /* LOCK */ 00566 call_xp_write_lock(&lock_lists); 00567 newitem->next = *list; 00568 *list = newitem; 00569 call_xp_write_unlock(&lock_lists); 00570 /* UNLOCK */ 00571 00572 return 0; 00573 }
|
|
Definition at line 2218 of file dazuko_xp.c. References call_xp_id_copy(), call_xp_id_free(), dazuko_find_slot(), NULL, daemon_id::unique, and daemon_id::xp_id. 02219 { 02220 /* Check if the current process is one 02221 * of the daemons. */ 02222 02223 struct daemon_id did; 02224 int ret; 02225 02226 did.xp_id = call_xp_id_copy(xp_id); 02227 did.unique = -1; 02228 02229 ret = (dazuko_find_slot(&did, 1, NULL) != NULL); 02230 02231 call_xp_id_free(did.xp_id); 02232 02233 return ret; 02234 }
|
|
Definition at line 2236 of file dazuko_xp.c. References dazuko_file_struct::aliases, call_xp_print, call_xp_read_lock(), call_xp_read_unlock(), dazuko_bzero(), dazuko_file_listnode::filename, dazuko_file_struct::filename, dazuko_file_struct::filename_length, dazuko_file_listnode::filename_length, path::len, path::next, dazuko_file_listnode::next, NULL, path::path, xp_free(), and xp_malloc(). 02237 { 02238 /* Check if the given filename (with path) is 02239 * under our include directories but not under 02240 * the exclude directories. */ 02241 02242 struct dazuko_file_listnode *cur; 02243 struct path *path; 02244 int selected = 0; 02245 int use_aliases = 1; 02246 02247 if (kfs == NULL) 02248 return 0; 02249 02250 /* If we are interrupted here, we will report that 02251 * this file is not selected. This will make the 02252 * kernel allow normal access. Is this dangerous? */ 02253 /* LOCK */ 02254 call_xp_read_lock(&lock_lists); 02255 02256 if (kfs->aliases == NULL && kfs->filename != NULL) 02257 { 02258 /* extension is not using aliases */ 02259 02260 use_aliases = 0; 02261 02262 kfs->aliases = (struct dazuko_file_listnode *)xp_malloc(sizeof(struct dazuko_file_listnode)); 02263 if (kfs->aliases == NULL) 02264 { 02265 call_xp_print("dazuko: warning: access not controlled (%s)\n", kfs->filename); 02266 return 0; 02267 } 02268 02269 dazuko_bzero(kfs->aliases, sizeof(struct dazuko_file_listnode)); 02270 02271 kfs->aliases->filename = kfs->filename; 02272 kfs->aliases->filename_length = kfs->filename_length; 02273 } 02274 02275 for (cur=kfs->aliases ; cur ; cur=cur->next) 02276 { 02277 if (cur->filename != NULL && cur->filename_length > 0) 02278 { 02279 /* check if filename is under our include paths */ 02280 for (path=incl_paths ; path ; path=path->next) 02281 { 02282 /* the include item must be at least as long as the given filename */ 02283 if (path->len <= cur->filename_length) 02284 { 02285 /* the include item should match the beginning of the given filename */ 02286 if (memcmp(path->path, cur->filename, path->len) == 0) 02287 { 02288 kfs->filename = cur->filename; 02289 kfs->filename_length = cur->filename_length; 02290 02291 selected = 1; 02292 break; 02293 } 02294 } 02295 } 02296 02297 /* If we didn't find a path, it isn't in our 02298 * include directories. It can't be one of 02299 * the selected files to scan. */ 02300 if (!selected) 02301 { 02302 continue; 02303 } 02304 02305 /* check if filename is under our exclude paths */ 02306 for (path=excl_paths ; path ; path=path->next) 02307 { 02308 /* the exclude item must be at least as long as the given filename */ 02309 if (path->len <= cur->filename_length) 02310 { 02311 /* the exclude item should match the beginning of the given filename */ 02312 if (memcmp(path->path, cur->filename, path->len) == 0) 02313 { 02314 kfs->filename = NULL; 02315 kfs->filename_length = 0; 02316 02317 selected = 0; 02318 break; 02319 } 02320 } 02321 } 02322 02323 /* If we are still selected, then we can stop. */ 02324 if (selected) 02325 break; 02326 } 02327 } 02328 02329 call_xp_read_unlock(&lock_lists); 02330 /* UNLOCK */ 02331 02332 if (!use_aliases) 02333 { 02334 xp_free(kfs->aliases); 02335 kfs->aliases = NULL; 02336 } 02337 02338 return selected; 02339 }
|
|
Definition at line 1043 of file dazuko_xp.c. 01044 { 01045 return (c >= '0' && c <= '9'); 01046 }
|
|
Definition at line 2374 of file dazuko_xp.c. References call_xp_compare_file(), call_xp_write_lock(), call_xp_write_unlock(), hash::dirty, hash::file, hash::next, and NULL. Referenced by dazuko_sys_post(). 02375 { 02376 struct hash *h = NULL; 02377 struct hash *entry = NULL; 02378 struct hash *prev = NULL; 02379 struct hash *prev_entry = NULL; 02380 02381 /* LOCK */ 02382 call_xp_write_lock(&lock_hash); 02383 02384 for (h=hash ; h ; h=h->next) 02385 { 02386 /* not found if hit first dirty entry */ 02387 if (h->dirty) 02388 { 02389 entry = NULL; 02390 break; 02391 } 02392 02393 if (call_xp_compare_file(&(h->file), file) == 0) 02394 { 02395 /* we found the entry */ 02396 02397 prev_entry = prev; 02398 entry = h; 02399 break; 02400 } 02401 02402 prev = h; 02403 } 02404 02405 if (entry) 02406 { 02407 if (!entry->dirty) 02408 { 02409 /* mark as dirty */ 02410 entry->dirty = 1; 02411 02412 /* If we already are last entry or next 02413 * entry dirty, we don't need to move */ 02414 02415 if (entry->next) 02416 { 02417 if (!entry->next->dirty) 02418 { 02419 for (h=entry->next ; h ; h=h->next) 02420 { 02421 if (h->dirty) 02422 break; 02423 02424 prev = h; 02425 } 02426 02427 /* remove from current position */ 02428 if (prev_entry) 02429 prev_entry->next = entry->next; 02430 else 02431 hash = entry->next; 02432 02433 if (prev == NULL) 02434 { 02435 /* insert as first item */ 02436 entry->next = hash; 02437 hash = entry; 02438 } 02439 else if (h) 02440 { 02441 /* insert before h (after prev) */ 02442 entry->next = prev->next; 02443 prev->next = entry; 02444 } 02445 else 02446 { 02447 /* insert as last item (after prev) */ 02448 entry->next = NULL; 02449 prev->next = entry; 02450 } 02451 } 02452 } 02453 } 02454 } 02455 02456 call_xp_write_unlock(&lock_hash); 02457 /* UNLOCK */ 02458 02459 }
|
|
Definition at line 1216 of file dazuko_xp.c. 01217 { 01218 /* hopefully this counts for all operating systems! */ 01219 01220 return ((c >= ' ') && (c <= '~') && (c != '\\')); 01221 }
|
|
Definition at line 734 of file dazuko_xp.c. References __dazuko_change_slot_state(), call_xp_atomic_inc(), call_xp_atomic_set(), call_xp_down(), call_xp_free(), call_xp_id_copy(), call_xp_init_mutex(), call_xp_malloc(), call_xp_print, call_xp_up(), dazuko_bzero(), dazuko_find_slot(), DAZUKO_FREE, dazuko_get_new_unique(), slot::did, DPRINT, slot::id, slot::mutex, NULL, NUM_SLOTS, slot_list::reg_name, slot_list_container::slot_list, daemon_id::unique, slot_list::use_count, slot::write_mode, XP_ERROR_BUSY, XP_ERROR_FAULT, XP_ERROR_INTERRUPT, XP_ERROR_PERMISSION, and daemon_id::xp_id. 00735 { 00736 const char *p1; 00737 char *p2; 00738 struct slot *s; 00739 struct slot_list *sl; 00740 int i; 00741 00742 DPRINT(("dazuko: dazuko_register_daemon() [%d]\n", did->unique)); 00743 00744 if (did == NULL || reg_name == NULL) 00745 return XP_ERROR_PERMISSION; 00746 00747 s = dazuko_find_slot(did, 1, NULL); 00748 00749 if (s != NULL) 00750 { 00751 /* We are already registered! */ 00752 00753 call_xp_print("dazuko: daemon %d already assigned to slot[%d]\n", did->unique, s->id); 00754 00755 return XP_ERROR_PERMISSION; 00756 } 00757 00758 /* Find the slot_list with the matching name. */ 00759 00760 for (i=0 ; i<NUM_SLOT_LISTS ; i++) 00761 { 00762 /* DOWN */ 00763 /* if we are interrupted, we say that it 00764 * was interrupted */ 00765 if (call_xp_down(&(slot_lists[i].mutex)) != 0) 00766 return XP_ERROR_INTERRUPT; 00767 00768 sl = slot_lists[i].slot_list; 00769 00770 call_xp_up(&(slot_lists[i].mutex)); 00771 /* UP */ 00772 00773 if (sl != NULL) 00774 { 00775 p1 = reg_name; 00776 p2 = sl->reg_name; 00777 00778 while (*p1 == *p2) 00779 { 00780 if (*p1 == 0) 00781 break; 00782 00783 p1++; 00784 p2++; 00785 } 00786 00787 if (*p1 == *p2) 00788 break; 00789 } 00790 } 00791 00792 if (i == NUM_SLOT_LISTS) 00793 { 00794 /* There is no slot_list with this name. We 00795 * need to make one. */ 00796 00797 sl = (struct slot_list *)call_xp_malloc(sizeof(struct slot_list) + string_length); 00798 if (sl == NULL) 00799 return XP_ERROR_FAULT; 00800 00801 dazuko_bzero(sl, sizeof(struct slot_list) + string_length); 00802 call_xp_atomic_set(&(sl->use_count), 0); 00803 00804 p1 = reg_name; 00805 p2 = sl->reg_name; 00806 00807 while (*p1) 00808 { 00809 *p2 = *p1; 00810 00811 p1++; 00812 p2++; 00813 } 00814 *p2 = 0; 00815 00816 /* give each slot a unique id */ 00817 for (i=0 ; i<NUM_SLOTS ; i++) 00818 { 00819 sl->slots[i].id = i; 00820 call_xp_init_mutex(&(sl->slots[i].mutex)); 00821 } 00822 00823 /* we need to find an empty slot */ 00824 for (i=0 ; i<NUM_SLOT_LISTS ; i++) 00825 { 00826 /* DOWN */ 00827 /* if we are interrupted, we need to cleanup 00828 * and return error */ 00829 if (call_xp_down(&(slot_lists[i].mutex)) != 0) 00830 { 00831 call_xp_free(sl); 00832 return XP_ERROR_INTERRUPT; 00833 } 00834 00835 if (slot_lists[i].slot_list == NULL) 00836 { 00837 slot_lists[i].slot_list = sl; 00838 00839 call_xp_up(&(slot_lists[i].mutex)); 00840 /* UP */ 00841 break; 00842 } 00843 00844 call_xp_up(&(slot_lists[i].mutex)); 00845 /* UP */ 00846 } 00847 00848 if (i == NUM_SLOT_LISTS) 00849 { 00850 /* no empty slot :( */ 00851 call_xp_free(sl); 00852 return XP_ERROR_BUSY; 00853 } 00854 } 00855 00856 /* find an available slot and hold the mutex 00857 * if we find one */ 00858 /* DOWN? */ 00859 s = dazuko_find_slot(NULL, 0, sl); 00860 00861 if (s == NULL) 00862 return XP_ERROR_BUSY; 00863 00864 /* DOWN */ 00865 00866 /* We have found a slot, so increment the active 00867 * variable and the kernel module use counter. 00868 * The module counter will always reflect the 00869 * number of daemons. */ 00870 00871 call_xp_atomic_inc(&active); 00872 00873 /* get new unique id for this process */ 00874 did->unique = dazuko_get_new_unique(); 00875 00876 s->did.unique = did->unique; 00877 s->did.xp_id = call_xp_id_copy(did->xp_id); 00878 s->write_mode = write_mode; 00879 00880 call_xp_atomic_inc(&(sl->use_count)); 00881 00882 /* the daemon is registered, but not yet 00883 * ready to receive files */ 00884 __dazuko_change_slot_state(s, DAZUKO_FREE, DAZUKO_FREE); 00885 00886 DPRINT(("dazuko: slot[%d] assigned to daemon %d\n", s->id, s->did.unique)); 00887 00888 call_xp_up(&(s->mutex)); 00889 /* UP */ 00890 00891 return 0; 00892 }
|
|
Definition at line 575 of file dazuko_xp.c. References call_xp_free(), call_xp_write_lock(), call_xp_write_unlock(), DPRINT, hash::name, and hash::next. Referenced by _dazuko_unregister_daemon(), and dazuko_exit(). 00576 { 00577 /* Empty the hash linked list. */ 00578 00579 struct hash *tmp; 00580 00581 /* LOCK */ 00582 call_xp_write_lock(&lock_hash); 00583 while (hash) 00584 { 00585 tmp = hash; 00586 hash = hash->next; 00587 00588 DPRINT(("dazuko: removing hash %s\n", tmp->name)); 00589 00590 call_xp_free(tmp); 00591 } 00592 call_xp_write_unlock(&lock_hash); 00593 /* UNLOCK */ 00594 }
|
|
Definition at line 596 of file dazuko_xp.c. References call_xp_free(), call_xp_write_lock(), call_xp_write_unlock(), DPRINT, path::next, and path::path. 00597 { 00598 /* Empty both include and exclude struct path 00599 * linked lists. */ 00600 00601 struct path *tmp; 00602 00603 /* LOCK */ 00604 call_xp_write_lock(&lock_lists); 00605 00606 /* empty include paths list */ 00607 while (incl_paths) 00608 { 00609 tmp = incl_paths; 00610 incl_paths = incl_paths->next; 00611 00612 DPRINT(("dazuko: removing incl %s\n", tmp->path)); 00613 00614 call_xp_free(tmp); 00615 } 00616 00617 /* empty exclude paths list */ 00618 while (excl_paths) 00619 { 00620 tmp = excl_paths; 00621 excl_paths = excl_paths->next; 00622 00623 DPRINT(("dazuko: removing excl %s\n", tmp->path)); 00624 00625 call_xp_free(tmp); 00626 } 00627 00628 call_xp_write_unlock(&lock_lists); 00629 /* UNLOCK */ 00630 }
|
|
Definition at line 976 of file dazuko_xp.c. References call_xp_notify(), call_xp_up(), call_xp_wait_until_condition(), dazuko_change_slot_state(), DAZUKO_DONE, dazuko_find_slot(), DAZUKO_WORKING, DPRINT, slot::id, slot::mutex, NULL, one_slot_state_not_condition(), slot::response, one_slot_state_not_condition_param::slot, one_slot_state_not_condition_param::state, daemon_id::unique, XP_ERROR_INTERRUPT, and XP_ERROR_PERMISSION. 00977 { 00978 /* The daemon has finished scanning a file 00979 * and has the response to give. The daemon's 00980 * slot should be in the DAZUKO_WORKING state. */ 00981 00982 struct one_slot_state_not_condition_param cond_p; 00983 00984 /* do we already have a slot? */ 00985 if (s == NULL) 00986 { 00987 /* find our slot */ 00988 s = dazuko_find_slot(did, 1, NULL); 00989 00990 if (s == NULL) 00991 { 00992 /* It appears the kernel isn't interested 00993 * in us or our response. It gave our slot away! */ 00994 00995 DPRINT(("dazuko: daemon %d unexpectedly lost slot\n", did->unique)); 00996 00997 return XP_ERROR_PERMISSION; 00998 } 00999 } 01000 01001 /* we will be writing into the slot, so we 01002 * need to lock it */ 01003 01004 /* DOWN? */ 01005 if (!dazuko_change_slot_state(s, DAZUKO_WORKING, DAZUKO_DONE, 0)) 01006 { 01007 /* The slot is in the wrong state. We will 01008 * assume the kernel has cancelled the file 01009 * access. */ 01010 01011 DPRINT(("dazuko: response from daemon %d on slot[%d] not needed\n", did->unique, s->id)); 01012 01013 return 0; 01014 } 01015 01016 /* DOWN */ 01017 01018 s->response = response; 01019 01020 call_xp_up(&(s->mutex)); 01021 /* UP */ 01022 01023 /* wake up any kernel processes that are 01024 * waiting for responses */ 01025 call_xp_notify(&wait_kernel_waiting_while_daemon_works); 01026 01027 cond_p.slot = s; 01028 cond_p.state = DAZUKO_DONE; 01029 if (call_xp_wait_until_condition(&wait_daemon_waiting_for_free, one_slot_state_not_condition, &cond_p, 1) != 0) 01030 { 01031 /* The user has issued an interrupt. 01032 * Return an error. The daemon should 01033 * unregister itself. */ 01034 01035 DPRINT(("dazuko: daemon %d killed while waiting for response acknowledgement\n", did->unique)); 01036 01037 return XP_ERROR_INTERRUPT; 01038 } 01039 01040 return 0; 01041 }
|
|
Definition at line 2170 of file dazuko_xp.c. References call_xp_down(), call_xp_up(), dazuko_run_daemon_on_slotlist(), NULL, slot_list_container::slot_list, event_properties::thrown, and XP_ERROR_INTERRUPT. 02171 { 02172 struct slot_list *sl; 02173 int i; 02174 int rc = 0; 02175 int error; 02176 02177 if (event_p != NULL) 02178 { 02179 /* we don't want to throw the same event twice */ 02180 if (event_p->thrown) 02181 return 0; 02182 event_p->thrown = 1; 02183 } 02184 02185 for (i=0 ; i<NUM_SLOT_LISTS ; i++) 02186 { 02187 /* DOWN */ 02188 /* if we are interrupted, we report error */ 02189 if (call_xp_down(&(slot_lists[i].mutex)) != 0) 02190 return XP_ERROR_INTERRUPT; 02191 02192 sl = slot_lists[i].slot_list; 02193 02194 call_xp_up(&(slot_lists[i].mutex)); 02195 /* UP */ 02196 02197 if (sl != NULL) 02198 { 02199 error = dazuko_run_daemon_on_slotlist(event, filename, filenamelength, event_p, file_p, rc, sl); 02200 02201 if (error < 0) 02202 { 02203 /* most likely user interrupt */ 02204 rc = error; 02205 break; 02206 } 02207 else if (error > 0) 02208 { 02209 /* this daemon wants access blocked */ 02210 rc = 1; 02211 } 02212 } 02213 } 02214 02215 return rc; 02216 }
|
|
Definition at line 2027 of file dazuko_xp.c. References __dazuko_change_slot_state(), call_xp_down(), call_xp_notify(), call_xp_up(), call_xp_wait_until_condition(), dazuko_bzero(), dazuko_change_slot_state(), DAZUKO_DONE, DAZUKO_FREE, DAZUKO_WAITING, DAZUKO_WORKING, slot::did, DPRINT, slot::event, slot::event_p, slot::file_p, slot::filename, slot::filenamelength, get_ready_slot_condition(), slot::mutex, NULL, event_properties::pid, slot::response, get_ready_slot_condition_param::slot, two_slot_state_not_condition_param::slot1, two_slot_state_not_condition_param::slot2, get_ready_slot_condition_param::slotlist, two_slot_state_not_condition_param::state1, two_slot_state_not_condition_param::state2, two_slot_state_not_condition(), and daemon_id::unique. 02028 { 02029 /* This is the main function called by the kernel 02030 * to work with a daemon. */ 02031 02032 int rc; 02033 int unique; 02034 struct slot *s; 02035 struct get_ready_slot_condition_param cond_p1; 02036 struct two_slot_state_not_condition_param cond_p2; 02037 02038 begin: 02039 /* we initialize the slot value because 02040 * we cannot guarentee that it will be 02041 * assigned a new value BEFORE !active 02042 * is checked */ 02043 s = NULL; 02044 02045 /* wait for a slot to become ready */ 02046 cond_p1.slotlist = sl; 02047 cond_p1.slot = s; 02048 if (call_xp_wait_until_condition(&wait_kernel_waiting_for_free_slot, get_ready_slot_condition, &cond_p1, 0) != 0) 02049 { 02050 /* The kernel process was killed while 02051 * waiting for a slot to become ready. 02052 * This is fine. */ 02053 02054 DPRINT(("dazuko: kernel process %d killed while waiting for free slot\n", event_p->pid)); 02055 02056 return -1; /* user interrupted */ 02057 } 02058 02059 /* Make sure we have a slot. We may have 02060 * gotten past the last wait because we 02061 * are no longer active. */ 02062 02063 s = cond_p1.slot; 02064 02065 if (s == NULL) 02066 { 02067 /* We were no longer active. We don't 02068 * need to initiate a daemon. This also 02069 * means we never acquired the lock. */ 02070 02071 return 0; /* allow access */ 02072 } 02073 02074 /* DOWN */ 02075 02076 /* the slot is already locked at this point */ 02077 02078 /* grab the daemon's unique */ 02079 unique = s->did.unique; 02080 02081 /* At this point we have a locked slot. It IS 02082 * sitting in the DAZUKO_WAITING state, waiting for 02083 * us to give it some work. */ 02084 02085 /* set up the slot to do work */ 02086 s->filename = filename; 02087 s->event = event; 02088 s->response = prev_response; 02089 s->filenamelength = filenamelength; 02090 02091 if (event_p == NULL) 02092 dazuko_bzero(&(s->event_p), sizeof(struct event_properties)); 02093 else 02094 memcpy(&(s->event_p), event_p, sizeof(struct event_properties)); 02095 02096 if (file_p == NULL) 02097 dazuko_bzero(&(s->file_p), sizeof(struct file_properties)); 02098 else 02099 memcpy(&(s->file_p), file_p, sizeof(struct file_properties)); 02100 02101 /* we are done modifying the slot */ 02102 call_xp_up(&(s->mutex)); 02103 /* UP */ 02104 02105 /* wake up any daemons waiting for work */ 02106 call_xp_notify(&wait_daemon_waiting_for_work); 02107 02108 /* wait until the daemon is finished with the slot */ 02109 cond_p2.slot1 = s; 02110 cond_p2.state1 = DAZUKO_WAITING; 02111 cond_p2.slot2 = s; 02112 cond_p2.state2 = DAZUKO_WORKING; 02113 if (call_xp_wait_until_condition(&wait_kernel_waiting_while_daemon_works, two_slot_state_not_condition, &cond_p2, 0) != 0) 02114 { 02115 /* The kernel process was killed while 02116 * waiting for a daemon to process the file. 02117 * This is fine. */ 02118 02119 DPRINT(("dazuko: kernel process %d killed while waiting for daemon response\n", event_p->pid)); 02120 02121 /* change the slot's state to let the 02122 * daemon know we are not interested 02123 * in a response */ 02124 dazuko_change_slot_state(s, DAZUKO_FREE, DAZUKO_FREE, 1); 02125 02126 return -1; /* user interrupted */ 02127 } 02128 02129 /* we are working with the slot, so 02130 * we need to lock it */ 02131 /* DOWN */ 02132 if (call_xp_down(&(s->mutex)) != 0) 02133 { 02134 return -1; /* user interrupted */ 02135 } 02136 02137 /* make sure this is the right daemon */ 02138 if (s->did.unique != unique) 02139 { 02140 /* This is a different daemon than 02141 * the one we assigned work to. 02142 * We need to scan again. */ 02143 call_xp_up(&(s->mutex)); 02144 /* UP */ 02145 goto begin; 02146 } 02147 02148 /* The slot should now be in the DAZUKO_DONE state. */ 02149 if (!__dazuko_change_slot_state(s, DAZUKO_DONE, DAZUKO_FREE)) 02150 { 02151 /* The daemon was killed while scanning. 02152 * We need to scan again. */ 02153 02154 call_xp_up(&(s->mutex)); 02155 /* UP */ 02156 goto begin; 02157 } 02158 02159 /* grab the response */ 02160 rc = s->response; 02161 02162 call_xp_up(&(s->mutex)); 02163 /* UP */ 02164 02165 /* CONGRATULATIONS! You successfully completed a full state cycle! */ 02166 02167 return rc; 02168 }
|
|
Definition at line 1276 of file dazuko_xp.c. References _dazuko_unregister_daemon(), access_mask, ADD_EXCLUDE_PATH, ADD_INCLUDE_PATH, call_xp_print, dazuko_find_slot(), dazuko_insert_path_fs(), dazuko_register_daemon(), dazuko_remove_all_paths(), NULL, REGISTER, REMOVE_ALL_PATHS, SET_ACCESS_MASK, UNREGISTER, and XP_ERROR_PERMISSION. 01277 { 01278 /* The daemon wants to set a configuration 01279 * option in the kernel. */ 01280 01281 struct slot *s; 01282 int error; 01283 01284 /* sanity check */ 01285 if (len < 0 || len > 8192) 01286 return XP_ERROR_PERMISSION; 01287 01288 /* make sure we are already registered 01289 * (or that we don't register twice) */ 01290 01291 /* find our slot */ 01292 s = dazuko_find_slot(did, 1, NULL); 01293 01294 switch (opt) 01295 { 01296 case REGISTER: 01297 call_xp_print("dazuko: dazuko_set_option does not support REGISTER (bug!)\n"); 01298 return XP_ERROR_PERMISSION; 01299 01300 case UNREGISTER: 01301 if (s == NULL) 01302 { 01303 /* We are not registered! */ 01304 01305 return 0; 01306 } 01307 break; 01308 01309 default: 01310 if (s == NULL) 01311 { 01312 error = dazuko_register_daemon(did, "_COMPAT", 7, 1); 01313 if (error) 01314 { 01315 call_xp_print("dazuko: unregistered daemon %d attempted access\n", did->unique); 01316 return XP_ERROR_PERMISSION; 01317 } 01318 01319 s = dazuko_find_slot(did, 1, NULL); 01320 if (s == NULL) 01321 { 01322 call_xp_print("dazuko: unregistered daemon %d attempted access\n", did->unique); 01323 return XP_ERROR_PERMISSION; 01324 } 01325 01326 call_xp_print("dazuko: warning: daemon %d is using a deprecated protocol\n", did->unique); 01327 } 01328 break; 01329 } 01330 01331 /* check option type and take the appropriate action */ 01332 switch (opt) 01333 { 01334 case UNREGISTER: 01335 error = _dazuko_unregister_daemon(did); 01336 if (error) 01337 return error; 01338 break; 01339 01340 case SET_ACCESS_MASK: 01341 memcpy(&access_mask, (char *)param, sizeof(char)); 01342 break; 01343 01344 case ADD_INCLUDE_PATH: 01345 error = dazuko_insert_path_fs(&incl_paths, (char *)param, len); 01346 if (error) 01347 return error; 01348 break; 01349 01350 case ADD_EXCLUDE_PATH: 01351 error = dazuko_insert_path_fs(&excl_paths, (char *)param, len); 01352 if (error) 01353 return error; 01354 break; 01355 01356 case REMOVE_ALL_PATHS: 01357 dazuko_remove_all_paths(); 01358 break; 01359 01360 default: 01361 call_xp_print("dazuko: daemon %d requested unknown set %d (possible bug)\n", did->unique, opt); 01362 break; 01363 } 01364 01365 return 0; 01366 }
|
|
Definition at line 2508 of file dazuko_xp.c. References call_xp_fill_file_struct(), dazuko_is_selected(), and dazuko_file_struct::should_scan. 02509 { 02510 /* Check if we are supposed to scan this file. 02511 * This checks for all the correct file types, 02512 * permissions, and if it is within the desired 02513 * paths to scan. */ 02514 02515 int result = 0; 02516 02517 /* check if we already know if we scan this file */ 02518 switch (kfs->should_scan) 02519 { 02520 /* case 0 means that we do not know yet. This is a little 02521 * confusing, because 0 represents uninitialized. However, 02522 * the should_scan variable is used in this function ONLY 02523 * so this optimization shouldn't cause any problems. */ 02524 02525 case 1: 02526 /* we already know it should be scanned */ 02527 return 1; 02528 02529 case 2: 02530 /* we already know it should not be scanned */ 02531 return 2; 02532 } 02533 02534 /* make necessary platform-dependent checks */ 02535 if (call_xp_fill_file_struct(kfs) == 0) 02536 { 02537 if (dazuko_is_selected(kfs)) 02538 { 02539 /* If we made it this far, we are supposed 02540 * to scan this file. We mark it so that 02541 * any further immediate inquiries don't have 02542 * to do all this work all over again. */ 02543 02544 /* yes, should be scanned */ 02545 kfs->should_scan = 1; 02546 02547 result = 1; 02548 } 02549 else 02550 { 02551 /* We will still mark it so that any further 02552 * immediate inquiries don't have to do all 02553 * this work all over again. */ 02554 02555 /* no, should not be scanned */ 02556 kfs->should_scan = 2; 02557 } 02558 } 02559 02560 return result; 02561 }
|
|
Definition at line 299 of file dazuko_xp.c. References call_xp_down(), call_xp_up(), slot::mutex, slot::state, and XP_ERROR_INTERRUPT. 00300 { 00301 int state; 00302 00303 /* DOWN */ 00304 if (call_xp_down(&(s->mutex)) != 0) 00305 return XP_ERROR_INTERRUPT; 00306 00307 state = s->state; 00308 00309 call_xp_up(&(s->mutex)); 00310 /* UP */ 00311 00312 return state; 00313 }
|
|
Definition at line 261 of file dazuko_xp.c. References dazuko_vsnprintf(). 00262 { 00263 va_list ap; 00264 int ret; 00265 00266 va_start(ap, format); 00267 ret = dazuko_vsnprintf(str, size, format, ap); 00268 va_end(ap); 00269 00270 return ret; 00271 }
|
|
Definition at line 723 of file dazuko_xp.c. References call_xp_notify(), DAZUKO_BROKEN, and dazuko_change_slot_state(). Referenced by dazuko_handle_user_request_compat12(). 00724 { 00725 if (dazuko_change_slot_state(s, current_state, DAZUKO_BROKEN, 1)) 00726 { 00727 call_xp_notify(&wait_kernel_waiting_for_free_slot); 00728 call_xp_notify(&wait_kernel_waiting_while_daemon_works); 00729 } 00730 00731 return 0; 00732 }
|
|
Definition at line 1101 of file dazuko_xp.c. References NULL. 01102 { 01103 const char *p; 01104 01105 if (haystack == NULL) 01106 return NULL; 01107 01108 for (p=haystack ; *p ; p++) 01109 { 01110 if (*p == needle) 01111 return p; 01112 } 01113 01114 return NULL; 01115 }
|
|
Definition at line 1088 of file dazuko_xp.c. References NULL. 01089 { 01090 const char *p; 01091 01092 if (string == NULL) 01093 return -1; 01094 01095 for (p=string ; *p ; p++) 01096 continue; 01097 01098 return (p - string); 01099 }
|
|
Definition at line 1117 of file dazuko_xp.c. References NULL. 01118 { 01119 const char *p1; 01120 const char *p2; 01121 const char *p3; 01122 01123 if (haystack == NULL || needle == NULL) 01124 return NULL; 01125 01126 for (p1=haystack ; *p1 ; p1++) 01127 { 01128 for (p2=needle,p3=p1 ; *p2&&*p3 ; p2++,p3++) 01129 { 01130 if (*p2 != *p3) 01131 break; 01132 } 01133 01134 if (*p2 == 0) 01135 return p1; 01136 } 01137 01138 return NULL; 01139 }
|
|
Definition at line 1048 of file dazuko_xp.c. References dazuko_isdigit(), and NULL. 01049 { 01050 long num = 1; 01051 const char *p = string; 01052 01053 if (string == NULL) 01054 return 0; 01055 01056 switch (*p) 01057 { 01058 case '-': 01059 num = -1; 01060 p++; 01061 break; 01062 01063 case '+': 01064 p++; 01065 break; 01066 } 01067 01068 if (dazuko_isdigit(*p)) 01069 { 01070 num *= *p - '0'; 01071 p++; 01072 } 01073 else 01074 { 01075 return 0; 01076 } 01077 01078 while (dazuko_isdigit(*p)) 01079 { 01080 num *= 10; 01081 num += *p - '0'; 01082 p++; 01083 } 01084 01085 return num; 01086 }
|
|
Definition at line 2563 of file dazuko_xp.c. References access_mask, call_xp_atomic_read(), dazuko_is_our_daemon(), DAZUKO_ON_CLOSE, DAZUKO_ON_OPEN, SCAN_ON_CLOSE, SCAN_ON_CLOSE_MODIFIED, and SCAN_ON_OPEN. Referenced by rsbac_adf_request_daz(), and rsbac_adf_set_attr_daz(). 02564 { 02565 /* is this event in our mask? */ 02566 switch (event) 02567 { 02568 case DAZUKO_ON_OPEN: 02569 /* this is a special case because the on_close information needs 02570 * to be saved during the on_open event */ 02571 02572 if ((SCAN_ON_OPEN || SCAN_ON_CLOSE || SCAN_ON_CLOSE_MODIFIED) == 0) 02573 return -1; 02574 break; 02575 02576 case DAZUKO_ON_CLOSE: 02577 /* will need to scan if ON_CLOSE_MODIFIED is in the mask too */ 02578 02579 if ((SCAN_ON_CLOSE || SCAN_ON_CLOSE_MODIFIED) == 0) 02580 return -1; 02581 break; 02582 02583 default: 02584 if ((access_mask & event) == 0) 02585 return -1; 02586 break; 02587 } 02588 02589 /* do we have any daemons? */ 02590 if (call_xp_atomic_read(&active) <= 0) 02591 return -1; 02592 02593 /* should daemons be allowed this event without a scan? */ 02594 if (daemon_is_allowed) 02595 { 02596 if (dazuko_is_our_daemon(xp_id)) 02597 { 02598 /* this is one of our daemons, so we will report as 02599 * as if this event was not in the mask */ 02600 02601 return -1; 02602 } 02603 } 02604 02605 return 0; 02606 }
|
|
Definition at line 2727 of file dazuko_xp.c. References call_xp_atomic_read(), call_xp_free(), dazuko_add_hash(), dazuko_get_hash(), dazuko_mark_hash_dirty(), DAZUKO_ON_CLOSE, DAZUKO_ON_CLOSE_MODIFIED, DAZUKO_ON_OPEN, dazuko_run_daemon(), dazuko_should_scan(), hash::dirty, hash::name, hash::namelen, NULL, SCAN_ON_CLOSE, SCAN_ON_CLOSE_MODIFIED, and SCAN_ON_OPEN. Referenced by rsbac_adf_set_attr_daz(). 02728 { 02729 struct hash *h = NULL; 02730 02731 switch (event) 02732 { 02733 case DAZUKO_ON_OPEN: /* kfs,file required */ 02734 /* if the file was opened and we are interested 02735 * in scanning on close, add this file to our struct hash list */ 02736 02737 if ((call_xp_atomic_read(&active) > 0) && file != NULL && kfs != NULL) 02738 { 02739 if (SCAN_ON_OPEN || SCAN_ON_CLOSE || SCAN_ON_CLOSE_MODIFIED) 02740 { 02741 /* make sure we should scan this file */ 02742 if (dazuko_should_scan(kfs)) 02743 { 02744 /* hash is added if we were given an xp_file */ 02745 if (file != NULL) 02746 dazuko_add_hash(file, kfs->filename, kfs->filename_length); 02747 02748 /* this is a fallback in case we didn't process the event in "sys_pre" */ 02749 dazuko_run_daemon(event, kfs->filename, kfs->filename_length, event_p, &(kfs->file_p)); 02750 } 02751 } 02752 } 02753 break; 02754 02755 case DAZUKO_ON_CLOSE: /* file,o_flags,o_mode,pid,uid required */ 02756 if (file != NULL) 02757 { 02758 /* find hash entry and remove it from list */ 02759 h = dazuko_get_hash(file); 02760 02761 /* if we found the file in our list and the file was 02762 * successfully closed, we need to scan it */ 02763 if (h != NULL) 02764 { 02765 /* determine if we are scanning on close or close_modified */ 02766 02767 /* note that close_modified has priority over just close */ 02768 02769 if (SCAN_ON_CLOSE_MODIFIED && h->dirty) 02770 dazuko_run_daemon(DAZUKO_ON_CLOSE_MODIFIED, h->name, h->namelen, event_p, NULL); 02771 else if (SCAN_ON_CLOSE) 02772 dazuko_run_daemon(DAZUKO_ON_CLOSE, h->name, h->namelen, event_p, NULL); 02773 02774 /* clean up the struct hash structure */ 02775 call_xp_free(h); 02776 } 02777 } 02778 else 02779 { 02780 if (SCAN_ON_CLOSE) 02781 { 02782 if (dazuko_should_scan(kfs)) 02783 { 02784 dazuko_run_daemon(DAZUKO_ON_CLOSE, kfs->filename, kfs->filename_length, event_p, &(kfs->file_p)); 02785 } 02786 } 02787 } 02788 break; 02789 02790 case DAZUKO_ON_CLOSE_MODIFIED: /* file required */ 02791 if (file != NULL) 02792 { 02793 /* if we actually wrote something and we found the 02794 * file in our list, set it as dirty */ 02795 02796 /* Swade 4/24/02: Move to end of clean list */ 02797 dazuko_mark_hash_dirty(file); 02798 } 02799 break; 02800 02801 default: 02802 break; 02803 } 02804 02805 return 0; 02806 }
|
|
Definition at line 2608 of file dazuko_xp.c. References call_xp_compare_file(), call_xp_malloc(), call_xp_print, call_xp_read_lock(), call_xp_read_unlock(), DAZUKO_ON_CLOSE, DAZUKO_ON_CLOSE_MODIFIED, DAZUKO_ON_OPEN, dazuko_run_daemon(), dazuko_should_scan(), dazuko_file_struct::extra_data, hash::file, dazuko_file_struct::filename, dazuko_file_struct::filename_length, hash::name, hash::namelen, hash::next, NULL, SCAN_ON_OPEN, dazuko_file_struct::should_scan, XP_ERROR_INTERRUPT, and XP_ERROR_PERMISSION. Referenced by rsbac_adf_request_daz(). 02609 { 02610 /* return codes: 02611 * >0 -> access should be blocked 02612 * <0 -> access should be blocked (because user interrupted) 02613 * 0 -> access is allowed 02614 * -2 -> unscanned access should not be taken care of 02615 */ 02616 02617 int error = 0; 02618 struct hash *h = NULL; 02619 02620 switch (event) 02621 { 02622 case DAZUKO_ON_OPEN: 02623 /* special case, because this pre may be called 02624 * in order to record ON_CLOSE events (in post) */ 02625 02626 if (!SCAN_ON_OPEN) 02627 return 2; 02628 break; 02629 02630 case DAZUKO_ON_CLOSE: 02631 /* handled in post */ 02632 02633 return 2; 02634 02635 case DAZUKO_ON_CLOSE_MODIFIED: 02636 /* (this is really sys_write) always permitted */ 02637 02638 return 2; 02639 02640 default: 02641 break; 02642 } 02643 02644 if (kfs == NULL) 02645 { 02646 /* kfs is required */ 02647 02648 call_xp_print("dazuko: kfs=NULL (possible bug)\n"); 02649 02650 return XP_ERROR_PERMISSION; 02651 } 02652 02653 if (file != NULL) 02654 { 02655 /* we search for the file descriptor first */ 02656 02657 /* LOCK */ 02658 call_xp_read_lock(&lock_hash); 02659 02660 for (h=hash ; h ; h=h->next) 02661 { 02662 if (call_xp_compare_file(&(h->file), file) == 0) 02663 { 02664 /* we found the file descriptor */ 02665 02666 kfs->filename = (char*)call_xp_malloc(h->namelen + 1); 02667 if (kfs->filename != NULL) 02668 { 02669 memcpy(kfs->filename, h->name, h->namelen); 02670 kfs->filename[h->namelen] = 0; 02671 kfs->filename_length = h->namelen; 02672 kfs->should_scan = 1; 02673 } 02674 else 02675 { 02676 /* error allocating, so we get out */ 02677 h = NULL; 02678 } 02679 break; 02680 } 02681 } 02682 02683 call_xp_read_unlock(&lock_hash); 02684 /* UNLOCK */ 02685 02686 if (h == NULL && kfs->extra_data == NULL) 02687 { 02688 /* we don't know this file descriptor 02689 * and we cannot fallback on name lookups 02690 */ 02691 02692 /* we should not scan this file */ 02693 kfs->should_scan = 2; 02694 02695 return 0; 02696 } 02697 } 02698 02699 /* make sure we should scan this file */ 02700 if (dazuko_should_scan(kfs)) 02701 error = dazuko_run_daemon(event, kfs->filename, kfs->filename_length, event_p, &(kfs->file_p)); 02702 else 02703 return 2; 02704 02705 if (error > 0) 02706 { 02707 /* access will be blocked */ 02708 02709 /* dazuko_sys_post should NOT be called! */ 02710 02711 return XP_ERROR_PERMISSION; 02712 } 02713 else if (error < 0) 02714 { 02715 /* user interrupted */ 02716 02717 /* dazuko_sys_post should NOT be called! */ 02718 02719 return XP_ERROR_INTERRUPT; 02720 } 02721 02722 /* access allowed */ 02723 02724 return 0; 02725 }
|
|
Definition at line 705 of file dazuko_xp.c. References _dazuko_unregister_daemon(), call_xp_id_copy(), call_xp_id_free(), NULL, daemon_id::unique, and daemon_id::xp_id. 00706 { 00707 struct daemon_id did; 00708 int ret; 00709 00710 if (xp_id == NULL) 00711 return 0; 00712 00713 did.unique = -1; 00714 did.xp_id = call_xp_id_copy(xp_id); 00715 00716 ret = _dazuko_unregister_daemon(&did); 00717 00718 call_xp_id_free(did.xp_id); 00719 00720 return ret; 00721 }
|
|
Definition at line 149 of file dazuko_xp.c. References DAZUKO_VSNPRINTF_PRINTSTRING, and NULL. 00150 { 00151 char *target; 00152 const char *end; 00153 int overflow = 0; 00154 char number_buffer[32]; /* 32 should be enough to hold any number, right? */ 00155 const char *s; 00156 00157 if (str == NULL || size < 1 || format == NULL) 00158 return -1; 00159 00160 target = str; 00161 end = (target + size) - 1; 00162 00163 #define DAZUKO_VSNPRINTF_PRINTSTRING \ 00164 for ( ; *s ; s++) \ 00165 { \ 00166 if (target == end) \ 00167 { \ 00168 overflow = 1; \ 00169 goto dazuko_vsnprintf_out; \ 00170 } \ 00171 *target = *s; \ 00172 target++; \ 00173 } 00174 00175 for ( ; *format ; format++) 00176 { 00177 if (target == end) 00178 { 00179 overflow = 1; 00180 goto dazuko_vsnprintf_out; 00181 } 00182 00183 if (*format == '%') 00184 { 00185 format++; 00186 00187 switch (*format) 00188 { 00189 case 's': /* %s */ 00190 s = va_arg(ap, char *); 00191 if (s == NULL) 00192 s = "(null)"; 00193 DAZUKO_VSNPRINTF_PRINTSTRING 00194 break; 00195 00196 case 'd': /* %d */ 00197 sprintf(number_buffer, "%d", va_arg(ap, int)); 00198 s = number_buffer; 00199 DAZUKO_VSNPRINTF_PRINTSTRING 00200 break; 00201 00202 case 'c': /* %c */ 00203 *target = va_arg(ap, int); 00204 target++; 00205 break; 00206 00207 case 'l': /* %lu */ 00208 format++; 00209 if (*format != 'u') 00210 { 00211 /* print error message */ 00212 goto dazuko_vsnprintf_out; 00213 } 00214 sprintf(number_buffer, "%lu", va_arg(ap, unsigned long)); 00215 s = number_buffer; 00216 DAZUKO_VSNPRINTF_PRINTSTRING 00217 break; 00218 00219 case '0': /* %02x */ 00220 format++; 00221 if (*format != '2') 00222 { 00223 /* print error message */ 00224 goto dazuko_vsnprintf_out; 00225 } 00226 format++; 00227 if (*format != 'x') 00228 { 00229 /* print error message */ 00230 goto dazuko_vsnprintf_out; 00231 } 00232 sprintf(number_buffer, "%02x", va_arg(ap, int)); 00233 s = number_buffer; 00234 DAZUKO_VSNPRINTF_PRINTSTRING 00235 break; 00236 00237 default: 00238 /* print error message */ 00239 goto dazuko_vsnprintf_out; 00240 } 00241 } 00242 else 00243 { 00244 *target = *format; 00245 target++; 00246 } 00247 } 00248 00249 dazuko_vsnprintf_out: 00250 00251 *target = 0; 00252 00253 /* We are returning what we've written. If there was an 00254 * overflow, the returned value will match "size" rather 00255 * than being less than "size" 00256 */ 00257 00258 return ((target - str) + overflow); 00259 }
|
|
Definition at line 2020 of file dazuko_xp.c. References call_xp_atomic_read(), dazuko_get_and_hold_ready_slot(), and NULL. 02021 { 02022 return ((((struct get_ready_slot_condition_param *)param)->slot = dazuko_get_and_hold_ready_slot(((struct get_ready_slot_condition_param *)param)->slotlist)) != NULL 02023 || call_xp_atomic_read(&active) == 0 02024 || call_xp_atomic_read(&(((struct get_ready_slot_condition_param *)param)->slotlist->use_count)) == 0); 02025 }
|
|
Definition at line 315 of file dazuko_xp.c. References dazuko_slot_state(). 00316 { 00317 return (dazuko_slot_state(((struct one_slot_state_not_condition_param *)param)->slot) 00318 != ((struct one_slot_state_not_condition_param *)param)->state); 00319 }
|
|
Definition at line 321 of file dazuko_xp.c. References dazuko_slot_state(). 00322 { 00323 return (dazuko_slot_state(((struct two_slot_state_not_condition_param *)param)->slot1) 00324 != ((struct two_slot_state_not_condition_param *)param)->state1 00325 && dazuko_slot_state(((struct two_slot_state_not_condition_param *)param)->slot2) 00326 != ((struct two_slot_state_not_condition_param *)param)->state2); 00327 }
|
|
Definition at line 133 of file dazuko_xp.c. Referenced by dazuko_handle_request(), dazuko_set_option(), and dazuko_sys_check(). |
|
Definition at line 140 of file dazuko_xp.c. |
|
Definition at line 136 of file dazuko_xp.c. |
|
Definition at line 137 of file dazuko_xp.c. |
|
Definition at line 135 of file dazuko_xp.c. |
|
Definition at line 138 of file dazuko_xp.c. |
|
Definition at line 139 of file dazuko_xp.c. |
|
Definition at line 141 of file dazuko_xp.c. |
|
Definition at line 134 of file dazuko_xp.c. |
|
Definition at line 132 of file dazuko_xp.c. |
|
Definition at line 146 of file dazuko_xp.c. |
|
Definition at line 144 of file dazuko_xp.c. |
|
Definition at line 143 of file dazuko_xp.c. |
|
Definition at line 145 of file dazuko_xp.c. |