Logo Search packages:      
Sourcecode: macopix version File versions  Download package

sockmsg.c

//  MaCoPiX = Mascot Construnctive Pilot for X
//                                (ActX / Gtk+ Evolution)
//
//
//      sockmsg.c
//      Management of Socket message function
//
//                            Copyright 2002-2008  K.Chimari
//                                     http://rosegray.sakura.ne.jp/
//
//
//  This program is free software; you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation; either version 2 of the License, or
//  (at your option) any later version.
// 
//  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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA.
//

#include "main.h"

#ifdef USE_SOCKMSG

#include <glib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/un.h>
#include <netdb.h>
#include <ctype.h>

#include "sockmsg.h"

extern gboolean flag_balloon;

gchar *cut_spc(gchar * obj_name);
static gchar *get_socket_name(void);
static gchar *get_duet_name(gchar *mascotname);
static gint fd_open_unix(const gchar *path);
static gint fd_connect_unix(const gchar *path);
static gint fd_accept(gint sock);
static gint fd_close(gint fd);
static gboolean io_callback(GIOChannel * source,
                      GIOCondition condition, gpointer data);
static gboolean io_callback_sv(GIOChannel * source,
                         GIOCondition condition, gpointer data);
SockMsgInitResult sockmsg_init(void);
SockMsgInitResult duet_sv_init(gchar *mascotname);
SockMsgInitResult duet_cl_init(gchar *mascotname);
void sockmsg_set_mascot(typMascot *mascot);
void duet_set_mascot(typMascot *mascot);
void sockmsg_send_msg(gchar *msg);
void duet_send_msg(gchar *msg);
void sockmsg_done(void);
void duet_sv_done(gchar *mascotname, gboolean flag_close);
void duet_cl_done(gchar *mascotname, gboolean flag_close);
#ifdef USE_GTK2
gchar* set_typing_msg();
gchar* my_strbuf();
#endif //USE_GTK2


gchar *cut_spc(gchar * obj_name){
  gchar *tgt_name=NULL, *ret_name, *c;
  gint  i_bak,i;
                                                                               
  tgt_name=g_strdup(obj_name);
  i_bak=strlen(tgt_name)-1;
  while((tgt_name[i_bak]==0x20)
        ||(tgt_name[i_bak]==0x0A)
        ||(tgt_name[i_bak]==0x0D)
        ||(tgt_name[i_bak]==0x09)){
    //tgt_name[i_bak]=(char)NULL;
    tgt_name[i_bak]=0x00;
    i_bak--;
  }
                                                                                
  c=tgt_name;
  i=0;
  while((tgt_name[i]==0x20)||(tgt_name[i]==0x09)){
    c++;
    i++;
  }

  return(tgt_name);
}


static gchar *get_socket_name(void)
{
  static gchar *filename = NULL;
  gchar *dirname = NULL;

  dirname = g_strdup_printf("%s%cmacopix-%d",
                      g_get_tmp_dir(), G_DIR_SEPARATOR, getuid());
  if (access(dirname, F_OK) != 0) {
    mkdir(dirname,(S_IRWXU|S_IRGRP|S_IROTH|S_IXGRP|S_IXOTH));
  }
  g_free(dirname);

  if (filename == NULL) {
    filename = g_strdup_printf("%s%cmacopix-%d%cmacopix",
                         g_get_tmp_dir(), G_DIR_SEPARATOR,
                         getuid(), G_DIR_SEPARATOR);
  }
  
  return filename;
}

static gchar *get_duet_name(gchar *mascotname)
{
  static gchar *filename = NULL;
  gchar *dirname = NULL;

  dirname = g_strdup_printf("%s%cmacopix-%d",
                      g_get_tmp_dir(), G_DIR_SEPARATOR, getuid());
  if (access(dirname, F_OK) != 0) {
    mkdir(dirname,(S_IRWXU|S_IRGRP|S_IROTH|S_IRGRP|S_IROTH));
  }
  g_free(dirname);
  
  filename = g_strdup_printf("%s%cmacopix-%d%cmacopix-%s",
                       g_get_tmp_dir(), 
                       G_DIR_SEPARATOR,
                       getuid(),
                       G_DIR_SEPARATOR,
                       mascotname);
  
  return filename;
}

