/* $Id$ */ #include "bbs.h" static int semid = -1; #ifndef SEM_R #define SEM_R 0400 #endif #ifndef SEM_A #define SEM_A 0200 #endif #ifndef __FreeBSD__ union semun { int val; /* value for SETVAL */ struct semid_ds *buf; /* buffer for IPC_STAT & IPC_SET */ u_short *array; /* array for GETALL & SETALL */ struct seminfo *__buf; /* buffer for IPC_INFO */ }; #endif int passwd_init() { semid = semget(PASSWDSEM_KEY, 1, SEM_R | SEM_A | IPC_CREAT | IPC_EXCL); if (semid == -1) { if (errno == EEXIST) { semid = semget(PASSWDSEM_KEY, 1, SEM_R | SEM_A); if (semid == -1) { perror("semget"); exit(1); } } else { perror("semget"); exit(1); } } else { union semun s; s.val = 1; if (semctl(semid, 0, SETVAL, s) == -1) { perror("semctl"); exit(1); } } return 0; } int passwd_update_money(int num) /* update money only */ { userec_t user; int pwdfd, money = moneyof(num); char path[256]; if (num < 1 || num > MAX_USERS) return -1; sethomefile(path, getuserid(num), ".passwd"); if ((pwdfd = open(path, O_WRONLY)) < 0) { if(passwd_index_query(num, &user)<0) // tempory code, will be removed exit(1); user.money=money; passwd_update(num, &user); return 0; } if(lseek(pwdfd, (off_t)((int)&user.money - (int)&user), SEEK_SET) >= 0) write(pwdfd, &money, sizeof(int)); close(pwdfd); return 0; } int passwd_index_update(int num, userec_t * buf) { int pwdfd; if (num < 1 || num > MAX_USERS) return -1; buf->money = moneyof(num); if ((pwdfd = open(fn_passwd, O_WRONLY)) < 0) exit(1); lseek(pwdfd, sizeof(userec_t) * (num - 1), SEEK_SET); write(pwdfd, buf, sizeof(userec_t)); close(pwdfd); return 0; } int passwd_update(int num, userec_t * buf) { int pwdfd; char path[256]; if(!buf->userid[0]) return -1; sethomefile(path, buf->userid, ".passwd"); buf->money = moneyof(num); if ((pwdfd = open(path, O_WRONLY|O_CREAT, 0600)) < 0) return -1; write(pwdfd, buf, sizeof(userec_t)); close(pwdfd); return 0; } int passwd_index_query(int num, userec_t * buf) { int pwdfd; if (num < 1 || num > MAX_USERS) return -1; if ((pwdfd = open(fn_passwd, O_RDONLY)) < 0) exit(1); lseek(pwdfd, sizeof(userec_t) * (num - 1), SEEK_SET); read(pwdfd, buf, sizeof(userec_t)); close(pwdfd); return 0; } userec_t userecbuf; int initcuser(char *userid) { // Ptt: setup cuser and usernum here if(userid[0]=='\0') return -1; if(!(usernum = searchuser(userid)) || usernum > MAX_USERS) return -1; passwd_query(usernum, &userecbuf); cuser = &userecbuf; return usernum; } int passwd_query(int num, userec_t * buf) { int pwdfd; char path[256], *userid; if (num < 1 || num > MAX_USERS) return -1; userid = getuserid(num); if(userid[0]=='\0') return -1; sethomefile(path, userid, ".passwd"); if((pwdfd = open(path, O_RDONLY)) < 0) { // copy from index // tempory code, will be removed if(passwd_index_query(num, buf)<0) exit(1); passwd_update(num, buf); return 0; } read(pwdfd, buf, sizeof(userec_t)); close(pwdfd); return 0; } int passwd_apply(int (*fptr) (int, userec_t *)) { int i; userec_t user; for (i = 0; i < MAX_USERS; i++) { passwd_query(i + 1, &user); if ((*fptr) (i, &user) == QUIT) return QUIT; } return 0; } void passwd_lock() { struct sembuf buf = {0, -1, SEM_UNDO}; if (semop(semid, &buf, 1)) { perror("semop"); exit(1); } } void passwd_unlock() { struct sembuf buf = {0, 1, SEM_UNDO}; if (semop(semid, &buf, 1)) { perror("semop"); exit(1); } }