1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
|
/* $Id: passwd.c,v 1.3 2002/06/30 14:33:14 in2 Exp $ */
#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 PASSWDfd;
int passwd_mmap() {
if( (PASSWDfd = open(fn_passwd, O_RDWR)) < 0 || PASSWDfd <= 1 )
return -1;
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) {
userec_t user;
if(num < 1 || num > MAX_USERS)
return -1;
passwd_query(num, &user);
user.money = moneyof(num);
passwd_update(num, &user);
return 0;
}
int passwd_update(int num, userec_t *buf) {
if(num < 1 || num > MAX_USERS)
return -1;
buf->money = moneyof(num);
lseek(PASSWDfd, sizeof(userec_t) * (num - 1), SEEK_SET);
write(PASSWDfd, buf, sizeof(userec_t));
return 0;
}
int passwd_query(int num, userec_t *buf) {
if(num < 1 || num > MAX_USERS)
return -1;
lseek(PASSWDfd, sizeof(userec_t) * (num - 1), SEEK_SET);
read(PASSWDfd, buf, sizeof(userec_t));
return 0;
}
int passwd_apply(int (*fptr)(userec_t *)) {
int i;
userec_t user;
for(i = 0; i < MAX_USERS; i++){
passwd_query(i + 1, &user);
if((*fptr)(&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);
}
}
|