static gint fd_open_unix(const gchar *path)
{
      gint sock;
      struct sockaddr_un addr;

      sock = socket(PF_UNIX, SOCK_STREAM, 0);

      if (sock < 0) {
            perror("sock_open_unix(): socket");
            return -1;
      }

      memset(&addr, 0, sizeof(addr));
      addr.sun_family = AF_UNIX;
      strncpy(addr.sun_path, path, sizeof(addr.sun_path) - 1);

      if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
            perror("bind");
            close(sock);
            return -1;
      }

      if (listen(sock, 1) < 0) {
            perror("listen");
            close(sock);
            return -1;        
      }

      return sock;
}

static gint fd_connect_unix(const gchar *path)
{
      gint sock;
      struct sockaddr_un addr;

      sock = socket(PF_UNIX, SOCK_STREAM, 0);
      if (sock < 0) {
            perror("sock_connect_unix(): socket");
            return -1;
      }

      memset(&addr, 0, sizeof(addr));
      addr.sun_family = AF_UNIX;
      strncpy(addr.sun_path, path, sizeof(addr.sun_path) - 1);

      if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
            close(sock);
            return -1;
      }

      return sock;
}

static gint fd_accept(gint sock)
{
      struct sockaddr_in caddr;
      gint caddr_len;

      caddr_len = sizeof(caddr);
      return accept(sock, (struct sockaddr *)&caddr, &caddr_len);
}

static gint fd_close(gint fd)
{
      return close(fd);
}

static gboolean io_callback(GIOChannel * source,
              GIOCondition condition, gpointer data)
{
  gchar buf[2048],tmp[10];
      gint fd, readsize;
      typMascot *mascot = data;
      gint step,mode;

      fd = fd_accept(g_io_channel_unix_get_fd(source));

      readsize = read(fd, buf, 2047);
      buf[readsize] = '\0';

      fd_close(fd);

      // Expiration
      strncpy(tmp,buf,8);
      mascot->sockmsg_expire=(gint)(atoi(tmp)/INTERVAL);
      if(mascot->sockmsg_expire<=0){
        mascot->sockmsg_expire=mascot->sockmsg_expire_def/INTERVAL;
      }

      // Stepping or Lump Sum?
      strncpy(tmp,buf+8,2);
      mode=(gint)atoi(tmp);
      if(mode<0){
        mode=mascot->sockmsg_type;
      }

      // Stepping Interval
      strncpy(tmp,buf+8+2,4);
      step=(gint)atoi(tmp);
      if(step<0){
        step=mascot->sockmsg_step;
      }
      
      
      mascot->balseq=0;
      mascot->bal_mode=BALLOON_SOCKMSG;
      if (mascot->sockmsg != NULL)
            g_free(mascot->sockmsg);
#ifdef USE_GTK2
      if(mode==SOCK_STEPPING){
        mascot->sockmsg = set_typing_msg(buf+8+2+4,step);
      }
      else{
        mascot->sockmsg = g_strdup(buf+8+2+4);
      }
#else
      mascot->sockmsg = g_strdup(buf+8+2+4);
#endif       
      DoBalloon(mascot);
      flag_balloon=TRUE;

}

