/* * リソースの獲得 */ StatusType GetResource(ResourceType resid) { StatusType ercd = E_OK; Priority ceilpri, curpri; LOG_GETRES_ENTER(resid); CHECK_CALLEVEL(TCL_TASK | TCL_ISR2); CHECK_RESID(resid); ceilpri = resinib_ceilpri[resid]; if (callevel == TCL_TASK) { CHECK_ACCESS(tinib_inipri[runtsk] <= ceilpri); lock_cpu(); D_CHECK_ACCESS(rescb_prevpri[resid] == TPRI_NULL); curpri = tcb_curpri[runtsk]; rescb_prevpri[resid] = curpri; rescb_prevres[resid] = tcb_lastres[runtsk]; tcb_lastres[runtsk] = resid; if (ceilpri > curpri) { tcb_curpri[runtsk] = ceilpri; if (ceilpri >= TPRI_MINISR) { set_ipl(ceilpri - TPRI_MINISR); } } } else { CHECK_ACCESS(isrinib_intpri[runisr] <= ceilpri); lock_cpu(); D_CHECK_ACCESS(rescb_prevpri[resid] == TPRI_NULL); curpri = current_ipl() + TPRI_MINISR; rescb_prevpri[resid] = curpri; rescb_prevres[resid] = isrcb_lastres[runisr]; isrcb_lastres[runisr] = resid; if (ceilpri > curpri) { set_ipl(ceilpri - TPRI_MINISR); } } exit: unlock_cpu(); LOG_GETRES_LEAVE(ercd); return(ercd); error_exit: lock_cpu(); d_error_exit: _errorhook_par1.resid = resid; call_errorhook(ercd, OSServiceId_GetResource); goto exit; }
/* * リソースの返却 */ StatusType ReleaseResource(ResourceType resid) { StatusType ercd = E_OK; LOG_RELRES_ENTER(resid); CHECK_CALLEVEL(TCL_TASK | TCL_ISR2); CHECK_RESID(resid); if (callevel == TCL_TASK) { CHECK_ACCESS(tinib_inipri[runtsk] <= resinib_ceilpri[resid]); CHECK_NOFUNC(tcb_lastres[runtsk] == resid); lock_cpu(); if (rescb_prevpri[resid] >= TPRI_MINISR) { set_ipl(rescb_prevpri[resid] - TPRI_MINISR); } else{ if (tcb_curpri[runtsk] >= TPRI_MINISR) { set_ipl(IPL_ENA_ALL); } } tcb_curpri[runtsk] = rescb_prevpri[resid]; tcb_lastres[runtsk] = rescb_prevres[resid]; rescb_prevpri[resid] = TPRI_NULL; if (tcb_curpri[runtsk] < nextpri) { preempt(); dispatch(); } } else { CHECK_ACCESS(isrinib_intpri[runisr] <= resinib_ceilpri[resid]); CHECK_NOFUNC(isrcb_lastres[runisr] == resid); lock_cpu(); set_ipl(rescb_prevpri[resid] - TPRI_MINISR); isrcb_lastres[runisr] = rescb_prevres[resid]; rescb_prevpri[resid] = TPRI_NULL; } exit: unlock_cpu(); LOG_RELRES_LEAVE(ercd); return(ercd); error_exit: lock_cpu(); _errorhook_par1.resid = resid; call_errorhook(ercd, OSServiceId_ReleaseResource); goto exit; }
/* * イベントのセット */ StatusType SetEvent(TaskType tskid, EventMaskType mask) { StatusType ercd = E_OK; LOG_SETEVT_ENTER(tskid, mask); CHECK_CALLEVEL(TCL_TASK | TCL_ISR2); CHECK_TSKID(tskid); CHECK_ACCESS(tskid < tnum_exttask); lock_cpu(); D_CHECK_STATE(tcb_tstat[tskid] != TS_DORMANT); tcb_curevt[tskid] |= mask; if ((tcb_curevt[tskid] & tcb_waievt[tskid]) != EVTMASK_NONE) { tcb_waievt[tskid] = EVTMASK_NONE; if ((make_runnable(tskid)) && (callevel == TCL_TASK)) { dispatch(); } } exit: unlock_cpu(); LOG_SETEVT_LEAVE(ercd); return(ercd); error_exit: lock_cpu(); d_error_exit: _errorhook_par1.tskid = tskid; _errorhook_par2.mask = mask; call_errorhook(ercd, OSServiceId_SetEvent); goto exit; }
/* * イベント待ち */ StatusType WaitEvent(EventMaskType mask) { StatusType ercd = E_OK; LOG_WAIEVT_ENTER(mask); CHECK_CALLEVEL(TCL_TASK); CHECK_ACCESS(runtsk < tnum_exttask); CHECK_RESOURCE(tcb_lastres[runtsk] == RESID_NULL); lock_cpu(); if ((tcb_curevt[runtsk] & mask) == EVTMASK_NONE) { tcb_curpri[runtsk] = tinib_inipri[runtsk]; tcb_tstat[runtsk] = TS_WAITING; tcb_waievt[runtsk] = mask; search_schedtsk(); dispatch(); tcb_curpri[runtsk] = tinib_exepri[runtsk]; } exit: unlock_cpu(); LOG_WAIEVT_LEAVE(ercd); return(ercd); error_exit: lock_cpu(); _errorhook_par1.mask = mask; call_errorhook(ercd, OSServiceId_WaitEvent); goto exit; }
/* * イベントの状態参照 */ StatusType GetEvent(TaskType tskid, EventMaskRefType p_mask) { StatusType ercd = E_OK; LOG_GETEVT_ENTER(tskid, p_mask); CHECK_CALLEVEL(TCL_TASK | TCL_ISR2 | TCL_ERROR | TCL_PREPOST); CHECK_TSKID(tskid); CHECK_ACCESS(tskid < tnum_exttask); lock_cpu(); D_CHECK_STATE(tcb_tstat[tskid] != TS_DORMANT); *p_mask = tcb_curevt[tskid]; exit: unlock_cpu(); LOG_GETEVT_LEAVE(ercd, *p_mask); return(ercd); error_exit: lock_cpu(); d_error_exit: _errorhook_par1.tskid = tskid; _errorhook_par2.p_mask = p_mask; call_errorhook(ercd, OSServiceId_GetEvent); goto exit; }
/* * イベントのクリア */ StatusType ClearEvent(EventMaskType mask) { StatusType ercd = E_OK; LOG_CLREVT_ENTER(mask); CHECK_CALLEVEL(TCL_TASK); CHECK_ACCESS(runtsk < tnum_exttask); lock_cpu(); tcb_curevt[runtsk] &= ~mask; exit: unlock_cpu(); LOG_CLREVT_LEAVE(ercd); return(ercd); error_exit: lock_cpu(); _errorhook_par1.mask = mask; call_errorhook(ercd, OSServiceId_ClearEvent); goto exit; }
/* PUBLIC HTVMS_checkAccess() ** CHECKS ACCESS TO FILE FOR CERTAIN USER ** ON ENTRY: ** FileName The file to be accessed ** UserName Name of the user to check access for. ** User nobody, represented by "" is given NO for an answer ** Method Name of the method to be chceked ** ** ON EXIT: ** returns YES if access is allowed ** */ PUBLIC BOOL HTVMS_checkAccess ARGS3( CONST char *, FileName, CONST char *, UserName, CONST char *, Method) { unsigned long Result; ItemStruct ItemList[2]; unsigned long Length; unsigned long Buffer; unsigned long ObjType; char *VmsName; struct dsc$descriptor_s FileNameDesc; struct dsc$descriptor_s UserNameDesc; char *colon; /* user nobody should access as from account under which server is running */ if (0 == strcmp(UserName,"")) return(NO); /* check Filename and convert */ colon = strchr(FileName,':'); if (colon) VmsName = HTVMS_name("",colon+1); else VmsName = HTVMS_name("",FileName); /* check for GET */ if (0 == strcmp(Method,"GET")) { /* fill Item */ ItemList[0].BufferLength = sizeof(Buffer); ItemList[0].BufferAddress = &Buffer; ItemList[0].ReturnLengthAddress = &Length; ItemList[0].ItemCode = CHP$_FLAGS; /* terminate list */ ItemList[1].ItemCode = 0; ItemList[1].BufferLength = 0; /* fill input */ ObjType = ACL$C_FILE; Buffer = CHP$M_READ; UserNameDesc.dsc$w_length = strlen(UserName); UserNameDesc.dsc$b_dtype = DSC$K_DTYPE_T; UserNameDesc.dsc$b_class = DSC$K_CLASS_S; UserNameDesc.dsc$a_pointer = UserName; FileNameDesc.dsc$w_length = strlen(VmsName); FileNameDesc.dsc$b_dtype = DSC$K_DTYPE_T; FileNameDesc.dsc$b_class = DSC$K_CLASS_S; FileNameDesc.dsc$a_pointer = VmsName; /* call system */ Result = SYS$CHECK_ACCESS(&ObjType,&FileNameDesc,&UserNameDesc,ItemList); if (Result == SS$_NORMAL) return(YES); else return(NO); } return(NO); }
/* PUBLIC HTVMS_checkAccess() ** CHECKS ACCESS TO FILE FOR CERTAIN USER ** ON ENTRY: ** FileName The file to be accessed ** UserName Name of the user to check access for. ** User nobody, represented by "" is given NO for an answer ** Method Method to be checked for ** 'method' 'access reuired' ** METHOD_GET read ** METHOD_HEAD read ** ** ON EXIT: ** returns YES if access is allowed ** ** Not only filename is checked but also filename.dir... ** */ PUBLIC BOOL HTVMS_checkAccess ARGS3( CONST char *, FileName, CONST char *, UserName, HTMethod, Method) { unsigned long Result; ItemStruct ItemList[2]; unsigned long Flags; unsigned long FlagsLength; unsigned long Access; unsigned long AccessLength; unsigned long ObjType; char *VmsName; char Fname[256]; struct dsc$descriptor_s FileNameDesc; struct dsc$descriptor_s UserNameDesc; char *colon; /* user nobody should access as from account under which server is running */ if (0 == strcmp(UserName,"")) { CTRACE(stderr, "VMSAccess... No access allowed user nobody. Error in rulefile specifying 'nobody' as uid for protect rule\n"); return(NO); } /* make local copy */ strcpy(Fname,FileName); /* strip off last slash anyway */ if (Fname[strlen(Fname)-1] == '/') Fname[strlen(Fname)-1] = '\0'; /* check Filename and convert */ colon = strchr(Fname,':'); if (colon) VmsName = HTVMS_name("",colon+1); else VmsName = HTVMS_name("",Fname); /* check for GET */ if ((Method == METHOD_GET) || (Method == METHOD_HEAD)) { Access = ARM$M_READ; Flags = CHP$M_READ; /* fill Access */ ItemList[0].BufferLength = sizeof(Access); ItemList[0].BufferAddress = &Access; ItemList[0].ReturnLengthAddress = &AccessLength; ItemList[0].ItemCode = CHP$_ACCESS; /* fill Flags */ ItemList[1].BufferLength = sizeof(Flags); ItemList[1].BufferAddress = &Flags; ItemList[1].ReturnLengthAddress = &FlagsLength; ItemList[1].ItemCode = CHP$_FLAGS; /* terminate list */ ItemList[2].ItemCode = 0; ItemList[2].BufferLength = 0; /* fill input */ ObjType = ACL$C_FILE; UserNameDesc.dsc$w_length = strlen(UserName); UserNameDesc.dsc$b_dtype = DSC$K_DTYPE_T; UserNameDesc.dsc$b_class = DSC$K_CLASS_S; UserNameDesc.dsc$a_pointer = UserName; FileNameDesc.dsc$w_length = strlen(VmsName); FileNameDesc.dsc$b_dtype = DSC$K_DTYPE_T; FileNameDesc.dsc$b_class = DSC$K_CLASS_S; FileNameDesc.dsc$a_pointer = VmsName; /* call system for filename */ Result = SYS$CHECK_ACCESS(&ObjType,&FileNameDesc,&UserNameDesc,ItemList); if (Result == SS$_NORMAL) return(YES); /* try with extension .dir... */ strcat(VmsName,".dir"); FileNameDesc.dsc$w_length = strlen(VmsName); Result = SYS$CHECK_ACCESS(&ObjType,&FileNameDesc,&UserNameDesc,ItemList); if (Result == SS$_NORMAL) return(YES); /* failed for filename and .dir */ CTRACE(stderr, "VMSAccess... No access allowed for user '%s', file '%s' under method '%s'\n",UserName,Fname,HTMethod_name(Method)); return(NO); } CTRACE(stderr, "VMSAccess... No access allowed for method '%s'\n",HTMethod_name(Method)); return(NO); }