⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 clientif.c

📁 《Beginning Linux Programming》书的配置实例源代码。
💻 C
字号:
// The file starts with #include files and constants.#define _POSIX_SOURCE#include <unistd.h>#include <stdlib.h>#include <stdio.h>#include <fcntl.h>#include <limits.h>#include <sys/types.h>#include <sys/stat.h>#include "cd_data.h"#include "cliserv.h"// The static variable mypid reduces the number of calls to getpid that would// otherwise be required.// We use a local function, read_one_response, to eliminate duplicated code.static pid_t mypid;static int read_one_response(message_db_t *rec_ptr);// The database_initialize and close routines are still called, but are now used, respectively,// for initializing the client-side of the pipes interface and for removing redundant named// pipes when the client exits.int database_initialize(const int new_database){    if (!client_starting()) return(0);    mypid = getpid();    return(1);    } /* database_initialize */void database_close(void) {    client_ending();}// The get_cdc_entry routine is called to get a catalog entry from the database,// given a CD catalog title.// Here we encode the request in a message_db_t structure and pass it to the server.// We then read the response back into a different message_db_t structure.// If an entry is found, it's included inside the message_db_t structure as a cdc_entry// structure, so we pass back the appropriate part of the structure.cdc_entry get_cdc_entry(const char *cd_catalog_ptr){    cdc_entry ret_val;    message_db_t mess_send;    message_db_t mess_ret;    ret_val.catalog[0] = '\0';    mess_send.client_pid = mypid;    mess_send.request = s_get_cdc_entry;    strcpy(mess_send.cdc_entry_data.catalog, cd_catalog_ptr);    if (send_mess_to_server(mess_send)) {        if (read_one_response(&mess_ret)) {            if (mess_ret.response == r_success) {                ret_val = mess_ret.cdc_entry_data;            } else {                fprintf(stderr, "%s", mess_ret.error_text);            }        } else {            fprintf(stderr, "Server failed to respond\n");        }    } else {        fprintf(stderr, "Server not accepting requests\n");    }    return(ret_val);}// Here's the source for the function read_one_response that we use to avoid duplicating code.static int read_one_response(message_db_t *rec_ptr) {    int return_code = 0;    if (!rec_ptr) return(0);        if (start_resp_from_server()) {        if (read_resp_from_server(rec_ptr)) {            return_code = 1;        }        end_resp_from_server();    }    return(return_code);} // The other get_xxx, del_xxx and add_xxx routines are implemented in a similar way to the// get_cdc_entry function and are reproduced here for completeness.// First, the function for retrieving CD tracks.cdt_entry get_cdt_entry(const char *cd_catalog_ptr, const int track_no){    cdt_entry ret_val;    message_db_t mess_send;    message_db_t mess_ret;    ret_val.catalog[0] = '\0';    mess_send.client_pid = mypid;    mess_send.request = s_get_cdt_entry;    strcpy(mess_send.cdt_entry_data.catalog, cd_catalog_ptr);    mess_send.cdt_entry_data.track_no = track_no;    if (send_mess_to_server(mess_send)) {        if (read_one_response(&mess_ret)) {            if (mess_ret.response == r_success) {                ret_val = mess_ret.cdt_entry_data;            } else {                fprintf(stderr, "%s", mess_ret.error_text);            }        } else {            fprintf(stderr, "Server failed to respond\n");        }    } else {        fprintf(stderr, "Server not accepting requests\n");    }    return(ret_val);}// Next, two functions for adding data, first to the catalog and then to the tracks database.int add_cdc_entry(const cdc_entry entry_to_add){    message_db_t mess_send;    message_db_t mess_ret;    mess_send.client_pid = mypid;    mess_send.request = s_add_cdc_entry;    mess_send.cdc_entry_data = entry_to_add;    if (send_mess_to_server(mess_send)) {        if (read_one_response(&mess_ret)) {            if (mess_ret.response == r_success) {                return(1);            } else {                fprintf(stderr, "%s", mess_ret.error_text);            }        } else {            fprintf(stderr, "Server failed to respond\n");        }    } else {        fprintf(stderr, "Server not accepting requests\n");    }    return(0);}int add_cdt_entry(const cdt_entry entry_to_add){    message_db_t mess_send;    message_db_t mess_ret;    mess_send.client_pid = mypid;    mess_send.request = s_add_cdt_entry;    mess_send.cdt_entry_data = entry_to_add;    if (send_mess_to_server(mess_send)) {        if (read_one_response(&mess_ret)) {            if (mess_ret.response == r_success) {                return(1);            } else {                fprintf(stderr, "%s", mess_ret.error_text);            }        } else {            fprintf(stderr, "Server failed to respond\n");        }    } else {        fprintf(stderr, "Server not accepting requests\n");    }    return(0);}// And lastly, two functions for data deletion.int del_cdc_entry(const char *cd_catalog_ptr){    message_db_t mess_send;    message_db_t mess_ret;    mess_send.client_pid = mypid;    mess_send.request = s_del_cdc_entry;    strcpy(mess_send.cdc_entry_data.catalog, cd_catalog_ptr);    if (send_mess_to_server(mess_send)) {        if (read_one_response(&mess_ret)) {            if (mess_ret.response == r_success) {                return(1);            } else {                fprintf(stderr, "%s", mess_ret.error_text);            }        } else {            fprintf(stderr, "Server failed to respond\n");        }    } else {        fprintf(stderr, "Server not accepting requests\n");    }    return(0);}int del_cdt_entry(const char *cd_catalog_ptr, const int track_no){    message_db_t mess_send;    message_db_t mess_ret;    mess_send.client_pid = mypid;    mess_send.request = s_del_cdt_entry;    strcpy(mess_send.cdt_entry_data.catalog, cd_catalog_ptr);    mess_send.cdt_entry_data.track_no = track_no;    if (send_mess_to_server(mess_send)) {        if (read_one_response(&mess_ret)) {            if (mess_ret.response == r_success) {                return(1);            } else {                fprintf(stderr, "%s", mess_ret.error_text);            }        } else {            fprintf(stderr, "Server failed to respond\n");        }    } else {        fprintf(stderr, "Server not accepting requests\n");    }    return(0);}// This function looks more complicated than it is because it calls three pipe functions// that we'll be looking at in the next section, send_mess_to_server, start_resp_from_server// and read_resp_from_server.cdc_entry search_cdc_entry(const char *cd_catalog_ptr, int *first_call_ptr){    message_db_t mess_send;    message_db_t mess_ret;        static FILE *work_file = (FILE *)0;    static int entries_matching = 0;    cdc_entry ret_val;    ret_val.catalog[0] = '\0';    if (!work_file && (*first_call_ptr == 0)) return(ret_val);// Here's the first call to search, i.e. with *first_call_ptr set to true.// It's set to false immediately, lest we forget. A work_file is created and the client// message structure initialized.    if (*first_call_ptr) {        *first_call_ptr = 0;        if (work_file) fclose(work_file);        work_file = tmpfile();        if (!work_file) return(ret_val);        mess_send.client_pid = mypid;        mess_send.request = s_find_cdc_entry;        strcpy(mess_send.cdc_entry_data.catalog, cd_catalog_ptr);// Now there's this three-deep condition test, which makes calls to functions in pipe_imp.c.// If the message is successfully sent to the server, the client waits for the server's response.// While reads from the server are successful, the search matches are returned to the client's// work_file and the entries_matching counter is incremented.        if (send_mess_to_server(mess_send)) {            if (start_resp_from_server()) {                while (read_resp_from_server(&mess_ret)) {                    if (mess_ret.response == r_success) {               fwrite(&mess_ret.cdc_entry_data, sizeof(cdc_entry), 1, work_file);                        entries_matching++;                    } else {                        break;                    }                } /* while */            } else {                fprintf(stderr, "Server not responding\n");            }        } else {            fprintf(stderr, "Server not accepting requests\n");        }// The next test checks whether the search had any luck.// Then the fseek call sets the work_file to the next place for data to be written.        if (entries_matching == 0) {            fclose(work_file);            work_file = (FILE *)0;            return(ret_val);        }              (void)fseek(work_file, 0L, SEEK_SET);// If this is not the first call to the search function with this particular search term,// the code checks whether there are any matches left. Finally, the next matching entry is// read to the ret_val structure. The previous checks guarantee that a matching entry exists.    } else {            /* not *first_call_ptr */        if (entries_matching == 0) {            fclose(work_file);            work_file = (FILE *)0;                        return(ret_val);        }    }    fread(&ret_val, sizeof(cdc_entry), 1, work_file);        entries_matching--;        return(ret_val);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -