[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Savannah-hackers] Re: submission of Giuli* Mail - savannah.gnu.org
From: |
Mathieu Roy |
Subject: |
[Savannah-hackers] Re: submission of Giuli* Mail - savannah.gnu.org |
Date: |
12 Feb 2003 21:53:24 +0100 |
User-agent: |
Gnus/5.09 (Gnus v5.9.0) Emacs/21.2 |
<address@hidden> a tapoté :
> You asked me the source code... ok, here you are, is very "incomplete",
> but me and a friend are still working around it.Scuse me if I don't uploand
> on anothe web site.
> Thank really for the time you are "wasting" for me.
Nothing is wasted :)
Do not forget to include the full GPL text in a file (called COPYING
for instance). Please, resubmit, it's fine.
Note that you should replace "copyleft" by "copyright". GPL is
copyleft, indeed, but it's copyleft protected by copyright. It's a
trick as copyleft have no legal existence.
Regards,
>
>
> /* Copyleft by Giulio Iotti (dullboy) 2003 address@hidden * GIM
> -- My own local-mail client * * This is a free software; you can
> redistribuite it and/or modify * if under the terms of the GNU
> General Public License as published by * the Free Software
> Foundation; either version 2 of the License, or * (ar your option)
> any later version. * * This program is distribuited 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 * * Compile with: * gcc -lncurses -o /usr/bin/gim
> gim.c * Ncurses library and header files are required! */
>
> /* ###### ####### # ### ####### *
> * ## ## ## # # ## ## ## *
> * ## ## ## ## ## ## # ## *
> * ###### ##### ## ## ## ##### *
> * ## ## ####### ## ## *
> * ## ## ## ## ## ## ## *
> * ## ####### ## ## ### ####### */
>
> #include <stdio.h>
> #include <string.h>
> #include <signal.h>
> #include <stdlib.h>
> #include <curses.h>
>
> /* version definition */
> #ifdef ALPHA_VERSION
> # define VERSION "GIM 0.44-alpha"
> #else
> # define VERSION "GIM 0.44.1"
> #endif
>
> /* EMERGENCY EXIT 8^)) */
> void sig() {
> clear();
> mvaddstr(LINES-1,0,NULL);
> endwin();
> exit(1);
> }
>
> /* Status of buttons, menus, etc */
> typedef enum {
> none=1,
> selected=2,
> open=3
> } Status;
>
> /* Buttons */
> struct {
> char *label; /* Name of this button */
> Status status; /* Status of this button */
> unsigned y; /* Position */
> unsigned x; /* " " */
> } buttonlist[] = {
> { "File", none, 0, 0 },
> { "New", none, 7, 0 },
> { "Mail", none, 13, 0 },
> { "Options", none, 20, 0 },
> { "Help", none, 30, 0 },
> { NULL, -1, 0, 0 }
> };
>
> /* Menus */
> struct {
> char *item;
> Status status;
> } menulist[5][8] = {
> {
> { " &Open mail file ", open },
> { " &Close this mail file ", none },
> { " &Exit ", none },
> { NULL, -1 }
> },
> {
> { " &Write new e-mail ", open }, /* FIXME */
> { " &Save draft ", none },
> { NULL, -1 }
> },
> {
> { " &List all mails ", open },
> { " &Delete all mails ", none },
> { " &Run FetchMail ", none },
> { NULL, -1 }
> },
> {
> { " Screen options &file ", open },
> { " Configure &FetchMail ", none },
> { " Set &options to default", none },
> { " --------------------- ", none },
> { " Default &0 ", none },
> { " Cyan & magenta &1 ", none },
> { " Green day &2 ", none },
> { NULL, -1 }
> },
> {
> { " Sent a &bug ", open },
> { " &Authors ", none },
> { " &License ", none },
> { " Fast &help ", none },
> { NULL, -1 }
> }
> };
>
> const int total_len = 37; /* Total len of the hight bar */
> unsigned lines=0; /* Lines of a single mail */
> bool mail_open = FALSE; /* Is mail already opended? */
> char mailfile[300]; /* File of local mail */
>
> void connectMenu(int);
>
> /* Print welcome message */
> /* TODO: improve me */
> void print_init_msg()
> {
> color_set(5,NULL);
> mvaddstr(3,2,"Welcome to GIM (GIuli* Mail) version 0.44");
> mvaddstr(4,2,"This program is a local mail reader, very light and easy
> to use,");
> mvaddstr(5,2,
> "based on a N-curses interface. Firstly you must have an account, if
> you");
> mvaddstr(6,2,"don't know if you have one, try to use the command \"");
> attrset(A_BOLD); addstr("echo $MAIL"); attrset(A_NORMAL); addch('\"');
> mvaddstr(7,2,"and enter in the menu \"");
> attrset(A_BOLD); addstr("File"); attrset(A_NORMAL);
> mvaddstr(7,29,"\" and choose \"");
> attrset(A_BOLD); addstr("Open mail file"); attrset(A_NORMAL);
> addstr("\";");
> mvaddstr(8,2,"Use the TAB key to move in the bar. Enjoy!");
> }
>
> /* Print in the posiotion (x,y) the label beween [ and ] */
> void print_button(char *text, unsigned short status,
> unsigned x, unsigned y)
> {
> mvaddstr(x,y,NULL);
> color_set(1, NULL);
> addstr(" [");
> color_set(status, NULL);
> printw("%s", text);
> color_set(1, NULL);
> addstr("] ");
> }
>
> /* Print in position (x,y) the label between | and | */
> void print_menu_item(char *text, unsigned short status,
> unsigned x, unsigned y)
> {
> unsigned short i;
>
> mvaddstr(x,y,NULL);
> color_set(1, NULL);
> addch('|');
> color_set(status, NULL);
>
> /* This routine finds & (without spaces near)
> * to color the closer letter */
> for (i=0; i <= (strlen(text) - 1); i++) {
> if (text[i] == '&') {
> if (text[++i] != ' ') {
> if (status == open)
> color_set(7, NULL);
> else color_set(6, NULL);
> addch(text[i]);
> color_set(status, NULL);
> continue;
> } else addch('&');
> }
> addch(text[i]);
> }
>
> color_set(1, NULL);
> addch('|');
> }
>
> #ifdef ALPHA_VERSION
> void list_mail()
> {
> FILE *file;
> char *buffer, *buffer1;
> unsigned short i, j;
> unsigned short y=1, count=1;
>
> buffer = buffer1 = (char *) malloc(COLS-1);
>
> if ((file = fopen(mailfile, "r")) == NULL) {
> mvaddstr(4,2, "Unable to open mail file!");
> return;
> }
>
> color_set(5, NULL);
>
> while (!feof(file)) {
> fgets(buffer, COLS-1, file);
> if (strncmp("From:", buffer, 5) == 0) {
> i = 5; j = 0;
> while (buffer[i++] != '\n') {
> if (buffer[i] == '<')
> while (buffer[++i] != '>')
> buffer1[j++] = buffer[i];
> //buffer1[j++] = '\0';
> }
> mvprintw(y++,0,"%d)\t", count++);
> printw("%s\t", buffer1);
> continue;
> }
>
> if (strncmp("Subject: ", buffer, 9) == 0) {
> for (i=9, j=0; i <= COLS; i++) {
> if (buffer[i] != '\n')
> buffer1[j++] = buffer[i];
> else
> buffer1[j++] = '\0';
> }
> printw("%s", buffer1);
> }
> }
>
> free(buffer);
> free(buffer1);
>
> return;
> }
> #endif /* APLPHA_VERSION */
>
> /* Print highter bar */
> void hightbar()
> {
> int i=0;
>
> while (buttonlist[i].label != NULL ||
> buttonlist[i].status != -1) {
> print_button(buttonlist[i].label, buttonlist[i].status,
> buttonlist[i].x, buttonlist[i].y); i++;
> }
> for (i=37; i < COLS; i++)
> mvaddch(0,i,' ');
> }
>
> /* Print a bar in LINES which contain:
> * Mail directory (getenv("MAIL"))
> * Username (getenv("LOGNAME"))
> * This program name + version */
> void lowbar(char *username)
> {
> int i=2,j;
> char *buffer;
>
> /* Print mail dir */
> color_set(1,NULL);
> buffer = (char *) malloc(200);
> sprintf(buffer, "%s", mailfile);
> mvaddstr(LINES-1,0,"+-");
> mvaddch(LINES-1,i++,'*');
>
> /* If it is too long cut it with a ~ */
> for (j=0; j <= 19; j++) {
> if (buffer[j] != '\0')
> mvaddch(LINES-1,i++,buffer[j]);
> else break;
> }
>
> if (buffer[i] != '\0')
> mvaddch(LINES-1,i,'~');
> mvaddch(LINES-1,i++,'*');
> j = i;
> i += strlen(username) + 4;
> if (i >= COLS-1) return;
> mvprintw(LINES-1,j,"--*%s*", username);
>
> /* Print program name + version */
> addstr("---*"); i+=4;
> addstr(VERSION); i+=strlen(VERSION);
> addch('*'); i++;
>
> /* Finish the bar */
> while (i < COLS-1) {
> mvaddch(LINES-1,i,'-');
> i++;
> }
> mvaddch(LINES-1,COLS-1,'+');
>
> free(buffer);
> return;
> }
>
> void set_pair(unsigned short i)
> {
> switch(i) {
> case 0:
> init_pair(1, COLOR_WHITE, COLOR_BLUE);
> init_pair(2, COLOR_RED, COLOR_BLUE);
> init_pair(3, COLOR_GREEN, COLOR_RED);
> init_pair(6, COLOR_CYAN, COLOR_BLUE);
> init_pair(7, COLOR_CYAN, COLOR_RED);
> break;
> case 1:
> init_pair(1, COLOR_BLUE, COLOR_WHITE);
> init_pair(2, COLOR_MAGENTA, COLOR_WHITE);
> init_pair(3, COLOR_MAGENTA, COLOR_BLUE);
> init_pair(6, COLOR_YELLOW, COLOR_WHITE);
> init_pair(7, COLOR_YELLOW, COLOR_BLUE);
> break;
> case 2:
> init_pair(1, COLOR_BLUE, COLOR_GREEN);
> init_pair(2, COLOR_RED, COLOR_GREEN);
> init_pair(3, COLOR_RED, COLOR_BLUE);
> init_pair(6, COLOR_WHITE, COLOR_GREEN);
> init_pair(7, COLOR_WHITE, COLOR_BLUE);
> break;
> }
>
> /* These two are always the same */
> init_pair(4, COLOR_BLACK, COLOR_BLACK);
> init_pair(5, COLOR_WHITE, COLOR_BLACK);
> }
>
> bool connectMenuItem(unsigned short i,
> unsigned short n)
> {
> switch(i) {
> case 0:
> switch(n) {
> case 2:
> erase();
> mvaddstr(0,0,NULL);
> endwin();
> exit(0);
> break;
> default:
> return FALSE;
> }
> case 3:
> /* TODO: in my opinion calls to getenv are too much */
> switch(n) {
> case 4:
> set_pair(0);
> hightbar();
> lowbar(getenv("LOGNAME"));
> break;
> case 5:
> set_pair(1);
> hightbar();
> lowbar(getenv("LOGNAME"));
> break;
> case 6:
> set_pair(2);
> hightbar();
> lowbar(getenv("LOGNAME"));
> break;
> default:
> return FALSE;
> }
> break;
> case 4:
> switch(n) {
> case 3:
> clear();
> hightbar();
> lowbar(getenv("LOGNAME"));
> mail_open = FALSE;
> lines = 0;
> break;
> default:
> return FALSE;
> }
> break;
> }
> return TRUE;
> }
>
> /* Move to the free space a mail, using its line no. */
> /* TODO: Improve headers reading */
> /* BUGS: lots */
> void screen_mail() {
> unsigned i=0,j=0,y=2,z=2;
> char *buffer;
> FILE *file;
> bool passed = FALSE;
>
> buffer = (char *) malloc(COLS-5);
> clear(); lowbar(getenv("LOGNAME")); hightbar();
> color_set(5, NULL);
> /* Have't got mail ... */
> if ((file = fopen(mailfile, "r")) == NULL) {
> mvprintw(3,3,
> "ERROR: Unable to open your $MAIL dir: %s\n"
> "%s",
> mailfile, "No such file or directory");
> return;
> }
>
> /* Find current position in mails file */
> rewind(file);
> if (lines != 0)
> while (i++ <= lines) {
> if (feof(file)) break;
> fgets(buffer, COLS-10, file);
> }
>
> for (i = 0; i <= 15; i++) {
> if (feof(file)) break;
> fgets(buffer, COLS-3, file);
> lines++;
> /* color for addresses in "form" */
> if (strncmp(buffer, "From:", 5) == 0) {
> while (buffer[j] != '\n') {
> if (buffer[j] == '<')
> attrset(A_BOLD);
> if (buffer[j] == '>') {
> mvaddch(y,z,buffer[j]);
> attrset(A_NORMAL);
> z++; j++;
> }
> mvaddch(y,z,buffer[j]);
> z++; j++;
> }
> y++; j=0; z=2;
> continue;
> }
>
> /* Color all subject field */
> if (strncmp(buffer, "Subject:", 8) == 0) {
> while (buffer[j] != '\n') {
> if (buffer[j] == ' ')
> attrset(A_BOLD);
> mvaddch(y,z,buffer[j]);
> z++; j++;
> }
> y++; j=0; z=2;
> attrset(A_NORMAL);
> continue;
> }
>
> mvaddstr(y++,2,NULL);
> if (buffer[0] == '\n')
> attrset(A_BOLD);
>
> /* If mail is finished exits */
> if (strcmp(buffer, "\n\n") == 0) {
> if (passed == TRUE) {
> passed = FALSE;
> break;
> }
> else passed = TRUE;
> }
>
> printw("%s", buffer);
> }
>
> attrset(A_NORMAL);
> color_set(1, NULL);
> free(buffer);
> fclose(file);
> return;
> }
>
> void print_center_bar(char *text)
> {
> unsigned short y = LINES / 2;
> unsigned short x = 5;
>
> mvaddch(y,0,'+');
> addstr("----");
> if (text != NULL) {
> x += strlen(text) + 2;
> if (x >= COLS) return;
> else printw("*%s*", text);
> }
>
> while (x++ <= COLS-2)
> addch('-');
> addch('+');
> }
>
> int main(int argc, char* argv[]) {
> int ch;
>
> /* Inizialize ncurses, */
> initscr();
> noecho();
> curs_set(0);
> keypad(stdscr, TRUE);
> refresh();
>
> if (has_colors())
> start_color();
> else sig();
>
> /* Redirect some signals */
> signal(SIGINT, sig);
> signal(SIGTERM, sig);
>
> /* Set default colors */
> set_pair(0);
>
> if (argv[1] != NULL && argv[1][0] != '-') {
> if (fopen(argv[1], "r") != NULL)
> strcpy(mailfile, argv[0]);
> else strcpy(mailfile, getenv("MAIL"));
> } else strcpy(mailfile, getenv("MAIL"));
>
> /* Print upper and lower bars */
> hightbar(); lowbar(getenv("LOGNAME"));
>
> print_init_msg(); /* TODO: We have to improve it */
>
> while ((ch = getch()))
> switch(ch) {
> #ifdef ALPHA_VERSION
> case 'l':
> clear();
> lowbar(getenv("LOGNAME"));
> hightbar();
> list_mail();
> break;
> #endif
> case 'h':
> clear(); lowbar(getenv("LOGNAME"));
> hightbar();
> print_init_msg();
> break;
> case 'e':
> case 'q':
> endwin();
> return 0;
> default:
> connectMenu(ch);
> }
>
> return 0;
> }
>
> void connectSubmenu(unsigned short i,
> unsigned short d,
> unsigned short max)
> {
> int ch;
> unsigned short m=2, n=0;
>
> max -= 4;
>
> while (menulist[i][n].status != open) {
> n++; m++;
> }
>
> while ((ch = getch()))
> switch(ch) {
> case KEY_UP:
> case KEY_DOWN:
> case 'd':
> case 'u':
> menulist[i][n].status = none;
> print_menu_item(menulist[i][n].item,
> menulist[i][n].status, m, d);
>
> if (ch == 'd' || ch == KEY_DOWN) {
> m++; n++;
> if (menulist[i][n].item == NULL ||
> menulist[i][n].status == -1) {
> n=0; m=2;
> }
> }
>
> if (ch == 'u' || ch == KEY_UP) {
> if (n != 0) {
> m--; n--;
> } else {
> m=max+2; n=max;
> }
> }
>
> menulist[i][n].status = open;
> print_menu_item(menulist[i][n].item,
> menulist[i][n].status, m, d);
> continue;
> case '\n':
> if (connectMenuItem(i, n))
> return;
> else continue;
> }
> return;
> }
>
> void connectMenu(int ch)
> {
> /* They are static 'cause we must use them several times */
> static unsigned short i=0,d;
> static bool touched=TRUE;
> unsigned short m=1, n=0;
>
> switch(ch) {
> case ' ': /* SPACE: select/deselect a button */
> if (buttonlist[i].status == none) {
> buttonlist[i].status = selected;
> break;
> }
> if (buttonlist[i].status == selected) {
> buttonlist[i].status = none;
> print_button(buttonlist[i].label, none,
> buttonlist[i].x, buttonlist[i].y);
> i=0; touched = TRUE;
> break;
> }
> case '\n': /* ENTER: open menu and wait another char */
> if (buttonlist[i].status == selected) {
> print_button(buttonlist[i].label, open,buttonlist[i].x,
> buttonlist[i].y);
> d = buttonlist[i].y + 1;
> /* In particolar situation(s) I reformat position
> * (ex. when the bottom is on the left border) */
> /* FIXME: I always assume thet max size is 26 */
> if ((d + 26) >= COLS)
> d = total_len - 26;
> mvaddstr(m++,d,"+----u------------------+");
> while (menulist[i][n].item != NULL ||
> menulist[i][n].status != -1) {
> print_menu_item(menulist[i][n].item,
> menulist[i][n].status,m,d);
> n++; m++;
> }
> mvaddstr(m++,d,"+----d------------------+");
> connectSubmenu(i, d, m);
> color_set(4,NULL);
> while(m-- > 1) /* delete menu (currently useless) */
> mvaddstr(m,d," ");
> m = 1;
> if (mail_open == TRUE) {
> clear();
> lowbar(getenv("LOGNAME"));
> hightbar();
> lines = 0;
> screen_mail();
> }
> else print_init_msg();
> buttonlist[i].status = none;
> print_button(buttonlist[i].label, none,
> buttonlist[i].x, buttonlist[i].y);
> touched = TRUE; i = 0; /* restore vars... */
> } else {
> screen_mail();
> attrset(A_NORMAL);
> mail_open = TRUE;
> }
> break;
> case KEY_RIGHT:
> case '\t': /* TAB: select next button */
> if (touched != TRUE) { /* is the first button */
> buttonlist[i].status = none;
> print_button(buttonlist[i].label, none,
> buttonlist[i].x, buttonlist[i].y);
> if (i < 4) i++;
> else i=0;
> buttonlist[i].status = selected;
> break;
> } else { /* it's not! */
> buttonlist[i].status = selected;
> touched = FALSE;
> break;
> }
> }
>
> /* Reprint buttons (some breaks require it) */
> print_button(buttonlist[i].label, buttonlist[i].status,
> buttonlist[i].x, buttonlist[i].y);
> return;
> }
--
Mathieu Roy
<< Profile << http://savannah.gnu.org/users/yeupou <<
>> Homepage >> http://yeupou.coleumes.org >>
<< GPG Key << http://stock.coleumes.org/gpg <<