static gboolean io_callback_sv(GIOChannel * source,
              GIOCondition condition, gpointer data)
{
      gchar buf[2048],tmp[8];
      gint fd, readsize;
      typMascot *mascot = data;
      gint i_ptn,i_frm;
      gint mode;

      fd = fd_accept(g_io_channel_unix_get_fd(source));

      readsize = read(fd, buf, 2047);
      buf[readsize] = '\0';

      fd_close(fd);
      
      if(readsize<4) return;
      
      strncpy(tmp,buf,2);
      mode=atoi(tmp);
      strncpy(tmp,buf+2,2);
      i_ptn=atoi(tmp);

      if(mode==DUET_CLICK){
        if (mascot->sockmsg != NULL)
          g_free(mascot->sockmsg);
        mascot->sockmsg=g_strdup(buf+2+2);
      }
      
      
      // クリックアニメ
      if((mode==DUET_CLICK)&&(mascot->duet_use_click)){
        if(mascot->frame_pix[i_ptn][0]!=-1){
          for(i_frm=0;i_frm<mascot->frame_num[mascot->anime_ptn];i_frm++){
            // ブロックループのキャンセル
            mascot->frame_loop[mascot->anime_ptn][i_frm].seq=0;
          }
          //mascot->anime_ptn=weight_click(mascot);
          mascot->anime_ptn=i_ptn;
          mascot->anime_frm=-1;
          mascot->anime_seq=-1;
          mascot->anime_seqend=
            RANDOM(mascot->frame_max[mascot->anime_ptn][mascot->anime_frm]
                 -mascot->frame_min[mascot->anime_ptn][mascot->anime_frm]+1)
            +mascot->frame_min[mascot->anime_ptn][mascot->anime_frm];
          
          sound_play(mascot,mascot->click_sound[mascot->anime_ptn]);

          if(mascot->sockmsg){
            if(strlen(mascot->sockmsg)>0){
            mascot->balseq=0;
            mascot->bal_mode=BALLOON_DUET;
            DoBalloon(mascot); 
            flag_balloon=TRUE;
            }
          }
        }
      }
      else if (mascot->duet_use_random){
        if(mascot->anime_ptn==0){ // ランダムアニメ
          if(mascot->frame_pix[i_ptn][0]!=-1){
            mascot->anime_ptn=i_ptn;
            mascot->anime_frm=0;
          }
        }
      }
}


gint sock = -1;
gint io_watch = -1;

SockMsgInitResult sockmsg_init() {
      gchar *sockname;
      SockMsgInitResult result;

      sockname = get_socket_name();

      sock = fd_connect_unix(sockname);
      if (sock < 0) {
            unlink(sockname);
            sock = fd_open_unix(sockname);
            if (sock < 0)
                  result = SOCKMSG_ERROR;
            else
                  result = SOCKMSG_CREATED;
      } else {
            result = SOCKMSG_OPENED;
      }

      return result;
}

gint duet_sv = -1;
gint io_watch_sv = -1;

SockMsgInitResult duet_sv_init(gchar *mascotname) {
  gchar *sockname;
  SockMsgInitResult result;
  
  sockname = get_duet_name(mascotname);
  
  duet_sv = fd_connect_unix(sockname);
  if (duet_sv < 0) {
    unlink(sockname);
    duet_sv = fd_open_unix(sockname);
    if (duet_sv < 0){
      //fd_close(duet_sv);
      result = SOCKMSG_ERROR;
    }
    else
      result = SOCKMSG_CREATED;
  } else {
    // Already Opened / Closeして再オープンする。
    fd_close(duet_sv);
    unlink(sockname);
    duet_sv = fd_open_unix(sockname);
    result = SOCKMSG_OPENED;
  }
  
  return result;
}

gint duet_cl = -1;

SockMsgInitResult duet_cl_init(gchar *mascotname) {
  gchar *sockname;
  SockMsgInitResult result;
  
  sockname = get_duet_name(mascotname);
  
  duet_cl = fd_connect_unix(sockname);
  if (duet_cl < 0) {
    //fd_close(duet_cl);
    result = SOCKMSG_ERROR;
  } else {
    result = SOCKMSG_OPENED;
  }
  
  return result;
}

void sockmsg_set_mascot(typMascot *mascot)
{
      GIOChannel *io;

      io = g_io_channel_unix_new(sock);
      io_watch = g_io_add_watch(io, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_PRI, io_callback, mascot);
      g_io_channel_unref(io);
}

