int add_session(char *nick, char *host, char *hostip) { Session *session, **list; Exception *exception; int sessionlimit = 0; session = findsession(host); if (session) { exception = find_hostip_exception(host, hostip); if (checkDefCon(DEFCON_REDUCE_SESSION)) { sessionlimit = exception ? exception->limit : DefConSessionLimit; } else { sessionlimit = exception ? exception->limit : DefSessionLimit; } if (sessionlimit != 0 && session->count >= sessionlimit) { if (SessionLimitExceeded) notice(s_OperServ, nick, SessionLimitExceeded, host); if (SessionLimitDetailsLoc) notice(s_OperServ, nick, "%s", SessionLimitDetailsLoc); /* We don't use kill_user() because a user stucture has not yet * been created. Simply kill the user. -TheShadow */ kill_user(s_OperServ, nick, "Session limit exceeded"); session->hits++; if (MaxSessionKill && session->hits >= MaxSessionKill) { char akillmask[BUFSIZE]; snprintf(akillmask, sizeof(akillmask), "*@%s", host); add_akill(NULL, akillmask, s_OperServ, time(NULL) + SessionAutoKillExpiry, "Session limit exceeded"); anope_cmd_global(s_OperServ, "Added a temporary AKILL for \2%s\2 due to excessive connections", akillmask); } return 0; } else { session->count++; return 1; } } nsessions++; session = scalloc(sizeof(Session), 1); session->host = sstrdup(host); list = &sessionlist[HASH(session->host)]; session->next = *list; if (*list) (*list)->prev = session; *list = session; session->count = 1; return 1; }
void del_session(const char *host) { Session *session; if (!LimitSessions) { if (debug) { alog("debug: del_session called when LimitSessions is disabled"); } return; } if (!host || !*host) { if (debug) { alog("debug: del_session called with NULL values"); } return; } if (debug >= 2) alog("debug: del_session() called"); session = findsession(host); if (!session) { if (debug) { anope_cmd_global(s_OperServ, "WARNING: Tried to delete non-existant session: \2%s", host); alog("session: Tried to delete non-existant session: %s", host); } return; } if (session->count > 1) { session->count--; return; } if (session->prev) session->prev->next = session->next; else sessionlist[HASH(session->host)] = session->next; if (session->next) session->next->prev = session->prev; if (debug >= 2) alog("debug: del_session(): free session structure"); free(session->host); free(session); nsessions--; if (debug >= 2) alog("debug: del_session() done"); }
static int ptfs_release(const char *path, struct fuse_file_info *fi) { unsigned int SID, inode, ret = 0; if ( (SID = findsession( path )) == -1 ) return -ENOENT; if ( (inode = findbypath( sessions[SID], hidedate( path ) ) ) == -1 ) return -ENOENT; pthread_mutex_lock( &sessions[SID].nodes[inode].mutex ); close( fi->fh ); /* zamykamy dopiero gdy ostatni bedzie chcial zamknac */ if ( !( --sessions[SID].nodes[inode].count ) ) if ( SID < sessCounter - 1 ) if ( remove( sessions[SID].nodes[inode].tmpnm ) ) ret = -errno; pthread_mutex_unlock( &sessions[SID].nodes[inode].mutex ); return ret; }
static int ptfs_getattr(const char *path, struct stat *stbuf) { unsigned int inode, SID; bzero(stbuf, sizeof(struct stat)); if ( strcmp( path, "/" ) == 0 ) { stbuf->st_mode = S_IFDIR | 0500; stbuf->st_nlink = sessCounter + 2; stbuf->st_mtime = mounttime; stbuf->st_atime = root_atime; stbuf->st_ctime = mounttime; stbuf->st_size = sessCounter + 2; stbuf->st_uid = getuid(); stbuf->st_gid = getgid(); return 0; } if ( strncmp( path, link_current, strlen(link_current)-1 ) == 0 ) { makestat( stbuf, &sessions[sessCounter-1].nodes[0].st, &sessions[sessCounter-1].st ); stbuf->st_mode = S_IFLNK | 0500; stbuf->st_size = strlen(sessions[sessCounter-1].nm)+1; stbuf->st_atime = link_curr_atime; return 0; } if ( strncmp( path, link_previous, strlen(link_previous)-1 ) == 0 ) { if ( sessCounter < 2 ) return -ENOENT; makestat( stbuf, &sessions[sessCounter-2].nodes[0].st, &sessions[sessCounter-2].st ); stbuf->st_mode = S_IFLNK | 0500; stbuf->st_size = strlen(sessions[sessCounter-2].nm)+1; stbuf->st_atime = link_prev_atime; return 0; } SID = findsession( path ); if ( SID == -1 ) return -ENOENT; inode = findbypath( sessions[SID], hidedate(path) ); if ( inode == -1 ) return -ENOENT; makestat( stbuf, &sessions[SID].nodes[inode].st, &sessions[SID].st ); return 0; }
static int ptfs_open(const char *path, struct fuse_file_info *fi) { unsigned int SID, inode; int fd = -1, i, j, ret = 0; if ( (SID = findsession( path )) == -1 ) return -ENOENT; if ( (inode = findbypath( sessions[SID], hidedate( path ) ) ) == -1 ) return -ENOENT; if ( (fi->flags & 3) != O_RDONLY ) return -EACCES; pthread_mutex_lock( &sessions[SID].nodes[inode].mutex ); sessions[SID].nodes[inode].st.atime = time(0); /* dostep */ if ( sessions[SID].nodes[inode].count == 0 ) { /* trzeba otworzyc... */ if ( SID == sessCounter - 1 ) { /* na szczescie najnowsza wersja, bedzie szybciej */ strncpy( sessions[SID].nodes[inode].tmpnm, rdiffpath, PATHLEN ); i = j = 0; while ( sessions[SID].nodes[inode].tmpnm[++i] ) /* obciecie koncowki /rdiff-backup-data/ **/ if ( sessions[SID].nodes[inode].tmpnm[i] == '/' && sessions[SID].nodes[inode].tmpnm[i+1] ) j = i; strncpy( sessions[SID].nodes[inode].tmpnm + j, hidedate(path), PATHLEN - j ); /* plus lokalizacja pliku **/ if ( (fd = open( sessions[SID].nodes[inode].tmpnm, O_RDONLY )) == -1 ) ret = -errno; if ( !ret ) sessions[SID].nodes[inode].count = 1; /* wpp, trzeba przywrocic plik z odpowiedniej wersji, restore() da nam fd */ } else if ( ( fd = restore( path, sessions[SID].nodes[inode].tmpnm )) < 0 ) ret = fd; else sessions[SID].nodes[inode].count = 1; /* juz mamy gotowy fd to zwiekszamy licznik */ /* Otwieranie otwartego pliku... */ } else if ( ( fd = open( sessions[SID].nodes[inode].tmpnm, O_RDONLY ) ) == -1 ) ret = -errno; else ++sessions[SID].nodes[inode].count; /* juz mamy gotowy fd to zwiekszamy licznik */ pthread_mutex_unlock( &sessions[SID].nodes[inode].mutex ); if ( !ret ) fi->fh = fd; return ret; }
static int restore( const char * path, char * dest ) { /** rdiff-backup -r date path_1 path_2 **/ int fd, st; unsigned int SID, i, j; char buf[PATHLEN]; if ( ( SID = findsession( path ) ) == -1 ) return -ENOENT; i = j = 0; strncpy( buf, rdiffpath, PATHLEN ); while ( buf[++i] ) /* obciecie koncowki /rdiff-backup-data/ **/ if ( buf[i] == '/' && buf[i+1] ) j = i; strncpy( buf + j, hidedate(path), PATHLEN - j ); /* plus lokalizacja pliku **/ strncpy( dest, tmp_template, PATHLEN ); if ( (fd = mkstemp( dest )) == -1 ) return -errno; switch ( fork() ) { case -1: return -errno; case 0: close ( fd ); /* pobieramy wlasciwa wersje rdiffem */ execlp( "rdiff-backup", "rdiff-backup", "--force", "-r", sessions[SID].date, buf, dest, 0 ); return -errno; default: wait(&st); } close( fd ); if ( (fd = open ( dest, O_RDONLY )) == -1 ) { remove( dest ); /* usuwamy plik, bo cos sie popsulo */ return -errno; } if ( st ) { /* cos nie tak bylo z execlp */ close( fd ); remove( dest ); return st; } else return fd; /* jak wszystko ok, to fd */ }
static int ptfs_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi) { struct list * t; unsigned int i = 0, SID, inode; filler( buf, ".", NULL, 0 ); filler( buf, "..", NULL, 0 ); if ( strcmp( path, "/" ) == 0 ) { /* gdy czytamy glowny katalog... */ for ( i = 0; i < sessCounter; ++i ) filler( buf, sessions[i].nm + 1, NULL, 0 ); filler( buf, link_current + 1, NULL, 0 ); if ( sessCounter > 1 ) filler( buf, link_previous + 1, NULL, 0 ); /* zmieniamy czas dostepu, gdy czytamy katalog */ root_atime = time(0); return 0; } if ( ( SID = findsession( path ) ) == -1 ) return -ENOENT; if ( ( inode = findbypath( sessions[SID], hidedate(path) ) ) == -1 ) return -ENOENT; t = sessions[SID].nodes[inode].in; if ( t == NULL ) return 0; do { /* przechodzmy sie po liscie plikow obecnych w katalogu */ filler( buf, lastname(getnode(t)->nm) , NULL, 0 ); t = t->next; } while ( t != sessions[SID].nodes[inode].in ); pthread_mutex_lock( &sessions[SID].nodes[inode].mutex ); sessions[SID].nodes[inode].st.atime = time(0); /* dostep */ pthread_mutex_unlock( &sessions[SID].nodes[inode].mutex ); return 0; }
int do_session(User * u) { Session *session; Exception *exception; char *cmd = strtok(NULL, " "); char *param1 = strtok(NULL, " "); int mincount; int i; if (!LimitSessions) { notice_lang(s_OperServ, u, OPER_SESSION_DISABLED); return MOD_CONT; } if (!cmd) cmd = ""; if (stricmp(cmd, "LIST") == 0) { if (!param1) { syntax_error(s_OperServ, u, "SESSION", OPER_SESSION_LIST_SYNTAX); } else if ((mincount = atoi(param1)) <= 1) { notice_lang(s_OperServ, u, OPER_SESSION_INVALID_THRESHOLD); } else { notice_lang(s_OperServ, u, OPER_SESSION_LIST_HEADER, mincount); notice_lang(s_OperServ, u, OPER_SESSION_LIST_COLHEAD); for (i = 0; i < 1024; i++) { for (session = sessionlist[i]; session; session = session->next) { if (session->count >= mincount) notice_lang(s_OperServ, u, OPER_SESSION_LIST_FORMAT, session->count, session->host); } } } } else if (stricmp(cmd, "VIEW") == 0) { if (!param1) { syntax_error(s_OperServ, u, "SESSION", OPER_SESSION_VIEW_SYNTAX); } else { session = findsession(param1); if (!session) { notice_lang(s_OperServ, u, OPER_SESSION_NOT_FOUND, param1); } else { exception = find_host_exception(param1); notice_lang(s_OperServ, u, OPER_SESSION_VIEW_FORMAT, param1, session->count, exception ? exception-> limit : DefSessionLimit); } } } else { syntax_error(s_OperServ, u, "SESSION", OPER_SESSION_SYNTAX); } return MOD_CONT; }