#include "ftptool.h"
#pragma ident "@(#)schedule.c 1.5 93/08/19"
#ifdef USE_PROTOTYPES
struct schedule *new_schedule(char *menu_name, int direction,
time_t date, time_t repeat_minutes, char *filename,
struct hostlist *hl)
#else
struct schedule *new_schedule(menu_name, direction, date,
repeat_minutes, filename, hl)
char *menu_name;
int direction;
time_t date;
time_t repeat_minutes;
char *filename;
struct hostlist *hl;
#endif
{
struct schedule *tmp = NULL;
tmp = (struct schedule *)malloc(sizeof (struct schedule));
if (tmp == NULL)
return (NULL);
bzero((char *)tmp, sizeof (struct schedule));
tmp->menu_name = (char *)malloc((unsigned int)(2+strlen(menu_name)+1));
if (tmp->menu_name == NULL) {
free_schedule(tmp);
return (NULL);
}
sprintf(tmp->menu_name, "%c:%s", direction == RECV ? 'R' : 'S',
menu_name);
tmp->direction = direction;
tmp->date = date;
tmp->repeat_minutes = repeat_minutes;
tmp->filename = strdup(filename);
if (tmp->filename == NULL) {
free_schedule(tmp);
return (NULL);
}
tmp->hl = (struct hostlist *)malloc(sizeof (struct hostlist));
if (tmp->hl == NULL) {
free_schedule(tmp);
return (NULL);
}
bcopy((char *)hl, (char *)tmp->hl, sizeof (struct hostlist));
tmp->next = NULL;
return (tmp);
}
#ifdef USE_PROTOTYPES
struct schedule *add_schedule(struct schedule *head, char *menu_name,
int direction, time_t date, time_t repeat_minutes, char *filename,
struct hostlist *hl)
#else
struct schedule *add_schedule(head, menu_name, direction, date,
repeat_minutes, filename, hl)
struct schedule *head;
char *menu_name;
int direction;
time_t date;
time_t repeat_minutes;
char *filename;
struct hostlist *hl;
#endif
{
struct schedule *tmp = NULL;
struct schedule *oldnext = NULL;
for (tmp = head; tmp->next != NULL; tmp = tmp->next)
if (date < tmp->next->date)
break;
oldnext = tmp->next;
tmp->next = new_schedule(menu_name, direction, date, repeat_minutes,
filename, hl);
if (tmp->next == NULL) {
tmp->next = oldnext;
return (NULL);
}
tmp->next->next = oldnext;
return (head);
}
#ifdef USE_PROTOTYPES
void free_schedule(struct schedule *head)
#else
void free_schedule(head)
struct schedule *head;
#endif
{
struct schedule *tmp = NULL;
struct schedule *item = NULL;
item = head;
while (item) {
tmp = item->next;
if (item->menu_name)
free(item->menu_name);
if (item->filename) {
(void) unlink(item->filename);
free(item->filename);
}
if (item->hl)
free_hostlist(item->hl);
free((char *)item);
item = tmp;
}
return;
}
#ifdef USE_PROTOTYPES
void delete_schedule(struct schedule *head, char *menu_name, int direction)
#else
void delete_schedule(head, menu_name, direction)
struct schedule *head;
char *menu_name;
int direction;
#endif
{
struct schedule *tmp = NULL;
struct schedule *item = NULL;
for (tmp = head; tmp->next != NULL; tmp = tmp->next)
if (tmp->next->direction == direction &&
!strcmp(menu_name, &tmp->next->menu_name[2])) {
item = tmp->next;
tmp->next = tmp->next->next;
item->next = NULL;
free_schedule(item);
return;
}
return;
}
#ifdef USE_PROTOTYPES
void reorder_list(struct schedule *head)
#else
void reorder_list(head)
struct schedule *head;
#endif
{
struct schedule *tmp = NULL;
struct schedule nl;
struct schedule *newlist = &nl;
struct schedule *item = NULL;
struct schedule *oldnext = NULL;
newlist->next = NULL;
item = head->next;
while (item != NULL) {
/* insert item in tmp */
for (tmp = newlist; tmp->next != NULL; tmp = tmp->next)
if (item->date < tmp->next->date)
break;
oldnext = tmp->next;
tmp->next = item;
item = item->next;
tmp->next->next = oldnext;
}
head->next = newlist->next;
}
#ifdef USE_PROTOTYPES
void load_schedule(void)
#else
void load_schedule()
#endif
{
static char scratch[2 * MAXHOSTNAMELEN + 4];
char *host = NULL;
char *login = NULL;
schedule_footer_message("");
host = (char *)xv_get(host_window.basic.host, PANEL_VALUE);
login = (char *)xv_get(host_window.basic.login, PANEL_VALUE);
sprintf(scratch, "%s@%s", login, host);
xv_set(schedule_window.menu_name,
PANEL_VALUE, scratch,
NULL);
update_date(1);
xv_set(schedule_window.frame,
XV_SHOW, TRUE,
NULL);
}
#ifdef USE_PROTOTYPES
void set_current_schedule_proc(Menu menu, Menu_item menu_item)
#else
void set_current_schedule_proc(menu, menu_item)
Menu menu;
Menu_item menu_item;
#endif
{
load_schedule();
xv_set(menu,
MENU_NOTIFY_STATUS, XV_ERROR,
NULL);
}
#ifdef USE_PROTOTYPES
int schedule_exists(struct schedule *head, char *menu_name,
int direction)
#else
int schedule_exists(head, menu_name, direction)
struct schedule *head;
char *menu_name;
int direction;
#endif
{
struct schedule *tmp = NULL;
for (tmp = head->next; tmp != NULL; tmp = tmp->next) {
if (direction == tmp->direction &&
!strcmp(menu_name, &tmp->menu_name[2]))
return (1);
}
return (0);
}
#ifdef USE_PROTOTYPES
void enter_schedule_info(int warnchange)
#else
void enter_schedule_info(warnchange)
int warnchange;
#endif
{
char *menu_name = NULL;
int direction;
time_t repeat_minutes;
time_t date;
struct tm tm;
char *filename = NULL;
int answer;
struct hostlist *hl = NULL;
int nitems;
int ret;
#ifdef XVIEW3
Xv_notice notice;
#endif
direction = (int)xv_get(schedule_window.direction, PANEL_VALUE);
if (direction == RECV)
nitems = (int)xv_get(schedule_window.receive_list,
PANEL_LIST_NROWS);
else
nitems = (int)xv_get(schedule_window.send_list,
PANEL_LIST_NROWS);
if (nitems == 0) {
schedule_footer_message("Select items to transfer first.");
goto out;
}
menu_name = (char *)xv_get(schedule_window.menu_name, PANEL_VALUE);
if (menu_name == '\0') {
schedule_footer_message("Specify login@host first.");
goto out;
}
if (schedule_exists(&schedule_list, menu_name, direction)) {
if (warnchange) {
#ifdef XVIEW3
notice = xv_create(schedule_window.panel, NOTICE,
NOTICE_MESSAGE_STRINGS,
"That host/action is scheduled. Do you really",
"want to change it?",
NULL,
NOTICE_BUTTON_YES, "Yes",
NOTICE_BUTTON_NO, "No",
NOTICE_STATUS, &answer,
XV_SHOW, TRUE,
NULL);
xv_destroy_safe(notice);
#else
answer = notice_prompt(schedule_window.panel, NULL,
NOTICE_MESSAGE_STRINGS,
"That host/action is scheduled. Do you really",
"want to change it?",
NULL,
NOTICE_BUTTON_YES, "Yes",
NOTICE_BUTTON_NO, "No",
NULL);
#endif
if (answer != NOTICE_YES)
goto out;
}
delete_schedule(&schedule_list, menu_name, direction);
}
bzero((char *)&tm, sizeof (tm));
tm.tm_hour = (int)xv_get(schedule_window.hour, PANEL_VALUE);
tm.tm_min = (int)xv_get(schedule_window.minute, PANEL_VALUE);
tm.tm_mon = (int)xv_get(schedule_window.month, PANEL_VALUE);
tm.tm_mday = (int)xv_get(schedule_window.day, PANEL_VALUE);
tm.tm_year = (int)xv_get(schedule_window.year, PANEL_VALUE) - 1900;
tm.tm_isdst = is_dst;
#if defined(SYSV) || defined(ultrix) || defined(SYSV386) || \
defined(AIXV3) || defined(hpux)
date = mktime(&tm);
#else
date = timelocal(&tm);
#endif
if (xv_get(schedule_window.repeat, PANEL_VALUE) == 1)
repeat_minutes = xv_get(schedule_window.repeat_minutes,
PANEL_VALUE);
else
repeat_minutes = 0;
filename = tempnam("/var/tmp", "sched");
if (filename == NULL) {
schedule_footer_message("Can't create temporary file.");
goto out;
}
if (direction == RECV)
ret = save_batch_list(schedule_window.receive_list, filename);
else
ret = save_batch_list(schedule_window.send_list, filename);
if (ret)
goto out;
hl = new_hostlist();
if (hl == NULL)
goto out;
bzero((char *)hl, sizeof (struct hostlist));
hl->aliasname = strdup((char *)(xv_get(host_window.advanced.alias,
PANEL_VALUE)));
if (hl->aliasname == NULL) {
goto out;
}
hl->proxy = strdup((char *)(xv_get(host_window.advanced.proxy,
PANEL_VALUE)));
if (hl->proxy == NULL) {
goto out;
}
hl->last_visited =
strdup((char *)(xv_get(host_window.advanced.last_visited,
PANEL_LABEL_STRING)));
if (hl->last_visited == NULL) {
goto out;
}
hl->host = strdup((char *)(xv_get(host_window.basic.host,
PANEL_VALUE)));
if (hl->host == NULL) {
goto out;
}
hl->login = strdup((char *)(xv_get(host_window.basic.login,
PANEL_VALUE)));
if (hl->login == NULL) {
goto out;
}
hl->password = strdup((char *)(xv_get(host_window.basic.password,
PANEL_VALUE)));
if (hl->password == NULL) {
goto out;
}
hl->transfer_mode = (int)xv_get(host_window.advanced.transfer_mode,
PANEL_VALUE);
hl->remote_directory = strdup((char *)
(xv_get(host_window.advanced.remote_auto_cd, PANEL_VALUE)));
if (hl->remote_directory == NULL) {
goto out;
}
hl->local_directory = strdup((char *)
(xv_get(host_window.advanced.local_auto_cd, PANEL_VALUE)));
if (hl->local_directory == NULL) {
goto out;
}
hl->dir_parse = strdup((char *)
(xv_get(host_window.advanced.dir_parse, PANEL_VALUE)));
if (hl->dir_parse == NULL) {
goto out;
}
hl->comment = strdup((char *)
(xv_get(host_window.advanced.comment, PANEL_VALUE)));
if (hl->comment == NULL) {
goto out;
}
if (add_schedule(&schedule_list, menu_name, direction, date,
repeat_minutes, filename, hl)
== NULL) {
xv_set(schedule_window.frame,
FRAME_SHOW_FOOTER, TRUE,
FRAME_LEFT_FOOTER, "Add failed.",
NULL);
goto out;
}
reload_schedule_menu(&schedule_list);
return;
out:
if (hl)
free_hostlist(hl);
return;
}
#ifdef USE_PROTOTYPES
void schedule_add_proc(Menu menu, Menu_item menu_item)
#else
void schedule_add_proc(menu, menu_item)
Menu menu;
Menu_item menu_item;
#endif
{
schedule_footer_message("");
enter_schedule_info(1);
xv_set(menu,
MENU_NOTIFY_STATUS, XV_ERROR,
NULL);
}
#ifdef USE_PROTOTYPES
void schedule_change_proc(Menu menu, Menu_item menu_item)
#else
void schedule_change_proc(menu, menu_item)
Menu menu;
Menu_item menu_item;
#endif
{
schedule_footer_message("");
enter_schedule_info(0);
xv_set(menu,
MENU_NOTIFY_STATUS, XV_ERROR,
NULL);
}
#ifdef USE_PROTOTYPES
void schedule_delete_proc(Menu menu, Menu_item menu_item)
#else
void schedule_delete_proc(menu, menu_item)
Menu menu;
Menu_item menu_item;
#endif
{
char *menu_name;
int direction;
schedule_footer_message("");
menu_name = (char *)xv_get(schedule_window.menu_name, PANEL_VALUE);
direction = (int)xv_get(schedule_window.direction, PANEL_VALUE);
delete_schedule(&schedule_list, menu_name, direction);
reload_schedule_menu(&schedule_list);
xv_set(menu,
MENU_NOTIFY_STATUS, XV_ERROR,
NULL);
}
#ifdef USE_PROTOTYPES
void schedule_item_proc(Menu menu, Menu_item menu_item)
#else
void schedule_item_proc(menu, menu_item)
Menu menu;
Menu_item menu_item;
#endif
{
struct schedule *tmp = NULL;
struct tm *tm = NULL;
schedule_footer_message("");
tmp = (struct schedule *)xv_get(menu_item, MENU_CLIENT_DATA);
xv_set(schedule_window.menu_name,
PANEL_VALUE, tmp->menu_name + 2,
NULL);
xv_set(schedule_window.direction,
PANEL_VALUE, tmp->direction,
NULL);
update_date(0);
tm = localtime(&tmp->date);
xv_set(schedule_window.frame,
XV_SHOW, TRUE,
NULL);
xv_set(schedule_window.hour,
PANEL_VALUE, tm->tm_hour,
NULL);
xv_set(schedule_window.minute,
PANEL_VALUE, tm->tm_min,
NULL);
xv_set(schedule_window.month,
PANEL_VALUE, tm->tm_mon,
NULL);
xv_set(schedule_window.day,
PANEL_VALUE, tm->tm_mday,
NULL);
xv_set(schedule_window.year,
PANEL_VALUE, tm->tm_year + 1900,
NULL);
if (tmp->repeat_minutes > 0) {
xv_set(schedule_window.repeat,
PANEL_VALUE, 1,
PANEL_CHOICE_STRING, 0, "in ",
XV_SHOW, TRUE,
NULL);
xv_set(schedule_window.repeat_minutes,
PANEL_VALUE, tmp->repeat_minutes,
XV_SHOW, TRUE,
NULL);
if (tmp->repeat_minutes > 1) {
xv_set(schedule_window.repeat_message,
PANEL_LABEL_STRING, "minutes",
PANEL_LABEL_BOLD, FALSE,
XV_SHOW, TRUE,
NULL);
} else {
xv_set(schedule_window.repeat_message,
PANEL_LABEL_STRING, "minute",
PANEL_LABEL_BOLD, FALSE,
XV_SHOW, TRUE,
NULL);
}
} else {
xv_set(schedule_window.repeat,
PANEL_VALUE, 0,
PANEL_CHOICE_STRING, 0, "",
XV_SHOW, TRUE,
NULL);
xv_set(schedule_window.repeat_minutes,
PANEL_VALUE, 1,
XV_SHOW, FALSE,
NULL);
xv_set(schedule_window.repeat_message,
PANEL_LABEL_STRING, "minute",
PANEL_LABEL_BOLD, FALSE,
XV_SHOW, FALSE,
NULL);
}
if (tmp->direction == RECV) {
load_batch_list(schedule_window.receive_list, tmp->filename);
} else {
load_batch_list(schedule_window.send_list, tmp->filename);
}
xv_set(menu,
MENU_NOTIFY_STATUS, XV_ERROR,
NULL);
}
#ifdef USE_PROTOTYPES
void reload_schedule_menu(struct schedule *head)
#else
void reload_schedule_menu(head)
struct schedule *head;
#endif
{
Menu menu = xv_get(schedule_window.hosts, PANEL_ITEM_MENU);
int nitems = xv_get(menu, MENU_NITEMS);
int row;
Menu_item mi;
Frame frame;
int isshown;
int maxwidth = 0;
int width = 0;
double cols;
struct schedule *tmp = NULL;
char *currentname;
frame = (Panel)xv_get(menu, MENU_PIN_WINDOW);
isshown = FALSE;
if (frame)
isshown = xv_get(frame, XV_SHOW);
currentname = (char *)xv_get(schedule_window.menu_name, PANEL_VALUE);
if (isshown) {
xv_set(frame,
#ifdef XVIEW3
FRAME_CMD_PIN_STATE, FRAME_CMD_PIN_OUT,
#else
FRAME_CMD_PUSHPIN_IN, FALSE,
#endif
XV_SHOW, FALSE,
NULL);
}
/* 2 items minimum, 1 for title */
for (row = nitems; row > 1; row--)
xv_set(menu,
MENU_REMOVE, row,
NULL);
nitems = 0;
for (tmp = head->next; tmp != NULL; tmp = tmp->next) {
width = strlen(tmp->menu_name);
maxwidth = MAX(maxwidth, width);
mi = (Menu_item)xv_create(XV_NULL, MENUITEM,
MENU_STRING, tmp->menu_name,
MENU_NOTIFY_PROC, schedule_item_proc,
MENU_CLIENT_DATA, tmp,
MENU_RELEASE,
NULL);
if (mi == XV_NULL) {
fprintf(stderr, "Out of memory for menu item.\n");
exit(1);
}
xv_set(menu,
MENU_APPEND_ITEM, mi,
PANEL_PAINT, PANEL_NONE,
NULL);
/* reload current information */
if (!strcmp(currentname, &tmp->menu_name[2]))
schedule_item_proc(menu, mi);
nitems++;
}
if (nitems == 0) {
mi = (Menu_item)xv_create(XV_NULL, MENUITEM,
MENU_STRING, "No Hosts!",
MENU_RELEASE,
NULL);
if (mi == XV_NULL) {
fprintf(stderr, "Out of memory for menu item.\n");
exit(1);
}
xv_set(menu,
MENU_APPEND_ITEM, mi,
NULL);
}
if (maxwidth == 0)
maxwidth = 1;
cols = 2.0 * nitems;
cols /= maxwidth;
cols = ceil(sqrt(cols));
xv_set(menu,
MENU_NCOLS, (int)cols,
NULL);
if (isshown) {
xv_set(frame,
#ifdef XVIEW3
FRAME_CMD_PIN_STATE, FRAME_CMD_PIN_IN,
#else
FRAME_CMD_PUSHPIN_IN, TRUE,
#endif
XV_SHOW, TRUE,
NULL);
}
}
#ifdef USE_PROTOTYPES
void action_choice_proc(Panel_item item, unsigned int value,
Event *event)
#else
void action_choice_proc(item, value, event)
Panel_item item;
unsigned int value;
Event *event;
#endif
{
schedule_footer_message("");
if (value == RECV) {
xv_set(schedule_window.send_list,
XV_SHOW, FALSE,
NULL);
xv_set(schedule_window.receive_list,
XV_SHOW, TRUE,
NULL);
} else {
xv_set(schedule_window.receive_list,
XV_SHOW, FALSE,
NULL);
xv_set(schedule_window.send_list,
XV_SHOW, TRUE,
NULL);
}
}
#ifdef USE_PROTOTYPES
Notify_value schedule_timer_proc(void)
#else
Notify_value schedule_timer_proc()
#endif
{
dowhat = DOSCHEDULE;
notify_stop();
return (NOTIFY_DONE);
}
#ifdef USE_PROTOTYPES
void activate_schedule_timer(void)
#else
void activate_schedule_timer()
#endif
{
time_t t;
struct itimerval itimer;
if (schedule_list.next == NULL) {
xv_set(schedule_window.process,
PANEL_LABEL_STRING, "Process Batch",
XV_HELP_DATA, "ftptool:ProcessBatch",
NULL);
return;
}
if (!strcmp((char *)xv_get(schedule_window.process, PANEL_LABEL_STRING),
"Process Batch"))
return; /* cancelled already */
t = time((time_t *)NULL);
itimer.it_value.tv_sec = schedule_list.next->date - t;
itimer.it_value.tv_usec = 0;
itimer.it_interval.tv_sec = 0;
itimer.it_interval.tv_usec = 0;
if (itimer.it_value.tv_sec < 0)
itimer.it_value.tv_sec = 1;
notify_set_itimer_func(schedule_window.frame, schedule_timer_proc,
ITIMER_REAL, &itimer, (struct itimerval *)NULL);
}
#ifdef USE_PROTOTYPES
void batch_process_proc(Panel_item item, Event *event)
#else
void batch_process_proc(item, event)
Panel_item item;
Event *event;
#endif
{
schedule_footer_message("");
if (!strcmp("Process Batch",
(char *)xv_get(item, PANEL_LABEL_STRING))) {
if (schedule_list.next == NULL) {
schedule_footer_message("Nothing to process.");
xv_set(item,
PANEL_NOTIFY_STATUS, XV_ERROR,
NULL);
return;
}
xv_set(item,
PANEL_LABEL_STRING, "Abort Batch",
XV_HELP_DATA, "ftptool:AbortBatch",
NULL);
xv_set(base_window.connect,
PANEL_INACTIVE, TRUE,
NULL);
xv_set(host_window.basic.connect,
PANEL_INACTIVE, TRUE,
NULL);
activate_schedule_timer();
batch_mode = 1;
} else {
xv_set(item,
PANEL_LABEL_STRING, "Process Batch",
XV_HELP_DATA, "ftptool:ProcessBatch",
NULL);
xv_set(base_window.connect,
PANEL_INACTIVE, FALSE,
NULL);
xv_set(host_window.basic.connect,
PANEL_INACTIVE, FALSE,
NULL);
notify_set_itimer_func(schedule_window.frame,
NOTIFY_FUNC_NULL, ITIMER_REAL, (struct itimerval *)NULL,
(struct itimerval *)NULL);
batch_mode = 0;
}
xv_set(item,
PANEL_NOTIFY_STATUS, XV_ERROR,
NULL);
}
#ifdef USE_PROTOTYPES
void doschedule(void)
#else
void doschedule()
#endif
{
struct schedule *tmp = schedule_list.next;
xv_set(host_window.advanced.alias,
PANEL_VALUE, tmp->hl->aliasname,
NULL);
xv_set(host_window.advanced.last_visited,
PANEL_LABEL_STRING, tmp->hl->last_visited,
NULL);
xv_set(host_window.advanced.proxy,
PANEL_VALUE, tmp->hl->proxy,
NULL);
xv_set(host_window.basic.host,
PANEL_VALUE, tmp->hl->host,
NULL);
xv_set(host_window.basic.login,
PANEL_VALUE, tmp->hl->login,
NULL);
xv_set(host_window.basic.password,
PANEL_VALUE, tmp->hl->password,
NULL);
xv_set(host_window.advanced.transfer_mode,
PANEL_VALUE, tmp->hl->transfer_mode,
NULL);
xv_set(host_window.advanced.remote_auto_cd,
PANEL_VALUE, tmp->hl->remote_directory,
NULL);
xv_set(host_window.advanced.local_auto_cd,
PANEL_VALUE, tmp->hl->local_directory,
NULL);
xv_set(host_window.advanced.dir_parse,
PANEL_VALUE, tmp->hl->dir_parse,
NULL);
xv_set(host_window.advanced.comment,
PANEL_VALUE, tmp->hl->comment,
NULL);
if (try_proxy) {
xv_set(host_window.advanced.proxy,
XV_SHOW, TRUE,
NULL);
} else {
xv_set(host_window.advanced.proxy,
XV_SHOW, FALSE,
NULL);
}
if (doconnect()) {
/* failed. Try again later. */
schedule_list.next->date += 300;
reorder_list(&schedule_list);
goto out;
}
if (tmp->direction == RECV) {
load_batch_list(schedule_window.receive_list, tmp->filename);
dobatchget();
} else {
load_batch_list(schedule_window.send_list, tmp->filename);
dobatchput();
}
disconnect();
if (tmp->repeat_minutes > 0) {
tmp->date += (tmp->repeat_minutes * 60);
reorder_list(&schedule_list);
} else {
delete_schedule(&schedule_list, &tmp->menu_name[2],
tmp->direction);
}
out:
reload_schedule_menu(&schedule_list);
activate_schedule_timer();
}
syntax highlighted by Code2HTML, v. 0.9.1