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

📄 server.c

📁 一套客户/服务器模式的备份系统代码,跨平台,支持linux,AIX, IRIX, FreeBSD, Digital Unix (OSF1), Solaris and HP-UX.
💻 C
📖 第 1 页 / 共 5 页
字号:
    fd = open(devicename, O_RDONLY | NONBLOCKING_FLAGS);    if(fd < 0)	st = -1;  }  if(st){    t = time(NULL);    t_mail = t + devunavail_send_mail * 60;    t_giveup = t + devunavail_give_up * 60;    do{      if(check_interrupted())	do_exit(1);      if(t_mail > 0 && t > t_mail && devunavail_send_mail > 0){	fp = tmp_fp(NULL);	if(fp){	  fprintf(fp, T_("The device %s on host %s is not ready for use.\n"),			devicename, unam.nodename);	  fprintf(fp, T_("You are requested to check the device for possible\n"));	  fprintf(fp, T_("errors and to correct them.\n\n"));	  fprintf(fp, T_("Best regards from your backup service.\n"));	  i = message_to_operator(fp, YES);	}	if(i || !fp){	  logmsg(LOG_ERR, T_("Error: Unable to ask user %s to check device availability.\n"),			user_to_inform);	}	t_mail = 0;      }      if(t_giveup > 0 && t > t_giveup && devunavail_give_up > 0){	logmsg(LOG_ERR, T_("Warning: Device access timed out.\n"));	return((Int32) DEVNOTREADY);      }      ms_sleep(1000 * 10);      t += 10;      st = stat(devicename, &devstatb);      if(!st && !IS_DIRECTORY(devstatb)){	fd = open(devicename, O_RDONLY | NONBLOCKING_FLAGS);	if(fd < 0)	  st = -1;      }    } while(st);  }  if(fd >= 0)    close(fd);  return(0);}static int			/* here we force stdin of the subprocess to */notty0system(char * cmd)	/* be no tty, thus it never gets interactive */{  int	pid, pst, i;  int	inpipe[2];  char	*shell;  i = pipe(inpipe);  if(i)   return(-1);  pid = fork_forced();  if(pid < 0)    return(-1);  if(pid == 0){    setpgid(0, 0);    close(inpipe[1]);    dup2(inpipe[0], 0);    shell = getenv("SHELL");    if(!shell || ! FN_ISABSPATH(shell)){	if(!access("/bin/sh", X_OK))	  shell = "/bin/sh";	else if(!access("/usr/bin/sh", X_OK))	  shell = "/usr/bin/sh";	else	  shell = find_program("sh");    }    if(!shell)	exit(99);    execl(shell, shell, "-c", cmd, NULL);    exit(98);  }  pgid_to_kill_on_interrupt = pid;  close(inpipe[0]);  pid = waitpid_forced(pid, &pst, 0);  close(inpipe[1]);  pgid_to_kill_on_interrupt = -1;  return(WEXITSTATUS(pst));}Int32poll_device_cmd(UChar * cmd, Flag wait_success, Int32 maxtries){  int		res;  Int32		i;	/* uninitialized ok */  Int32		tries;  time_t	t, t_mail, t_giveup;  FILE		*fp;  if(strlen(remoteuser) > 0)    set_env(REMOTEUSERENVVAR, remoteuser);  if(strlen(clientuname) > 0)    set_env(REMOTEHOSTENVVAR, clientuname);  res = notty0system(cmd);	  tries = 1;  if(res && (wait_success || maxtries > 0)){    t = time(NULL);    t_mail = t + devunavail_send_mail * 60;    t_giveup = t + devunavail_give_up * 60;    do{      if(check_interrupted())	do_exit(1);      if(maxtries > 0){	if(tries >= maxtries)	  break;	tries++;      }      if(t_mail > 0 && t > t_mail && devunavail_send_mail > 0){	fp = tmp_fp(NULL);	if(fp){	  fprintf(fp, T_("The device %s on host %s is not ready for use.\n"),			devicename, unam.nodename);	  fprintf(fp, T_("You are requested to check the device for possible\n"));	  fprintf(fp, T_("errors and to correct them.\n\n"));	  fprintf(fp, T_("Best regards from your backup service.\n"));	  i = message_to_operator(fp, YES);	}	if(i || !fp){	  logmsg(LOG_ERR, T_("Error: Unable to ask user %s to check device availability.\n"),			user_to_inform);	}	t_mail = 0;      }      if(t_giveup > 0 && t > t_giveup && devunavail_give_up > 0){	logmsg(LOG_ERR, T_("Warning: Device command timed out.\n"));	return((Int32) res);      }      ms_sleep(1000 * 30);      t += 30;    } while( (res = notty0system(cmd)) );  }  return(res);}Int32set_lock(LockData * the_lock, Int8 lock_mode){  struct stat	statb;  int		i, fd, lock_state = BU_NO_LOCK;  char		buf[30], *cptr;  struct flock	lockb;  if(the_lock->locked & BU_GOT_LOCK){    if(lock_mode == LOCK_WRITE && the_lock->locked != BU_GOT_LOCK_WR){	lseek(the_lock->lockfd, 0, SEEK_SET);	sprintf(buf, "%d %c\n", (int) getpid(), 'w');	write_forced(the_lock->lockfd, buf, strlen(buf) + 1);	the_lock->locked = BU_GOT_LOCK_WR;    }    return((Int32) the_lock->locked);  }  fd = open(the_lock->lockfile, O_RDONLY);  if(fd >= 0){    i = read(fd, buf, 29);    close(fd);    lock_state = BU_LOCKED_WR;    if(i > 0){	buf[i] = '\0';	for(cptr = buf + strlen(buf) - 1; cptr >= buf; cptr--){	  if(*cptr == 'r')	    lock_state = BU_LOCKED_RD;	  if(isdigit(*cptr))	    break;	}    }  }  i = lstat(the_lock->lockfile, &statb);  if(!i && !IS_REGFILE(statb)){    if(unlink(the_lock->lockfile)){	logmsg(LOG_CRIT, T_("Error: Cannot remove lock file entry `%s', that is not a file.\n"), the_lock->lockfile);	return( (Int32) (the_lock->locked = BU_CANT_LOCK) );    }    i = 1;  }  if(! i){    the_lock->lockfd = open(the_lock->lockfile, O_WRONLY | O_SYNC);    if(the_lock->lockfd < 0){      logmsg(LOG_ERR, T_("Warning: Lock file `%s' exists, but can't open it.\n"),			the_lock->lockfile);      return( (Int32) (the_lock->locked = lock_state) );    }  }  else{    the_lock->lockfd = open(the_lock->lockfile, O_WRONLY | O_CREAT | O_SYNC, 0644);    if(the_lock->lockfd < 0){	logmsg(LOG_ERR, T_("Error: Cannot create lock file `%s'.\n"), the_lock->lockfile);	return( (Int32) (the_lock->locked = BU_CANT_LOCK) );    }  }  SETZERO(lockb);  lockb.l_type = F_WRLCK;  if(fcntl(the_lock->lockfd, F_SETLK, &lockb)){    close(the_lock->lockfd);    return( (Int32) (the_lock->locked = lock_state) );  }  sprintf(buf, "%d %c\n", (int) getpid(), lock_mode == LOCK_WRITE ? 'w' : 'r');  write_forced(the_lock->lockfd, buf, strlen(buf) + 1);  the_lock->locked = (lock_mode == LOCK_WRITE ? BU_GOT_LOCK_WR : BU_GOT_LOCK_RD);  return((Int32) the_lock->locked);}voidregister_pref_serv(){  struct flock	plockb;  time_t	locked_until, curtime;  UChar		locking_remhost[100], buf[300];  UChar		*cptr, *clientid_in_file = NULL;  Int32		lock_failed, i;  int		fd;  struct stat	statb;  fd = 0;  i = lstat(pref_client_file, &statb);  if(!i && !IS_REGFILE(statb)){    if(unlink(pref_client_file)){      if(errno != ENOENT){	logmsg(LOG_CRIT, T_("Warning: Cannot remove filesystem entry to check preferred service for client, that is not a regular file !!!\n"));	fd = -1;      }    }  }		/* check, if the same client did already connect recently */  if(!fd)    fd = open(pref_client_file, O_RDWR | O_CREAT, 0644);  if(fd < 0){    logmsg(LOG_WARNING, T_("Warning: Cannot open file to check preferred service for client.\n"));  }  else{    do{      SETZERO(plockb);      plockb.l_type = F_WRLCK;      lock_failed = fcntl(fd, F_SETLK, &plockb);			/* if we cannot get the lock, we will surely be able */      if(lock_failed)		/* to read the file after a short period */	ms_sleep(100 + (Int32) (drandom() * 500.0));      lseek(fd, 0, SEEK_SET);      i = read(fd, buf, 299);      if(i > 0){	buf[i] = '\0';	massage_string(buf);	if(word_count(buf) >= 2){	  cptr = sscanword(buf, locking_remhost);	  cptr = first_nospace(cptr);	  locked_until = 0;	  while(*cptr && isdigit(*cptr))	    locked_until = locked_until * 10 + (*(cptr++) - '0');	  cptr = first_nospace(cptr);		/* cptr now used as flag */	  if(*cptr){				/* client id on file -> */	    EM__(clientid_in_file = strdup(cptr));	    if(strcmp(client_id, "")){		/* if client did identify */		if(!strcmp(cptr, client_id))	/* and is identical */		  cptr = NULL;			/* no delay */	    }	    else{				/* in favour of the client */		cptr = NULL;			/* we assume, that it's the */	    }					/* same one and delay later */	  }					/* when receiving the ID */	  else{		/* no client id on file: no delay by client id */	    cptr = NULL;	  }	  if(same_host(locking_remhost, remotehost) <= 0 || cptr){	    curtime = time(NULL);	    if(locked_until >= curtime){		ms_sleep(1000 * (locked_until + 1 - curtime));	    }	  }	}      }    } while(lock_failed);    lseek(fd, 0, SEEK_SET);    EM__(cptr = time_t_to_intstr(time(NULL) + PREF_CLIENT_DELAY, NULL));    sprintf(buf, "%s %s", remotehost, cptr);    free(cptr);    if(strcmp(client_id, "")){	strcat(buf, " ");	strcat(buf, client_id);    }    else if(clientid_in_file){		/* keep the old one in place */	strcat(buf, " ");	strcat(buf, clientid_in_file);	free(clientid_in_file);    }    strcat(buf, "\n");    i = strlen(buf) + 1;    write(fd, buf, i);    ftruncate(fd, i);    close(fd);  }}Int32release_lock(LockData * the_lock){  if(the_lock->locked & BU_GOT_LOCK){#if	0	/* unnecessary: close removes any lock */    struct flock	lockb;    SETZERO(lockb);    lockb.l_type = F_UNLCK;    fcntl(the_lock->lockfd, F_SETLK, &lockb);#endif    close(the_lock->lockfd);    unlink(the_lock->lockfile);    the_lock->lockfd = -1;    the_lock->locked = BU_NO_LOCK;  }  return(the_lock->locked);}Int32wait_for_service(Int8 lock_mode, Flag quiet){  time_t	t, t_mail, t_giveup;  FILE		*fp;  Int32		lck;  Int32		i;	/* uninitialized ok */  int		sleeptime;  if(!quiet)    statusmsg(T_("Waiting for device %s to become available.\n"),				(char *) devicename);  lck = set_lock(&g_lock, lock_mode);  if(lck == BU_CANT_LOCK)    return((Int32) FATAL_ERROR);  if(lck & BU_LOCKED){    t = time(NULL);    t_mail = t + devunavail_send_mail * 60;    t_giveup = t + devunavail_give_up * 60;    sleeptime = 1;    do{      if(check_interrupted())	do_exit(1);      if(t_mail > 0 && t > t_mail && devunavail_send_mail > 0){	fp = tmp_fp(NULL);	if(fp){	  fprintf(fp, T_("The backup service on host %s is in use.\n"), unam.nodename);	  fprintf(fp, T_("You are requested to check the service for possible\n"));	  fprintf(fp, T_("errors and to correct them.\n\n"));	  fprintf(fp, T_("Best regards from your backup service.\n"));	  i = message_to_operator(fp, NO);	}	if(i || !fp){	  logmsg(LOG_ERR, T_("Error: Unable to ask user %s to check service availability.\n"),			user_to_inform);	}	t_mail = 0;      }      if(t_giveup > 0 && t > t_giveup && devunavail_give_up > 0){	logmsg(LOG_WARNING, T_("Warning: Service access timed out.\n"));	return((Int32) SERVICEINUSE);      }      ms_sleep(1000 * sleeptime);      t += sleeptime;      sleeptime = (sleeptime < 30 ? sleeptime + 1 : 30);      lck = set_lock(&g_lock, lock_mode);      if(lck == BU_CANT_LOCK)	return((Int32) FATAL_ERROR);    } while(! (lck & BU_GOT_LOCK));    ER__(read_tapepos_file(), i);	/* if we had to wait, this */  }				/* information is probably outdated */  if(!quiet)    statusmsg(T_("Device %s available, idle.\n"), (char *) devicename);  return(0);}Int32		/* reopen the stream for writing, this is not a cmd */reopentapewr(){  Int32		i, ret = NO_ERROR;  int		filemode;  UChar		*filename;  statusmsg(T_("Device %s reopening for write.\n"), (char *) devicename);  if(TAPE_NOT_CLOSED && (tapeaccessmode & MODE_MASK) != OPENED_FOR_WRITE){    logmsg(LOG_CRIT, T_("Internal Error: tape not open for writing in reopen.\n"));    ret = FATAL_ERROR;    GETOUT;  }  if(TAPE_NOT_CLOSED){    if(tapefd >= 0){      i = close(tapefd);      tapefd = -1;      if(i){	ret = i;	GETOUT;      }    }  }  if(interrupted)    do_exit(1);  bytes_in_tapefile = 0;  endofrec = NO;  if( (i = save_bytes_per_tape_msg(bytesontape_file, actcart,				bytes_on_tape, actfilenum, NO, time(NULL))) ){    ret = i;    GETOUT;  }  if(TAPE_NOT_CLOSED){    actfilenum++;    insfilenum[active_cartset]++;    rdfilenum = actfilenum;  }  if( (i = write_tapepos_file_msg()) ){    ret = i;    GETOUT;  }  if(stat(devicename, &devstatb)){    ret = -errno;    GETOUT;  }  if(IS_REGFILE(devstatb) || IS_DIRECTORY(devstatb)){    if( (i = update_devicesettings(insfilenum[active_cartset], YES)) ){      logmsg(LOG_ERR, T_("Error: Cannot change store file.\n"));      ret = i;      GETOUT;    }  }  tape_moved = YES;  tape_rewound = NO;  filename = devicename;  filemode = O_WRONLY | O_BINARY;  if(IS_DIRECTORY(devstatb)){    filename = storefile;    filemode = O_WRONLY | O_CREAT | O_TRUNC | O_BINARY;  }  tapefd = open(filename, filemode, 0600);  if(tapefd < 0){    logmsg(LOG_ERR, T_("Error: Cannot open tape once again for writing.\n"));    ret = -errno;    GETOUT;  }  tapeaccessmode = OPENED_FOR_WRITE;  if( (i = save_bytes_per_tape_msg(bytesontape_file, actcart,				bytes_on_tape, actfilenum, NO, time(NULL))) ){    ret = i;    GETOUT;  }  filenum_incr_by_eof = NO;  statusmsg(T_("Device %s opened for writing to cartridge %d, file %d.\n"),		(char *) devicename, (int) actcart, (int) actfilenum);  return(0); getout:  if(tapefd >= 0)    close(tapefd);

⌨️ 快捷键说明

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