mcabber/src/buddies.c
changeset 24 e88b15cbf2de
child 30 4ea2df449381
equal deleted inserted replaced
23:d7107507424b 24:e88b15cbf2de
       
     1 #include <stdio.h>
       
     2 #include <stdlib.h>
       
     3 #include <string.h>
       
     4 #include <ncurses.h>
       
     5 #include <panel.h>
       
     6 #include "screen.h"
       
     7 #include "buddies.h"
       
     8 
       
     9 #include "lang.h"
       
    10 #include "utils.h"
       
    11 #include "server.h"
       
    12 #include "list.h"
       
    13 #include "harddefines.h"
       
    14 
       
    15 /* global vars for BUDDIES.C */
       
    16 int buddySelected = 1;		/* Hold the selected Buddy  */
       
    17 int buddyOffset = 0;		/* Hold the roster offset   */
       
    18 
       
    19 static LIST_HEAD(buddy_list);
       
    20 static LIST_HEAD(sorted_buddies);
       
    21 
       
    22 #define buddy_entry(n) list_entry(n, buddy_entry_t, list)
       
    23 
       
    24 
       
    25 void bud_SetBuddyStatus(char *jidfrom, int status)
       
    26 {
       
    27   struct list_head *pos, *n;
       
    28   buddy_entry_t *tmp;
       
    29   int changed = 0;
       
    30   char *buffer = (char *) malloc(4096);
       
    31 
       
    32   list_for_each_safe(pos, n, &buddy_list) {
       
    33     tmp = buddy_entry(pos);
       
    34     if (!strcmp(tmp->jid, jidfrom)) {
       
    35       if (tmp->flags != status) {
       
    36 	tmp->flags = status;
       
    37 	changed = 1;
       
    38       }
       
    39       break;
       
    40     }
       
    41   }
       
    42   if (changed) {
       
    43     bud_DrawRoster(scr_GetRosterWindow());
       
    44     switch (status) {
       
    45     case FLAG_BUDDY_DISCONNECTED:
       
    46       sprintf(buffer, "--> %s %s!", jidfrom, i18n("disconected"));
       
    47       break;
       
    48 
       
    49     case FLAG_BUDDY_CONNECTED:
       
    50       sprintf(buffer, "--> %s %s!", jidfrom, i18n("connected"));
       
    51       break;
       
    52     }
       
    53     scr_LogPrint("%s", buffer);
       
    54   }
       
    55   free(buffer);
       
    56 }
       
    57 
       
    58 int compara(buddy_entry_t * t1, buddy_entry_t * t2)
       
    59 {
       
    60   const char *s1 =
       
    61       (const char *) (STR_EMPTY(t1->name) ? t1->jid : t1->name);
       
    62   const char *s2 =
       
    63       (const char *) (STR_EMPTY(t2->name) ? t2->jid : t2->name);
       
    64   return strcasecmp(s1, s2);
       
    65 }
       
    66 
       
    67 void bud_SortRoster(void)
       
    68 {
       
    69   buddy_entry_t *indice, *tmp;
       
    70   struct list_head *pos, *n;
       
    71 
       
    72   while (!list_empty(&buddy_list)) {
       
    73     indice = NULL;
       
    74     tmp = NULL;
       
    75     list_for_each_safe(pos, n, &buddy_list) {
       
    76       if (!indice) {
       
    77 	indice = buddy_entry(pos);
       
    78 	tmp = buddy_entry(pos);
       
    79       } else {
       
    80 	tmp = buddy_entry(pos);
       
    81 	if (compara(indice, tmp) > 0) {
       
    82 	  indice = tmp;
       
    83 	}
       
    84       }
       
    85     }
       
    86     list_move_tail(&indice->list, &sorted_buddies);
       
    87   }
       
    88   list_splice(&sorted_buddies, &buddy_list);
       
    89 }
       
    90 
       
    91 void bud_ParseBuddies(char *roster)
       
    92 {
       
    93   buddy_entry_t *tmp = NULL;
       
    94   char *aux;
       
    95   char *p, *str;
       
    96 
       
    97   ut_WriteLog("[roster]: %s\n\n", roster);
       
    98 
       
    99   while ((aux = ut_strrstr(roster, "<item")) != NULL) {
       
   100     char *jid = getattr(aux, "jid='");
       
   101     char *name = getattr(aux, "name='");
       
   102     char *group = gettag(aux, "group='");
       
   103 
       
   104     *aux = '\0';
       
   105 
       
   106     tmp = (buddy_entry_t *) calloc(1, sizeof(buddy_entry_t));
       
   107 
       
   108     tmp->flags = FLAG_BUDDY_DISCONNECTED;
       
   109 
       
   110     if (strncmp(jid, "UNK", 3)) {
       
   111       char *res = strstr(jid, "/");
       
   112       if (res)
       
   113 	*res = '\0';
       
   114 
       
   115       tmp->jid = (char *) malloc(strlen(jid) + 1);
       
   116       strcpy(tmp->jid, jid);
       
   117       free(jid);
       
   118     }
       
   119 
       
   120     if (strncmp(name, "UNK", 3)) {
       
   121       tmp->name = (char *) calloc(1, strlen(name) + 1);
       
   122       strcpy(tmp->name, name);
       
   123       free(name);
       
   124     } else {
       
   125       tmp->name = (char *) calloc(1, strlen(tmp->jid) + 1);
       
   126       str = strdup(tmp->jid);
       
   127       p = strstr(str, "@");
       
   128       if (p) {
       
   129 	*p = '\0';
       
   130       }
       
   131       strncpy(tmp->name, str, 18);
       
   132       free(str);
       
   133     }
       
   134 
       
   135     if (strncmp(group, "UNK", 3)) {
       
   136       tmp->group = (char *) malloc(strlen(group) + 1);
       
   137       strcpy(tmp->group, group);
       
   138       free(group);
       
   139     }
       
   140 
       
   141     if (!strncmp(tmp->jid, "msn.", 4)) {
       
   142       sprintf(tmp->name, "%c MSN %c", 254, 254);
       
   143     }
       
   144 
       
   145     if (!STR_EMPTY(tmp->jid)) {
       
   146       list_add_tail(&tmp->list, &buddy_list);
       
   147     } else {
       
   148       if (tmp->jid)
       
   149 	free(tmp->jid);
       
   150       if (tmp->name)
       
   151 	free(tmp->name);
       
   152       if (tmp->group)
       
   153 	free(tmp->group);
       
   154       free(tmp);
       
   155     }
       
   156   }
       
   157   free(roster);
       
   158 
       
   159   bud_SortRoster();
       
   160 }
       
   161 
       
   162 /* Desc: Initialize buddy list
       
   163  * 
       
   164  * In : none
       
   165  * Out: none
       
   166  *
       
   167  * Note: none
       
   168  */
       
   169 void bud_InitBuddies(int sock)
       
   170 {
       
   171   char *roster;
       
   172   roster = srv_getroster(sock);
       
   173   bud_ParseBuddies(roster);
       
   174 }
       
   175 
       
   176 /* Desc: Destroy (and free) buddy list
       
   177  * 
       
   178  * In : none
       
   179  * Out: none
       
   180  *
       
   181  * Note: none
       
   182  */
       
   183 void bud_TerminateBuddies(void)
       
   184 {
       
   185 }
       
   186 
       
   187 /* Desc: Count elements in buddy list
       
   188  * 
       
   189  * In : none
       
   190  * Out: number of buddies
       
   191  *
       
   192  * Note: none
       
   193  */
       
   194 int bud_BuddyCount(void)
       
   195 {
       
   196   int i = 0;
       
   197   struct list_head *pos, *n;
       
   198 
       
   199   list_for_each_safe(pos, n, &buddy_list) {
       
   200     i++;
       
   201   }
       
   202   return i;
       
   203 }
       
   204 
       
   205 /* Desc: Draw the roster in roster window
       
   206  * 
       
   207  * In : roster window
       
   208  * Out: none
       
   209  *
       
   210  * Note: none
       
   211  */
       
   212 void bud_DrawRoster(WINDOW * win)
       
   213 {
       
   214   buddy_entry_t *tmp = NULL;
       
   215   struct list_head *pos, *nn;
       
   216   int i = 1;
       
   217   int n;
       
   218   int maxx, maxy;
       
   219   int fakeOffset = buddyOffset;
       
   220 
       
   221   getmaxyx(win, maxy, maxx);
       
   222 
       
   223 
       
   224   /* cleanup of roster window */
       
   225   wattrset(win, COLOR_PAIR(COLOR_GENERAL));
       
   226   for (i = 1; i < maxy - 1; i++) {
       
   227     mvwprintw(win, i, 1, "");
       
   228     for (n = 2; n < maxx; n++)
       
   229       waddch(win, ' ');
       
   230   }
       
   231 
       
   232   i = 1;
       
   233   list_for_each_safe(pos, nn, &buddy_list) {
       
   234 
       
   235     char status = '?';
       
   236     char pending = ' ';
       
   237 
       
   238     if (fakeOffset > 0) {
       
   239       fakeOffset--;
       
   240       continue;
       
   241     }
       
   242 
       
   243     tmp = buddy_entry(pos);
       
   244     if (scr_IsHiddenMessage(tmp->jid)) {
       
   245       pending = '#';
       
   246     }
       
   247 
       
   248     if ((tmp->flags && FLAG_BUDDY_CONNECTED) == 1) {
       
   249       status = 'o';
       
   250       if (i == (buddySelected - buddyOffset))
       
   251 	wattrset(win, COLOR_PAIR(COLOR_BD_CONSEL));
       
   252       else
       
   253 	wattrset(win, COLOR_PAIR(COLOR_BD_CON));
       
   254     } else {
       
   255       if (i == (buddySelected - buddyOffset))
       
   256 	wattrset(win, COLOR_PAIR(COLOR_BD_DESSEL));
       
   257       else
       
   258 	wattrset(win, COLOR_PAIR(COLOR_BD_DES));
       
   259     }
       
   260     mvwprintw(win, i, 1, "");
       
   261     for (n = 2; n < maxx; n++)
       
   262       waddch(win, ' ');
       
   263     //mvwprintw(win, i, (maxx - strlen(tmp->name)) / 2, "%s", tmp->name);
       
   264     mvwprintw(win, i, 1, " %c[%c] %.12s", pending, status, tmp->name);
       
   265     i++;
       
   266     if (i >= maxy - 1)
       
   267       break;
       
   268   }
       
   269   update_panels();
       
   270   doupdate();
       
   271 
       
   272   update_roaster = FALSE;
       
   273 }
       
   274 
       
   275 /* Desc: Change selected buddy (one position down)
       
   276  * 
       
   277  * In : none
       
   278  * Out: none
       
   279  *
       
   280  * Note: none
       
   281  */
       
   282 void bud_RosterDown(void)
       
   283 {
       
   284   int x, y;
       
   285   getmaxyx(scr_GetRosterWindow(), y, x);
       
   286   y -= 2;
       
   287 
       
   288   if (buddySelected < bud_BuddyCount()) {
       
   289     buddySelected++;
       
   290     if (buddySelected > y)
       
   291       buddyOffset++;
       
   292     bud_DrawRoster(scr_GetRosterWindow());
       
   293   }
       
   294 }
       
   295 
       
   296 /* Desc: Change selected buddy (one position up)
       
   297  * 
       
   298  * In : none
       
   299  * Out: none
       
   300  *
       
   301  * Note: none
       
   302  */
       
   303 void bud_RosterUp(void)
       
   304 {
       
   305   if (buddySelected > 1) {
       
   306     buddySelected--;
       
   307     if (buddySelected - buddyOffset < 1)
       
   308       buddyOffset--;
       
   309     bud_DrawRoster(scr_GetRosterWindow());
       
   310   }
       
   311 }
       
   312 
       
   313 /* Desc: Retrieve info for selected buddy
       
   314  * 
       
   315  * In : none
       
   316  * Out: (buddy_entry_t *) of selected buddy
       
   317  *
       
   318  * Note: none
       
   319  */
       
   320 buddy_entry_t *bud_SelectedInfo(void)
       
   321 {
       
   322   struct list_head *pos, *n;
       
   323   buddy_entry_t *tmp = NULL;
       
   324 
       
   325   int i = 0;
       
   326 
       
   327   list_for_each_safe(pos, n, &buddy_list) {
       
   328     tmp = buddy_entry(pos);
       
   329     if (i == buddySelected - 1) {
       
   330       return tmp;
       
   331     }
       
   332     i++;
       
   333   }
       
   334   return NULL;
       
   335 }
       
   336 
       
   337 void bud_AddBuddy(int sock)
       
   338 {
       
   339   char *buffer = (char *) calloc(1, 1024);
       
   340   char *buffer2 = (char *) calloc(1, 1024);
       
   341   char *p, *str;
       
   342   buddy_entry_t *tmp;
       
   343 
       
   344   ut_CenterMessage(i18n("write jid here"), 60, buffer2);
       
   345   scr_CreatePopup(i18n("Add jid"), buffer2, 60, 1, buffer);
       
   346 
       
   347   if (!STR_EMPTY(buffer)) {
       
   348     tmp = (buddy_entry_t *) calloc(1, sizeof(buddy_entry_t));
       
   349     tmp->jid = (char *) malloc(strlen(buffer) + 1);
       
   350     strcpy(tmp->jid, buffer);
       
   351     tmp->name = (char *) malloc(strlen(buffer) + 1);
       
   352 
       
   353     str = strdup(buffer);
       
   354     p = strstr(str, "@");
       
   355     if (p) {
       
   356       *p = '\0';
       
   357     }
       
   358     strcpy(tmp->name, str);
       
   359     free(str);
       
   360 
       
   361     list_add_tail(&tmp->list, &buddy_list);
       
   362     buddySelected = 1;
       
   363     bud_DrawRoster(scr_GetRosterWindow());
       
   364     srv_AddBuddy(sock, tmp->jid);
       
   365   }
       
   366   free(buffer);
       
   367 }
       
   368 
       
   369 void bud_DeleteBuddy(int sock)
       
   370 {
       
   371   buddy_entry_t *tmp = bud_SelectedInfo();
       
   372   srv_DelBuddy(sock, tmp->jid);
       
   373   list_del(&tmp->list);
       
   374   buddySelected = 1;
       
   375   bud_DrawRoster(scr_GetRosterWindow());
       
   376 }