summaryrefslogtreecommitdiffstats
path: root/mbbsd/passwd.c
blob: 28a311191b2b8d1f43e0ba8d93ba0b0e02992c1c (plain) (blame)
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/* $Id: passwd.c,v 1.1 2002/03/07 15:13:48 in2 Exp $ */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include "config.h"
#include "pttstruct.h"
#include "modes.h"
#include "proto.h"

extern char *fn_passwd;

static userec_t *passwd_image = NULL;
static int passwd_image_size;
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_mmap() {
    int fd;
    
    fd = open(fn_passwd, O_RDWR);
    if(fd > 0) 
    {
    struct stat st;
    
    fstat(fd, &st);
    passwd_image_size = st.st_size;
    passwd_image = mmap(NULL, passwd_image_size,
                PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if(passwd_image == (userec_t *)-1) {
        perror("mmap");
        return -1;
    }
/* rocker 011018: after success get mmap, close file descript */
    close (fd);
    
    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);
        }
    }
    } else {
    perror(fn_passwd);
    return -1;
    }
    return 0;
}

extern int usernum;
int passwd_update_money(int num) {
    int money;
    if(num < 1 || num > MAX_USERS)
        return -1;
    money = moneyof(num);
    memcpy(&passwd_image[num - 1].money, &money, sizeof(int));
    return 0;
}   

int passwd_update(int num, userec_t *buf) {
    if(num < 1 || num > MAX_USERS)
    return -1;
    buf->money = moneyof(num);
    memcpy(&passwd_image[num - 1], buf, sizeof(userec_t));
    return 0;
}

int passwd_query(int num, userec_t *buf) {
    if(num < 1 || num > MAX_USERS)
    return -1;
    memcpy(buf, &passwd_image[num - 1], sizeof(userec_t));
    return 0;
}

int passwd_apply(int (*fptr)(userec_t *)) {
    int i;

    for(i = 0; i < MAX_USERS; i++)
    if((*fptr)(&passwd_image[i]) == 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);
    }
}