📄 atm_svr_processes.c
字号:
open_account_sem_buf.sem_flg = SEM_UNDO; if (semop(open_account_sem_id, &open_account_sem_buf, 1) < 0) { perror("SERVER: child process, open account p semop() failed %d\n"); exit (1); }#endif /* Get a new account */ if ((rtn = new_account(&id, &accountp)) < 0) { DPRINTF(("SERVER: open new_account failed, %s\n", atm_err_tbl[-rtn])); sprintf(resp_buf, "%d %d %d %s", TRANS_FAILURE, -1, -1, atm_err_tbl[-rtn]); } else { accountp->password = id; accountp->balance = 0; /* Store it back to the database */ if ((rtn = store_account(accountp)) < 0) { DPRINTF(("SERVER: open, store_account failed %s\n", atm_err_tbl[-rtn])); sprintf(resp_buf, "%d %d %d %s", TRANS_FAILURE, -1, -1, atm_err_tbl[-rtn]); } else { sprintf(resp_buf, "%d %d %d", TRANS_SUCCESS, id, id); } }#ifdef NO_DATABASE_SYNC#elif defined(SINGLE_DATABASE_SEM_SYNC) /* "v()" single database semaphore */ single_database_sem_buf.sem_num = 0; single_database_sem_buf.sem_op = 1; /* "v()" */ single_database_sem_buf.sem_flg = SEM_UNDO; if (semop(single_database_sem_id, &single_database_sem_buf, 1) < 0) { perror("SERVER child process, single_database v semop() failed %d\n"); exit (1); }#elif defined(ACCOUNT_SEM_SYNC) /* "v()" open account semaphore */ open_account_sem_buf.sem_num = 0; open_account_sem_buf.sem_op = 1; /* "v()" */ open_account_sem_buf.sem_flg = SEM_UNDO; if (semop(open_account_sem_id, &open_account_sem_buf, 1) < 0) { perror("SERVER child process, open account v semop() failed %d\n"); exit (1); }#endif}/************************************************************************** * Deposit money in an account. The account id and access password are * verified before the transaction is done. **************************************************************************/void deposit(char *req_buf, char *resp_buf){ int rtn; int temp, id, password, amount; account_t *accountp; /* Parse input string */ sscanf(req_buf, "%d %d %d %d ", &temp, &id, &password, &amount); DPRINTF(("SERVER: deposit, id %d, password %d, amount %d\n", id, password, amount)); /* Check inputs */ if ((id < 0) || (id >= MAX_NUM_ACCOUNTS)) { DPRINTF(("SERVER: deposit, %s\n", ERR_MSG_BAD_ACCOUNT)); sprintf(resp_buf, "%d %s", TRANS_FAILURE, ERR_MSG_BAD_ACCOUNT); return; }#ifdef NO_DATABASE_SYNC#elif defined(SINGLE_DATABASE_SEM_SYNC) /* "p()" single database semaphore */ single_database_sem_buf.sem_num = 0; single_database_sem_buf.sem_op = -1; /* "p()" */ single_database_sem_buf.sem_flg = SEM_UNDO; if (semop(single_database_sem_id, &single_database_sem_buf, 1) < 0) { perror("SERVER: child process, single database p semop() failed %d\n"); exit (1); }#elif defined(ACCOUNT_SEM_SYNC) /* "p()" account semaphore */ account_sem_buf.sem_num = account_sem_array[id].sem_num; account_sem_buf.sem_op = -1; /* "p()" */ account_sem_buf.sem_flg = SEM_UNDO; if (semop(account_sem_array[id].set_id, &account_sem_buf, 1) < 0) { perror("SERVER: child process, account sem p semop() failed %d\n"); exit (1); }#endif /* Retrieve account from database */ if ((rtn = retrieve_account( id, &accountp)) < 0) { DPRINTF(("SERVER: deposit, retrieve_account failed %s\n", atm_err_tbl[-rtn])); sprintf(resp_buf, "%d %s", TRANS_FAILURE, atm_err_tbl[-rtn]); /* Check password */ } else if (password != accountp->password) { DPRINTF(("SERVER: deposit, %s\n", ERR_MSG_BAD_PASSWORD)); sprintf(resp_buf, "%d %s", TRANS_FAILURE, ERR_MSG_BAD_PASSWORD); /* Add new balance */ } else { (accountp->balance) += amount; /* Store back to database */ if ((rtn = store_account(accountp)) < 0) { DPRINTF(("SERVER: deposit, store_account failed %s\n", atm_err_tbl[-rtn])); sprintf(resp_buf, "%d %d %d %s", TRANS_FAILURE, -1, -1, atm_err_tbl[-rtn]); /* Everything OK */ } else { sprintf(resp_buf, "%d", TRANS_SUCCESS); } }#ifdef NO_DATABASE_SYNC#elif defined(SINGLE_DATABASE_SEM_SYNC) /* "v()" single database semaphore */ single_database_sem_buf.sem_num = 0; single_database_sem_buf.sem_op = 1; /* "v()" */ single_database_sem_buf.sem_flg = SEM_UNDO; if (semop(single_database_sem_id, &single_database_sem_buf, 1) < 0) { perror("SERVER child process, single_database v semop() failed %d\n"); exit (1); }#elif defined(ACCOUNT_SEM_SYNC) /* "v()" account semaphore */ account_sem_buf.sem_num = account_sem_array[id].sem_num; account_sem_buf.sem_op = 1; /* "v()" */ account_sem_buf.sem_flg = SEM_UNDO; if (semop(account_sem_array[id].set_id, &account_sem_buf, 1) < 0) { perror("SERVER child process, account sem v semop() failed %d\n"); exit (1); }#endif}/************************************************************************** * Remove money from an account. The account id and access password are * verified, and sufficient funds must be available for the transaction * to proceed. **************************************************************************/void withdraw(char *req_buf, char *resp_buf){ int rtn; int temp, id, password, amount; account_t *accountp; /* Parse input string */ sscanf(req_buf, "%d %d %d %d", &temp, &id, &password, &amount); DPRINTF(("SERVER: withdraw, id %d, password %d, amount %d\n", id, password, amount)); /* Check inputs */ if ((id < 0) || (id >= MAX_NUM_ACCOUNTS)) { DPRINTF(("SERVER: withdraw, %s", ERR_MSG_BAD_ACCOUNT)); sprintf(resp_buf, "%d %s", TRANS_FAILURE, ERR_MSG_BAD_ACCOUNT); return; }#ifdef NO_DATABASE_SYNC#elif defined(SINGLE_DATABASE_SEM_SYNC) /* "p()" single database semaphore */ single_database_sem_buf.sem_num = 0; single_database_sem_buf.sem_op = -1; /* "p()" */ single_database_sem_buf.sem_flg = SEM_UNDO; if (semop(single_database_sem_id, &single_database_sem_buf, 1) < 0) { perror("SERVER: child process, single database p semop() failed %d\n"); exit (1); }#elif defined(ACCOUNT_SEM_SYNC) /* "p()" account semaphore */ account_sem_buf.sem_num = account_sem_array[id].sem_num; account_sem_buf.sem_op = -1; /* "p()" */ account_sem_buf.sem_flg = SEM_UNDO; if (semop(account_sem_array[id].set_id, &account_sem_buf, 1) < 0) { perror("SERVER: child process, account sem p semop() failed %d\n"); exit (1); }#endif /* Retrieve account from database */ if ((rtn = retrieve_account( id, &accountp)) < 0) { DPRINTF(("SERVER: withdraw, retrieve_account failed %s\n", atm_err_tbl[-rtn])); sprintf(resp_buf, "%d %s", TRANS_FAILURE, atm_err_tbl[-rtn]); /* Check password */ } else if (password != accountp->password) { DPRINTF(("SERVER: withdraw, %s\n", ERR_MSG_BAD_PASSWORD)); sprintf(resp_buf, "%d %s", TRANS_FAILURE, ERR_MSG_BAD_PASSWORD); /* Check for funds */ } else if (amount > accountp->balance) { DPRINTF(("SERVER: withdraw, %s\n", ERR_MSG_INS_FUNDS)); return_account(accountp); sprintf(resp_buf, "%d %s", TRANS_FAILURE, ERR_MSG_INS_FUNDS); /* Compute new balance */ } else { accountp->balance -= amount; if ((rtn = store_account(accountp)) < 0) { DPRINTF(("SERVER: withdraw, store_account failed %s\n", atm_err_tbl[-rtn])); sprintf(resp_buf, "%d %d %d %s", TRANS_FAILURE, -1, -1, atm_err_tbl[-rtn]); } else { sprintf(resp_buf, "%d", TRANS_SUCCESS); } }#ifdef NO_DATABASE_SYNC#elif defined(SINGLE_DATABASE_SEM_SYNC) /* "v()" single database semaphore */ single_database_sem_buf.sem_num = 0; single_database_sem_buf.sem_op = 1; /* "v()" */ single_database_sem_buf.sem_flg = SEM_UNDO; if (semop(single_database_sem_id, &single_database_sem_buf, 1) < 0) { perror("SERVER child process, single_database v semop() failed %d\n"); exit (1); }#elif defined(ACCOUNT_SEM_SYNC) /* "v()" account semaphore */ account_sem_buf.sem_num = account_sem_array[id].sem_num; account_sem_buf.sem_op = 1; /* "v()" */ account_sem_buf.sem_flg = SEM_UNDO; if (semop(account_sem_array[id].set_id, &account_sem_buf, 1) < 0) { perror("SERVER child process, account sem v semop() failed %d\n"); exit (1); }#endif}/************************************************************************** * Provide the current balance in an account. Account id and access password * are verified. **************************************************************************/void balance(char *req_buf, char *resp_buf){ int rtn; int temp, id, password; int cur_bal; account_t *accountp; /* Parse input string */ sscanf(req_buf, "%c %d %d", &temp, &id, &password); DPRINTF(("SERVER: balance, id %d, password %d\n", id, password)); /* Check inputs */ if ((id < 0) || (id >= MAX_NUM_ACCOUNTS)) { DPRINTF(("SERVER: balance, %s", ERR_MSG_BAD_ACCOUNT)); sprintf(resp_buf, "%d %s", TRANS_FAILURE, ERR_MSG_BAD_ACCOUNT); return; }#ifdef NO_DATABASE_SYNC#elif defined(SINGLE_DATABASE_SEM_SYNC) /* "p()" single database semaphore */ single_database_sem_buf.sem_num = 0; single_database_sem_buf.sem_op = -1; /* "p()" */ single_database_sem_buf.sem_flg = SEM_UNDO; if (semop(single_database_sem_id, &single_database_sem_buf, 1) < 0) { perror("SERVER: child process, single database p semop() failed %d\n"); exit (1); }#elif defined(ACCOUNT_SEM_SYNC) /* "p()" account semaphore */ account_sem_buf.sem_num = account_sem_array[id].sem_num; account_sem_buf.sem_op = -1; /* "p()" */ account_sem_buf.sem_flg = SEM_UNDO; if (semop(account_sem_array[id].set_id, &account_sem_buf, 1) < 0) { perror("SERVER: child process, account sem p semop() failed %d\n"); exit (1); }#endif /* Retrieve account from database */ if ((rtn = retrieve_account( id, &accountp)) < 0) { DPRINTF(("SERVER: balance, retrieve_account failed %s\n", atm_err_tbl[-rtn])); sprintf(resp_buf, "%d %s", TRANS_FAILURE, atm_err_tbl[-rtn]); } else { /* Check password */ if (password != accountp->password) { DPRINTF(("SERVER: balance, %s\n", ERR_MSG_BAD_PASSWORD)); sprintf(resp_buf, "%d %s", TRANS_FAILURE, ERR_MSG_BAD_PASSWORD); } else { /* Get balance */ cur_bal = accountp->balance; sprintf(resp_buf, "%d %d", TRANS_SUCCESS, cur_bal); } return_account(accountp); } #ifdef NO_DATABASE_SYNC#elif defined(SINGLE_DATABASE_SEM_SYNC) /* "v()" single database semaphore */ single_database_sem_buf.sem_num = 0; single_database_sem_buf.sem_op = 1; /* "v()" */ single_database_sem_buf.sem_flg = SEM_UNDO; if (semop(single_database_sem_id, &single_database_sem_buf, 1) < 0) { perror("SERVER child process, single_database v semop() failed %d\n"); exit (1); }#elif defined(ACCOUNT_SEM_SYNC) /* "v()" account semaphore */ account_sem_buf.sem_num = account_sem_array[id].sem_num; account_sem_buf.sem_op = 1; /* "v()" */ account_sem_buf.sem_flg = SEM_UNDO; if (semop(account_sem_array[id].set_id, &account_sem_buf, 1) < 0) { perror("SERVER child process, account sem v semop() failed %d\n"); exit (1); }#endif}/************************************************************************** * Provide a means to remotely shutdown server. * Any valid account can do it under this simple scheme. **************************************************************************/int shutdown_req(char *req_buf, char *resp_buf){ int temp, password; /* Parse input string */ sscanf(req_buf, "%d %d %d", &temp, &password); DPRINTF(("SERVER: shutdown, password %d\n", password)); /* Check password */ if (check_server_password(password) != 1) { DPRINTF(("SERVER: shutdown_req, %s\n", ERR_MSG_BAD_PASSWORD)); sprintf(resp_buf, "%d %s", TRANS_FAILURE, ERR_MSG_BAD_PASSWORD); return 0; } else { /* ok, go ahead */ sprintf(resp_buf, "%d", TRANS_SUCCESS); return 1; }}/************************************************************************** * Respond to client when transaction is unrecognized. **************************************************************************/void handle_bad_trans_id(char *req_buf, char *resp_buf){ int trans_id; /* Parse input string */ sscanf(req_buf, "%d ", &trans_id); DPRINTF(("SERVER: bad transaction id, trans id %d\n", trans_id)); sprintf(resp_buf, "%d %s", TRANS_FAILURE, ERR_MSG_BAD_TRANSID);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -