SEXP store_password(SEXP svc, SEXP usr, SEXP pwd) { OSStatus status; SecKeychainRef kc = NULL; /* default */ const char *un, *sn, *pw; char *svc_name; int l; if (TYPEOF(svc) != STRSXP || LENGTH(svc) != 1) Rf_error("Invalid service name"); if (TYPEOF(pwd) != STRSXP || LENGTH(pwd) != 1) Rf_error("Invalid password"); pw = Rf_translateCharUTF8(STRING_ELT(pwd, 0)); if (usr == R_NilValue) { un = getlogin(); if (!un) Rf_error("Unable to get current user name via getlogin()"); } else { if (TYPEOF(usr) != STRSXP || LENGTH(usr) != 1) Rf_error("Invalid user name (must be a character vector of length one)"); un = Rf_translateCharUTF8(STRING_ELT(usr, 0)); } sn = Rf_translateCharUTF8(STRING_ELT(svc, 0)); l = strlen(sn); if (l > sizeof(buf) - 16) { svc_name = (char*) malloc(l + 16); if (!svc_name) Rf_error("Cannot allocate memory for service name"); } else svc_name = buf; /* we are enforcing R.keychain. prefix to avoid abuse to access other system keys */ strcpy(svc_name, SEC_PREFIX); strcat(svc_name, sn); status = SecKeychainAddGenericPassword(kc, strlen(svc_name), svc_name, strlen(un), un, strlen(pw), pw, NULL); if (svc_name != buf) free(svc_name); chk_status(status, "add"); return R_NilValue; }
SEXP find_password(SEXP svc, SEXP usr, SEXP new_pwd, SEXP quiet, SEXP del) { SEXP res; OSStatus status; SecKeychainRef kc = NULL; /* default */ SecKeychainItemRef kci; const char *un, *sn; char *svc_name; void *pwd; UInt32 pwd_len = 0; int l; int silent = Rf_asInteger(quiet) == 1; int do_rm = Rf_asInteger(del) == 1; int modify = 0; if (TYPEOF(svc) != STRSXP || LENGTH(svc) != 1) Rf_error("Invalid service name"); if (new_pwd != R_NilValue && (TYPEOF(new_pwd) != STRSXP || LENGTH(new_pwd) != 1)) Rf_error("Invalid password"); if (new_pwd != R_NilValue || do_rm) modify = 1; if (usr == R_NilValue) { un = getlogin(); if (!un) Rf_error("Unable to get current user name via getlogin()"); } else { if (TYPEOF(usr) != STRSXP || LENGTH(usr) != 1) Rf_error("Invalid user name (must be a character vector of length one)"); un = Rf_translateCharUTF8(STRING_ELT(usr, 0)); } sn = Rf_translateCharUTF8(STRING_ELT(svc, 0)); l = strlen(sn); if (l > sizeof(buf) - 16) { svc_name = (char*) malloc(l + 16); if (!svc_name) Rf_error("Cannot allocate memory for service name"); } else svc_name = buf; /* we are enforcing R.keychain. prefix to avoid abuse to access other system keys */ strcpy(svc_name, SEC_PREFIX); strcat(svc_name, sn); status = SecKeychainFindGenericPassword(kc, strlen(svc_name), svc_name, strlen(un), un, &pwd_len, &pwd, modify ? &kci : NULL); if (svc_name != buf) free(svc_name); if (silent && status == errSecItemNotFound) return R_NilValue; chk_status(status, "find"); res = PROTECT(Rf_ScalarString(Rf_mkCharLenCE(pwd, pwd_len, CE_UTF8))); /* FIXME: we'll leak if the above fails in R */ SecKeychainItemFreeContent(NULL, pwd); if (do_rm) { status = SecKeychainItemDelete(kci); chk_status(status, "delete"); } else if (new_pwd != R_NilValue) { /* set a new one */ const char *np = Rf_translateCharUTF8(STRING_ELT(new_pwd, 0)); status = SecKeychainItemModifyContent(kci, NULL, strlen(np), np); chk_status(status, "modify"); } UNPROTECT(1); return res; }
void gen_interupt() { if (stop == 1) { dyna_stop(); } if (savestates_job & LOADSTATE) { savestates_load(); savestates_job &= ~LOADSTATE; return; } if (skip_jump) { if (q->count > Count || (Count - q->count) < 0x80000000) { next_interupt = q->count; } else { next_interupt = 0; } interp_addr = skip_jump; last_addr = interp_addr; skip_jump=0; return; } switch(q->type) { case SPECIAL_INT: if (Count > 0x10000000) { return; } remove_interupt_event(); add_interupt_event_count(SPECIAL_INT, 0); return; break; case VI_INT: updateScreen(); #ifdef PROFILE refresh_stat(); #endif new_vi(); vi_register.vi_delay = (vi_register.vi_v_sync == 0) ? 500000 : ((vi_register.vi_v_sync + 1)*1500); next_vi += vi_register.vi_delay; vi_field = (vi_register.vi_status&0x40) ? 1-vi_field : 0; remove_interupt_event(); add_interupt_event_count(VI_INT, next_vi); MI_register.mi_intr_reg |= 0x08; if(!chk_status(1)) { return; } break; case COMPARE_INT: remove_interupt_event(); Count+=2; add_interupt_event_count(COMPARE_INT, Compare); Count-=2; Cause = (Cause | 0x8000) & 0xFFFFFF83; if(!chk_status(0)) { return; } break; case CHECK_INT: remove_interupt_event(); break; case SI_INT: PIF_RAMb[0x3F] = 0x0; remove_interupt_event(); MI_register.mi_intr_reg |= 0x02; si_register.si_status |= 0x1000; if(!chk_status(1)) { return; } break; case PI_INT: remove_interupt_event(); MI_register.mi_intr_reg |= 0x10; pi_register.read_pi_status_reg &= ~3; if(!chk_status(1)) { return; } break; case AI_INT: if (ai_register.ai_status & 0x80000000) { // full unsigned long ai_event = get_event(AI_INT); remove_interupt_event(); ai_register.ai_status &= ~0x80000000; ai_register.current_delay = ai_register.next_delay; ai_register.current_len = ai_register.next_len; add_interupt_event_count(AI_INT, ai_event+ai_register.next_delay); } else { remove_interupt_event(); ai_register.ai_status &= ~0x40000000; } MI_register.mi_intr_reg |= 0x04; if(!chk_status(1)) { return; } break; default: remove_interupt_event(); break; } exception_general(); if (savestates_job & SAVESTATE) { savestates_save(); savestates_job &= ~SAVESTATE; } }