void duet_set_mascot(typMascot *mascot)
{
      GIOChannel *io;

      io = g_io_channel_unix_new(duet_sv);
      io_watch_sv = g_io_add_watch(io, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_PRI, io_callback_sv, mascot);
      g_io_channel_unref(io);
}

void sockmsg_send_msg(gchar *msg)
{
#ifdef USE_GTK2
        msg = g_locale_to_utf8(msg,-1,NULL,NULL,NULL);
        if(!msg)
            _("(Invalid Character Code)");
#endif

      if (write(sock, msg, strlen(msg)) <0){
        printf("Error : sockmsg_send_msg();\n");
        return;
      }
}

void duet_send_msg(gchar *msg)
{
#ifdef USE_GTK2
        msg = g_locale_to_utf8(msg,-1,NULL,NULL,NULL);
        if(!msg)
            _("(Invalid Character Code)");
#endif

      if (write(duet_cl, msg, strlen(msg)) <0){
        printf("Error : duet_send_msg();\n");
        return;
      }
      
}

void sockmsg_done()
{
      gchar *sockname;

      if (io_watch != -1)
            g_source_remove(io_watch);
        fd_close(sock);

        sockname = get_socket_name();
        unlink(sockname);
}

void duet_sv_done(gchar *mascotname, gboolean flag_close)
{
      gchar *sockname;

      if (io_watch_sv != -1)
            g_source_remove(io_watch_sv);
        fd_close(duet_sv);

      if(flag_close) {
        sockname = get_duet_name(mascotname);
        unlink(sockname);
      }
}

void duet_cl_done(gchar *mascotname, gboolean flag_close)
{
      gchar *sockname;

        fd_close(duet_cl);

      if(flag_close) {
        sockname = get_duet_name(mascotname);
        unlink(sockname);
      }
}

#ifdef USE_GTK2
gchar* set_typing_msg(gchar* input, gint interval){
  gchar *p, *p1, *ret;
  gint i,j,num;
  
  p = input;
  ret=my_strbuf(NULL);

  while (*p) {
    gunichar ch, ch1;
    gchar tmp[64];

    ch= g_utf8_get_char (p);
    
    if (ch == '%'){
      num=0;
      i=0;
      p1=p;
      for(;;){
      p1=g_utf8_next_char (p1);
      ch1= g_utf8_get_char (p1);
      if((ch1 == 'c')||(ch1 == 'a')||(ch1 == 'n')||(ch1 == 'p')){
        i++;
        break;
      }
      else if(isdigit(ch1)){
        i++;
      }
      else{
        i=0;
        break;
      }
      }

      if(i!=0){
      ret=my_strbuf("%");
      for(j=0;j<i;j++){
        p = g_utf8_next_char (p);
        g_utf8_strncpy(tmp,p,1);
        ret=my_strbuf(tmp);
      }
      }
      else{
      sprintf(tmp,"%%%%%%%dc",interval);
      ret=my_strbuf(tmp);
      }
    }
    else{
      g_utf8_strncpy(tmp,p,1);
      ret=my_strbuf(tmp);
      sprintf(tmp,"%%%dc",interval);
      ret=my_strbuf(tmp);
    }
    
    
    p = g_utf8_next_char (p);
  }
  //fprintf(stderr,"%s\n",ret);
  //fflush(stderr);

  return(ret);
}

gchar* my_strbuf(gchar *p)
{
  static gchar    *start = NULL;
  static gchar    *next;
  static int      len, len2, l;
  
  if (p == NULL) {
    len = len2 = 4096;
    start = next = (gchar *) g_malloc(len + 1);
    start[0] = '\0';
  } else if (start != NULL) {
    l = strlen(p);
    while (len - l < 0) {
      gchar           *p;
      len2 += 256;
      len += 256;
      p = (gchar *) g_realloc(start, len2 + 1);
      start = p;
      next = p + len2 - len;
                }
    strcpy(next,p);
    len -= l;
    next += l;
  }
  return start;
}
#endif //USE_GTK2

#endif  // USE_SOCKMSG


Generated by  Doxygen 1.6.0   Back to index