diff options
Diffstat (limited to 'ftpfs/conn.c')
-rw-r--r-- | ftpfs/conn.c | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/ftpfs/conn.c b/ftpfs/conn.c new file mode 100644 index 00000000..930e2eb7 --- /dev/null +++ b/ftpfs/conn.c @@ -0,0 +1,105 @@ +/* Ftp connection management + + Copyright (C) 1997 Free Software Foundation, Inc. + Written by Miles Bader <miles@gnu.ai.mit.edu> + This file is part of the GNU Hurd. + + The GNU Hurd is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + The GNU Hurd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ + +#include <assert.h> + +#include "ftpfs.h" + +/* A particular connection. */ +struct ftpfs_conn +{ + struct ftp_conn *conn; + struct ftpfs_conn *next; +}; + +/* For debugging purposes, give each connection a unique integer id. */ +static unsigned conn_id = 0; + +/* Get an ftp connection to use for an operation. */ +error_t +ftpfs_get_ftp_conn (struct ftpfs *fs, struct ftp_conn **conn) +{ + struct ftpfs_conn *fsc; + + spin_lock (&fs->conn_lock); + fsc = fs->free_conns; + if (fsc) + fs->free_conns = fsc->next; + spin_unlock (&fs->conn_lock); + + if (! fsc) + { + error_t err; + + fsc = malloc (sizeof (struct ftpfs_conn)); + if (! fsc) + return ENOMEM; + + err = ftp_conn_create (fs->ftp_params, fs->ftp_hooks, &fsc->conn); + + if (! err) + { + /* Set connection type to binary. */ + err = ftp_conn_set_type (fsc->conn, "I"); + if (err) + ftp_conn_free (fsc->conn); + } + + if (err) + { + free (fsc); + return err; + } + + /* For debugging purposes, give each connection a unique integer id. */ + fsc->conn->hook = (void *)conn_id++; + } + + spin_lock (&fs->conn_lock); + fsc->next = fs->conns; + fs->conns = fsc; + spin_unlock (&fs->conn_lock); + + *conn = fsc->conn; + + return 0; +} + +/* Return CONN to the pool of free connections in FS. */ +void +ftpfs_release_ftp_conn (struct ftpfs *fs, struct ftp_conn *conn) +{ + struct ftpfs_conn *fsc, *pfsc; + + spin_lock (&fs->conn_lock); + for (pfsc = 0, fsc = fs->conns; fsc; pfsc = fsc, fsc = fsc->next) + if (fsc->conn == conn) + { + if (pfsc) + pfsc->next = fsc->next; + else + fs->conns = fsc->next; + fsc->next = fs->free_conns; + fs->free_conns = fsc; + break; + } + assert (fsc); + spin_unlock (&fs->conn_lock); +} |