📄 server.c
字号:
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 + -