📄 protocol_c.c
字号:
/* Copyright (C) 2002 Mikael Ylikoski * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, Version 2 as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. *//** * @file * Classification daemon protocol, client side. * Helper functions for Select clients. * * \todo Check for buffer overruns (pd->bp >= pd->buf + pd->len). * * @author Mikael Ylikoski * @date 2002 */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/socket.h>#include <sys/un.h>#include <unistd.h>#include "protocol_c.h"/** * Client protocol data. */struct protocol_c_data_ { int sockfd; /**< Socket file descriptor */ char *buf; /**< Input/Output buffer */ char *bp; /**< Input/Output buffer pointer */ int blen; /**< Input/Output buffer length */ int len; /**< Currently used input buffer length */ struct sockaddr_un addr; /**< Socket address */};/** * Create a new protocol session data structure. */protocol_c_data *protocol_c_new (int len, const char *addr) { int i; protocol_c_data *pd; pd = malloc (sizeof(protocol_c_data)); if (!pd) return NULL; pd->buf = malloc (len + 1); if (!pd->buf) { free (pd); return NULL; } pd->bp = pd->buf; pd->blen = len; pd->len = 0; pd->sockfd = -1; pd->addr.sun_family = AF_UNIX; memset (pd->addr.sun_path, 0, sizeof(pd->addr.sun_path)); if (!addr) addr = "@my_select_classifier"; i = strlen (addr); if (i > sizeof(pd->addr.sun_path) - 1) i = sizeof(pd->addr.sun_path) - 1; memcpy (pd->addr.sun_path, addr, i); if (pd->addr.sun_path[0] == '@') pd->addr.sun_path[0] = 0; return pd;}/** * Free protocol data. * * @param pd protocol data to free */voidprotocol_c_free (protocol_c_data *pd) { if (pd->sockfd >= 0) close (pd->sockfd); free (pd->buf); free (pd);}/** * Send a message. * * @param pd protocol session data * @return Zero if ok, or nonzero otherwise. */static intprotocol_send (protocol_c_data *pd) { int i, j; //pd->bp[0] = '\0'; //printf ("send<%s>\n", pd->buf); *pd->bp = '\n'; j = pd->bp - pd->buf + 1; i = send (pd->sockfd, pd->buf, j, 0); pd->bp = pd->buf; pd->len = 0; if (i == j) return 0; return -1;}/** * Receive a message. * * @param pd protocol session data * @return Zero if ok, or nonzero otherwise. */static intprotocol_receive (protocol_c_data *pd) { int i; /* if (pd->bp - pd->buf < pd->len) return 0; */ pd->bp = pd->buf; i = recv (pd->sockfd, pd->bp, pd->blen, 0); if (i < 1) { fprintf (stderr, "Error: No data!\n"); return -1; } pd->len = i; if (pd->len == pd->blen) { fprintf (stderr, "Error: Too much data!\n"); return -1; } pd->buf[pd->len] = '\0'; //printf ("recv<%s>\n", pd->buf); return 0;}/** * Make an open request. * * @param pd protocol session data * @return Zero if ok, or nonzero otherwise. */intprotocol_c_open (protocol_c_data *pd) { int i; pd->bp = pd->buf; pd->bp += sprintf (pd->buf, "open"); pd->len = 0; pd->sockfd = socket (PF_UNIX, SOCK_STREAM, 0); if (pd->sockfd == -1) { fprintf (stderr, "Error creating socket\n"); return -1; } i = connect (pd->sockfd, (struct sockaddr *)&pd->addr, sizeof(pd->addr)); if (i) { fprintf (stderr, "Error connecting socket\n"); return -1; } i = protocol_send (pd); if (i) { fprintf (stderr, "Error sending message\n"); return -1; } /* Receive ack */ //protocol_wait_ok (pd); return 0;}/** * Send a close request. * * @param pd protocol session data * @return Zero if ok, or nonzero otherwise. */intprotocol_c_close (protocol_c_data *pd) { pd->bp = pd->buf; pd->bp += sprintf (pd->bp, "close\n"); protocol_send (pd); close (pd->sockfd); pd->sockfd = -1; return 0;}intprotocol_c_part (protocol_c_data *pd, const char *type, const char *charset, const char *string, int len) { int i; pd->bp = pd->buf; pd->bp += sprintf (pd->bp, "part:"); /* type */ i = strlen (type); memcpy (pd->bp, type, i); pd->bp += i; *pd->bp = ':'; pd->bp++; /* charset */ if (charset) { i = strlen (charset); memcpy (pd->bp, charset, i); pd->bp += i; } *pd->bp = ':'; pd->bp++; /* len */ pd->bp += sprintf (pd->bp, "%d", len); *pd->bp = ':'; pd->bp++; /* string */ memcpy (pd->bp, string, len); pd->bp += len; return protocol_send (pd);}intprotocol_c_learn (protocol_c_data *pd, int class) { pd->bp = pd->buf; pd->bp += sprintf (pd->bp, "learn:%d", class); return protocol_send (pd);}intprotocol_c_learn_folder (protocol_c_data *pd, const char *class) { pd->bp = pd->buf; pd->bp += sprintf (pd->bp, "learn:\"%s\"", class); return protocol_send (pd);}intprotocol_c_unlearn (protocol_c_data *pd, int class) { pd->bp = pd->buf; pd->bp += sprintf (pd->bp, "unlearn:%d", class); return protocol_send (pd);}intprotocol_c_unlearn_folder (protocol_c_data *pd, const char *class) { pd->bp = pd->buf; pd->bp += sprintf (pd->bp, "unlearn:\"%s\"", class); return protocol_send (pd);}static double_array *protocol_get_scorelist (protocol_c_data *pd) { char *ch; int i; double_array *dl; if (strncmp (pd->bp, "s:", 2)) return NULL; pd->bp += 2; i = strtol (pd->bp, &ch, 10); if (ch == pd->bp) return NULL; pd->bp = ch; if (*pd->bp != ':') return NULL; pd->bp++; dl = malloc (sizeof(double_array)); if (!dl) return NULL; if (i < 1) { dl->array = NULL; dl->len = 0; } else { dl->array = malloc (i * sizeof(double)); if (!dl->array) { free (dl); return NULL; } dl->len = i; for (i = 0; i < dl->len; i++) { dl->array[i] = strtod (pd->bp, &ch); pd->bp = ch; pd->bp++; // assert (pd->ibp == ';') } } if (*pd->bp != '\n') { free (dl->array); free (dl); return NULL; } pd->bp++; return dl;}static int *protocol_get_ranklist (protocol_c_data *pd) { char *ch; int i, j, *il; if (strncmp (pd->bp, "r:", 2)) return NULL; pd->bp += 2; i = strtol (pd->bp, &ch, 10); pd->bp = ch; pd->bp++; // assert (pd->ibp == ':') if (0 && i < 1) { // FIXME il = NULL; } else { il = malloc ((i + 1) * sizeof(double)); if (!il) return NULL; for (j = 0; j < i; j++) { il[j] = strtol(pd->bp, &ch, 10); pd->bp = ch; pd->bp++; // assert (pd->ibp == ';') } il[j] = -1; } if (*pd->bp != '\n') fprintf(stderr, "Error in classification answer!\n"); pd->bp++; return il;}double_array *protocol_c_classify_score (protocol_c_data *pd, const char *str) { int i; /* Send message */ pd->bp = pd->buf; pd->bp += sprintf (pd->bp, "classify:%s:s", str); i = protocol_send (pd); if (i) return NULL; /* Receive message */ i = protocol_receive (pd); if (i) return NULL; return protocol_get_scorelist (pd);}int *protocol_c_classify_rank (protocol_c_data *pd, const char *str) { int i; /* Send request */ pd->bp = pd->buf; pd->bp += sprintf (pd->bp, "classify:%s:r", str); i = protocol_send (pd); if (i) return NULL; /* Receive answer */ i = protocol_receive (pd); if (i) return NULL; return protocol_get_ranklist (pd);}intprotocol_c_classify_top (protocol_c_data *pd, const char *str) { int i, *il; /* Send request */ pd->bp = pd->buf; pd->bp += sprintf (pd->bp, "classify:%s:t", str); i = protocol_send (pd); if (i) return -1; /* Receive answer */ i = protocol_receive (pd); if (i) return -1; il = protocol_get_ranklist (pd); if (!il) return -1; i = il[0]; free (il); return i;}static str_array *protocol_get_table (protocol_c_data *pd) { char *ch, **sl; int i, j, k; str_array *sa; sa = malloc (sizeof(str_array)); if (!sa) return NULL; if (strncmp (pd->bp, "l:", 2)) return NULL; pd->bp += 2; i = strtol (pd->bp, &ch, 10); pd->bp = ch; pd->bp++; // assert (pd->bp == ':') if (i < 1) { sl = NULL; } else { sl = malloc (i * sizeof(char *)); if (!sl) return NULL; for (j = 0; j < i; j++) { k = strtol (pd->bp, &ch, 10); pd->bp = ch; pd->bp++; // assert (pd->bp == '=') ch = strchr (pd->bp, ';'); // assert (ch != NULL) sl[k] = malloc (ch - pd->bp + 1); // assert (sl[i] != NULL) memcpy (sl[k], pd->bp, ch - pd->bp); sl[k][ch - pd->bp] = '\0'; pd->bp = ch + 1; } } if (*pd->bp != '\n') fprintf(stderr, "Error in table answer!\n"); pd->bp++; sa->len = i; sa->array = sl; return sa;}str_array *protocol_c_get_table (protocol_c_data *pd, const char *key) { int i; /* Send request */ pd->bp = pd->buf; pd->bp += sprintf (pd->bp, "get:%s", key); i = protocol_send (pd); if (i) return NULL; /* Receive answer */ i = protocol_receive (pd); if (i) return NULL; return protocol_get_table (pd);}intprotocol_c_get_integer (protocol_c_data *pd, const char *key) { int i; char *ch; /* Send request */ pd->bp = pd->buf; pd->bp += sprintf (pd->bp, "get:%s", key); i = protocol_send (pd); if (i) return -1; /* Receive answer */ i = protocol_receive (pd); if (i) return -1; i = strtol (pd->bp, &ch, 10); if (ch == pd->bp || *ch != '\n') return -1; pd->bp = ch + 1; return i;}char *protocol_c_get_string (protocol_c_data *pd, const char *key) { int i; char *res; /* Send request */ pd->bp = pd->buf; pd->bp += sprintf (pd->bp, "get:%s", key); i = protocol_send (pd); if (i) return NULL; /* Receive answer */ i = protocol_receive (pd); if (i) return NULL; res = malloc (sizeof(char *) * (pd->len + 1)); memcpy (res, pd->buf, pd->len); res[pd->len] = '\0'; return res;}intprotocol_c_set (protocol_c_data *pd, const char *key, const char *value) { int i; /* Send request */ pd->bp = pd->buf; pd->bp += sprintf (pd->bp, "set:%s:%s", key, value); i = protocol_send (pd); if (i) return -1; /* Receive answer */ i = protocol_receive (pd); if (i) return -1; // FIXME Check answer return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -