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

📄 cmds.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
#ifndef lint#ifdef sccsstatic  char sccsid[] = "@(#)cmds.c 1.1 92/07/30 Copyr 1987 Sun Micro";#endif#endif/* * Copyright (c) 1987 by Sun Microsystems, Inc. *//* * Mailtool - tool command handling *//***************************************************************  *******                                                  *******  ******  NOTE: please use the comment section at the end   ****** ******        of the program to document source changes.  ******            *******                                                  *******  ***************************************************************/  #include <stdio.h>#include <errno.h>#include <signal.h>#include <ctype.h>#include <vfork.h>#include <sunwindow/window_hs.h>#include <sys/stat.h>#include <sys/types.h>#include <sundev/kbd.h>#include <fcntl.h>#include <suntool/window.h>#include <suntool/frame.h>#include <suntool/panel.h>#include <suntool/text.h>#include <suntool/walkmenu.h>#include <suntool/scrollbar.h>#include <suntool/selection.h>#include <suntool/selection_svc.h>#include <suntool/selection_attributes.h>#include <suntool/alert.h>#include "glob.h"#include "tool.h"/* performance: global cache of getdtablesize() */extern int dtablesize_cache;#define GETDTABLESIZE() \        (dtablesize_cache?dtablesize_cache:(dtablesize_cache=getdtablesize()))#define	PRIMARY_PD_SELECTION	0x0010 #define	PRIMARY_SELECTION	0x0001 char    *strcpy(), *sprintf(), *strcat();static char	*fields[] = {"|>recipients<|", "|>subject<|", "|>body of message<|", "|>other recipients<|", "|>blind carbon copies<|", 0};static	char	*mt_get_command_string(), *mt_find_command_string();Menu	mt_file_menu;		/* menu of most recent file names used.				 * Behind File: panel item */static void	mt_create_cmd_panel(), mt_do_del(), mt_do_deliver(); static void	mt_do_retrieve(), mt_do_save(), mt_set_nomail();static int	mt_has_selection();static void	mt_yield_all();static Seln_holder	seln_holder;/* notify procs, in alphabetical order *//* * Abort the tool. *//* ARGSUSED */voidmt_abort_proc(item, ie)	Panel_item      item;	Event          *ie;{	(void)win_release_event_lock(mt_cmdpanel_fd);	mt_yield_all();	mt_aborting = TRUE;	if (event_ctrl_is_down(ie))		mt_assign("expert", ""); /* XXX - force no confirm, just quit */	(void)window_done((struct tool *)(LINT_CAST(mt_frame)));	/* Should free window */}/* * "Quietly" retrieves new mail, i.e.., does not scroll headersw or update * message sw. Does commit if more than specified number of messages have * been deleted. Used for auto-reading. See mt_itimer in tool.c  */voidmt_auto_retrieve_mail_proc(item, ie)	Panel_item      item;	Event          *ie;{	char           *p;	p = mt_value("commitfrequency"); 	mt_do_retrieve(item, ie, (!p || mt_del_count <= atoi(p)), TRUE);}/* * Cancel the current reply (or send, or forward). *//* ARGSUSED */voidmt_cancel_proc(item, ie)	Panel_item      item;	Event          *ie;{	Panel           panel;	struct reply_panel_data *ptr;	char		scratch[256];	panel = panel_get(item, PANEL_PARENT_PANEL);	ptr = (struct reply_panel_data *)panel_get(panel, PANEL_CLIENT_DATA);	if (!(event_ctrl_is_down(ie)) &&		window_get(ptr->replysw, TEXTSW_MODIFIED) &&		(ptr->behavior == mt_Stay_Up			? !mt_confirm(ptr->replysw, FALSE, FALSE,			"Confirm",			"Do NOT clear window",			"Are you sure you want to Clear window?",			0)			 : !mt_confirm(ptr->replysw, FALSE, FALSE,			"Confirm",			"Do NOT cancel window",			"Are you sure you want to Cancel window?",			 0)	   ))		return;	if (mt_value("save")) {		char	*s;		FILE	*f;		s = mt_value("DEAD");		/* 		 * (Bug# 1014141 fix) added code to recognise		 * "/dev/null" and not to save to it. 		 */ 		if (strcmp(s,"/dev/null") != 0) 		{		  if (s == NULL || *s == '\0')			s = "~/dead.letter";		  mt_full_path_name(s, scratch);		  if (f = mt_fopen(scratch, "w")) {		  	/* check to see if can write to this file */			(void) fclose(f);			(void) textsw_store_file(ptr->replysw, scratch, 0, 0);		  }		}	}	textsw_reset(ptr->replysw, 0, 0);	(void) unlink(ptr->replysw_file); 	ptr->inuse = FALSE;	if (ptr->frame != mt_frame)		(void) window_set(ptr->frame,			FRAME_ICON, &mt_empty_letter_icon,			0);	if (ptr->behavior == mt_Disappear)		mt_stop_reply(ptr);	else if (ptr->behavior == mt_Close)		(void) window_set(ptr->frame, FRAME_CLOSED, TRUE, 0);}/*/* * Change Mail's working directory. *//* ARGSUSED */voidmt_cd_proc(item, ie)	Panel_item      item;	Event          *ie;{	char           *dir;	if (mt_dir_item == NULL) {		mt_create_cd_popup();		return;	}	dir = (char *)panel_get_value(mt_dir_item);	if (dir == NULL)		dir = "~";	if (strcmp(dir, mt_wdir) == 0)		return;	mt_mail_cmd("echo \"%s\"", dir);	mt_info[strlen(mt_info) - 1] = '\0';	if (chdir(mt_info) < 0) {		extern int errno;		extern int sys_nerr;		extern char *sys_errlist[];		if (errno < sys_nerr)			(void) sprintf(mt_info, "cd: %s", sys_errlist[errno]);		else			(void) sprintf(mt_info, "cd: errno=%d", errno);		mt_warn(mt_frame, mt_info, 0);	} else {		mt_set_mailwd(mt_info);		(void) strcpy(mt_wdir, dir);		mt_update_info("");	}	if (mt_cd_frame)		mt_destroy_cd_popup();}/* * Commit the current set of changes. *//* ARGSUSED */voidmt_commit_proc(item, ie)	Panel_item      item;	Event          *ie;{	static u_long   last;	u_long          when;	when = event_time(ie).tv_sec;	if (last != 0 && when < last) {		/*		 * this event occurred BEFORE the last commit operation		 * completed, i.e., user bounced on the key 		 */		last = when;		return;	}	if (mt_nomail && mt_delp == NULL) {		mt_warn(mt_frame, "No Mail", 0);		return;	}	(void)win_release_event_lock(mt_cmdpanel_fd);	mt_yield_all();	/* use mt_yield_all() to save shelf */	if (strcmp(mt_folder, mt_mailbox) == 0)		mt_new_folder("%", FALSE, FALSE);	else		mt_new_folder(mt_folder, FALSE, FALSE);	last = mt_current_time();}/* Compose a new mail message. */voidmt_comp_proc(item, ie)	Panel_item      item;	Event          *ie;{	struct reply_panel_data *ptr;	int             msg, orig;	int		lower_context;	if (!(ptr = mt_get_replysw(item)))		return;	msg = 0;	orig = event_ctrl_is_down(ie);	if (orig && (msg = mt_get_curselmsg(0)) == 0)		return;	mt_save_curmsg();	if (!(mt_compose_msg(msg, ptr->replysw_file,		mt_value("askcc")			? !event_shift_is_down(ie)			: event_shift_is_down(ie),		orig)))		return;	mt_start_reply(ptr);	lower_context = (int)window_get(ptr->replysw, TEXTSW_LOWER_CONTEXT);	(void) window_set(ptr->replysw,		TEXTSW_LOWER_CONTEXT, -1,	/* work around to						 * suppress scrolling as						 * you insert */		TEXTSW_FILE_CONTENTS, ptr->replysw_file,		TEXTSW_LOWER_CONTEXT, lower_context,		0);	(void) window_set(ptr->replysw, TEXTSW_INSERTION_POINT, 4, 0); 		/* after "To: " */	if (mt_use_fields) {		Textsw_index             first, last_plus_one;		first = (Textsw_index)window_get(ptr->replysw,			TEXTSW_INSERTION_POINT);		textsw_match_bytes(ptr->replysw,			&first, &last_plus_one, "|>", 2, "<|", 2,			TEXTSW_FIELD_FORWARD);		(void) textsw_set_selection(ptr->replysw, first, last_plus_one,			PRIMARY_SELECTION | PRIMARY_PD_SELECTION);		(void) window_set(ptr->replysw, TEXTSW_INSERTION_POINT,			last_plus_one, 0);	} 	mt_display_reply(ptr);	if (ptr->frame != mt_frame)		(void) window_set(ptr->frame,			FRAME_ICON, &mt_composing_icon,			0);	if ((nfds_avail()) < 4) {		/*		 * currently, you		 * need 4 (choke!) fds to invoke a filter, two for each pair		 * of pipes 		 */		mt_warn(window_get(ptr->replysw, WIN_OWNER),			"Warning: low on fds. Don't use text filters",			"or the text extras menu in composition windows.",			0);	}	if (mt_debugging) {		(void) printf("replysw setup, #fds = %d\n", nfds_avail());		(void) fflush(stdout);	}}/* * Copy the selected message to the specified file. *//* ARGSUSED */voidmt_copy_proc(item, ie)	Panel_item      item;	Event          *ie;{        mt_do_save(0, ie, mt_has_selection());}/* Delete the current message and display the next message. *//* ARGSUSED */voidmt_del_proc(item, ie)	Panel_item      item;	Event          *ie;{	int             msg;	int		has_selection;	char           *p;	if (mt_nomail) {		mt_warn(mt_frame, "No Mail", 0);		return;	}	if ((msg = mt_get_curselmsg(0)) == 0)		return;	has_selection = mt_has_selection();	mt_yield_all();       /* use mt_yield_all() to save shelf */	if ((p = mt_value("trash")) || msg != mt_curmsg) {		/* no need to save current message if no trash folder */		mt_save_curmsg();		if (p)			(void)mt_copy_msg(msg, p);	}	mt_do_del(msg, ie, has_selection);}/* * Actually send the current reply-type message. *//* ARGSUSED */voidmt_deliver_proc(item, ie)	Panel_item      item;	Event          *ie;{	mt_do_deliver(item, ie);}/* Saves the shelf before before yeilding /* * Actually send the current reply-type message, but leave window intact. *//* ARGSUSED */voidmt_deliver_intact_proc(item, ie)	Panel_item      item;	Event          *ie;{	mt_do_deliver(item, ie);}/* * Yield all selections to Selection Service.  Use when exiting or * undertaking a lengthy process where the program * will be unable to respond to requests concerning selections held. * 					 * (bug# 1011496 & bug# 1009592 fix) * Routine also saves the current shelf (clipboard) with seln_hold_file(), * even if mailtool exits completely. */static voidmt_yield_all(){	Seln_holder	holder;	holder = seln_inquire(SELN_SHELF);	if (holder.state != SELN_NONE) 	/* if clipboard has something */	{	  int 		fd;	  Seln_request	*request;	  /* get ASCII contents of shelf, limit 2000 bytes */	  request = seln_ask(&holder, SELN_REQ_CONTENTS_ASCII, 0, 0);	  if (request->status == SELN_FAILED) 	    (void) fputs("Unable to get & save shelf contents\n", stderr);	  else if ((fd = open(mt_clipboard, (O_RDWR | O_TRUNC))) != -1) 	  {	    /* 	     * The 1st 4 bytes of the data buffer contain info to 	     * identify that a shelf has been returned.  Write out	     * the ASCII contents minus the 4 bytes into the opened	     * file, then close the file.	     */	    (void) write(fd, &request->data[4], strlen(request->data)-4);	    (void) close(fd); 	    /* tell the selection service to use file contents for shelf */	    if ((seln_hold_file(SELN_SHELF, mt_clipboard)) != SELN_SUCCESS)	      (void) fprintf(stderr,"Cannot get shelf in %s\n",mt_clipboard);	  }	  else	    (void) fprintf(stderr,"Cannot open %s to save shelf\n",mt_clipboard);	}	seln_yield_all();}/* * Done with the current folder, close the tool. *//* ARGSUSED */voidmt_done_proc(item, ie)	Panel_item      item;	Event          *ie;{	char           *p;	mt_save_curmsg();	/*	 * Since a commit has been made, check to see if the header array can	 * be reduced in size.	 */	if ((mt_maxmsg-mt_del_count) <= (current_size-INCR_SIZE))	{	  if((mt_message=(struct msg *)realloc((struct msg *)mt_message, 	     (unsigned)(sizeof(struct msg)*(current_size-INCR_SIZE)))) == NULL)		{		  	fprintf(stderr,"Realloc failed to decrement storage\n");			exit(1);		}		else			current_size -= INCR_SIZE;	}	(void) window_set(mt_frame, FRAME_CLOSED, TRUE, 0);	(void) win_post_id(mt_frame, WIN_RESIZE, NOTIFY_IMMEDIATE);	(void) win_post_id(mt_frame, WIN_REPAINT, NOTIFY_IMMEDIATE);	mt_tool_is_busy(TRUE, "going idle...");	if (mt_open_menu_item)		(void) menu_set(mt_open_menu_item,			MENU_PULLRIGHT, mt_open_menu_pullright,			0);	(void) win_release_event_lock(mt_cmdpanel_fd);	mt_yield_all();	if (!mt_idle_mail()) {	/* can fail if can't problems writing to /tmp */		mt_tool_is_busy(FALSE);		return;	}	mt_idle = TRUE;	mt_load_from_folder = NULL;	(void) strcpy(mt_folder, "[None]");	mt_set_nomail();	if (p = mt_value("trash"))		mt_del_folder(p);	mt_tool_is_busy(FALSE);}/* * Switch to the specified folder. *//* ARGSUSED */voidmt_folder_proc(item, ie)	Panel_item      item;	Event          *ie;{	char           *file;	static u_long   last;	u_long          when;	when = event_time(ie).tv_sec;	/*	 * (Bug# 1009020 fix) when mailtool is iconic and the user opens	 * the tool into a particular folder, the above line will set to	 * "when = 0".  I added that check below so mailtool will not 	 * abort the loading of a folder from the iconic state.	 */ 	if (when != 0 && last != 0 && when < last ) {		/*		 * this event occurred BEFORE the last folder operation		 * completed, i.e., user bounced on the key 		 */		last = when;		return;	}	(void)win_release_event_lock(mt_cmdpanel_fd);	file = (char *)panel_get_value(mt_file_item);	if (file == NULL || *file == '\0') {		mt_warn(mt_frame, "Must specify file name.", 0);		return;	}	mt_save_filename(file);	mt_new_folder(file, FALSE, FALSE);	last = mt_current_time();}/* * Include the selected message in the message composition window. *//* ARGSUSED */voidmt_include_proc(item, ie)	Panel_item      item;	Event          *ie;{	Frame           frame;	struct reply_panel_data *ptr;	int             msg;	Textsw_status	status;	if (mt_nomail) {		mt_warn(mt_frame, "No Mail", 0);		return;	} else if ((msg = mt_get_curselmsg(0)) == 0) 		/* warning displayed in mt_get_curselmsg */		return;	ptr = (struct reply_panel_data *)panel_get(		panel_get(item, PANEL_PARENT_PANEL),		PANEL_CLIENT_DATA);	frame = window_get(ptr->replysw, WIN_OWNER);	mt_save_curmsg();	if (!(mt_include_msg(msg, mt_scratchfile, event_ctrl_is_down(ie))))		return;	(void) window_set(ptr->replysw,		TEXTSW_STATUS, &status,		TEXTSW_INSERT_FROM_FILE, mt_scratchfile,		0);	if (status == TEXTSW_STATUS_OUT_OF_MEMORY) 		mt_warn(frame,			"Insertion failed: memory buffer exceeded.",			 "You can get around this by undoing the Include,",			 "using the text menu to store the contents of the",			 "message composition window to a file, and then",			 "redoing the include. Or, you can enlarge the size",			 "of the memory buffer by using defaultsedit to",			 "increase the default value of \'memorymaximum\'",			 "quitting mailtool, and starting again.",			0);	/*	 * this copies the bytes, so don't have to worry about overwriting	 * scratch file if more than one include. 	 */

⌨️ 快捷键说明

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