#include #include #include /* for stat() */ #include /* for unlink() */ #include #include /* for exec(), wait() et. al */ #include #include "global.h" #include "manhat-lib/shared_util.h" #include "manhat-lib/shared_super_util.h" #include "manhat-lib/shared_strtrm.h" #include "manhat-lib/shared_bio.h" #include "manhat-lib/shared_news_util.h" #include "manhat-lib/shared_file_util.h" #include "manhat-lib/shared_lock.h" #include "manhat-lib/shared_cs_util.h" #include "manhat-lib/shared_fold_file.h" /** Course is an optional parameter. If course is sent, *** the the user is working within a Manhattan course. *** Otherwise, they are working from the My Manhattan page. ***/ static void read_parameters (char *course, char *key, char *username, int *is_admin, char *email, char *website, int *photo) { char tmp[10 + 1]; cs_get_required_parameter ("id", key, MAX_KEY); cs_get_required_parameter ("user", username, MAX_USERNAME); cs_get_required_parameter ("photo", tmp, 10); *photo = atoi(tmp); cs_get_optional_parameter("email", email, MAX_URL); cs_get_optional_parameter("website", website, MAX_URL); cs_get_optional_parameter("crs", course, MAX_PATH); cs_get_optional_parameter("admin", tmp, 10); if(strlen(tmp)) *is_admin = 1; else *is_admin = 0; } static void write_cgi_bio_file (FILE *infp, const char *filepath) { #define CHUNKSIZE 2048 FILE *outfp; int bytes_read; int bytes_left; char buffer[CHUNKSIZE]; struct stat file_stat; if(fstat(fileno(infp), &file_stat)) cs_critical_error(ERR_NO_FILE, "write cgi file failed"); if(file_stat.st_size ==0) cs_critical_error(ERR_NO_FILE, "write cgi file failed"); outfp = fopen (filepath, "w"); if (!outfp) cs_critical_error (ERR_FOPEN_WRITE_FAILED, filepath); bytes_left = file_stat.st_size; bytes_read = CHUNKSIZE; while (bytes_left) { if (bytes_left < CHUNKSIZE) bytes_read = bytes_left; if (fread (buffer, bytes_read, 1, infp) != 1) { cs_critical_error (ERR_FREAD_FAILED, "write cgi file failed"); } bytes_left -= bytes_read; if (fwrite (buffer, bytes_read, 1, outfp) != 1) { cs_critical_error(ERR_FWRITE_FAILED, "write_cgi_file failed"); } } fclose (outfp); #undef CHUNKSIZE } static void run_thumbnailer (const char *bindir) { #define MAX_ARG_SIZE 20 #define MAX_DIMENSION 150 #define MAX_QUALITY 90 char thumbnail_program[MAX_PATH + 1]; char size_arg[MAX_ARG_SIZE + 1]; char quality_arg[MAX_ARG_SIZE + 1]; pid_t pid, status; snprintf(thumbnail_program,MAX_PATH + 1, "%s/jpgtn", bindir); snprintf(size_arg, MAX_ARG_SIZE + 1, "-s %d", MAX_DIMENSION); snprintf(quality_arg, MAX_ARG_SIZE + 1, "-q %d", MAX_QUALITY); if ((pid = fork ()) < 0) cs_critical_error (ERR_CANT_START_NEW_PROCESS, "thum nail function"); if (pid == 0) { /* child process */ execl (thumbnail_program, "jpgtn", "-f", "-pthumb.", size_arg, quality_arg, BIO_ORIG_PIC_FNAME, (char *) 0); exit (1); /* this is returned if above execl() fails */ } /*** parent process */ while (wait (&status) != pid); #undef MAX_ARG_SIZE #undef MAX_DIMENSION #undef MAX_QUALITY } static void replace_photo(const char *bio_dir) { char current_dir[MAX_PATH + 1]; char path[MAX_PATH + 1]; char *filename; FILE *fp; /** was it a *.jpg file? */ filename = hdf_get_value(global_cgi->hdf, "Query.photofile", 0); if(!filename) cs_critical_error(ERR_NO_FILE, "empty upload file"); get_extension(filename,path); /* shared_news_util.c */ if(strcmp(path,"jpg") && strcmp(path,"jpeg") && strcmp(path,"JPG") && strcmp(path,"JPEG")) cs_critical_error(ERR_NOT_JPG_FILE, ""); fp = cgi_filehandle(global_cgi, "photofile"); if(!fp) cs_critical_error(ERR_NO_FILE, "replace_photo()"); /* write the uploaded file to BIO_ORIG_PIC_FNAME in the bio_dir */ snprintf(path, MAX_PATH + 1, "%s/%s", bio_dir, BIO_ORIG_PIC_FNAME); write_cgi_bio_file(fp,path); /* convert uploaded file to thumbnail */ /* get current directory so we can return */ if(!getcwd(current_dir, MAX_PATH + 1)) cs_critical_error(ERR_CANT_GET_CWD, ""); /* make the bio dir the current directory */ if(chdir(bio_dir)) cs_critical_error(ERR_CHDIR_FAILED, ""); //snprintf(command,MAX_PATH + 1, "%s/mkthumb -o -f %d %s", current_dir, MAX_DIMENSION, BIO_ORIG_PIC_FNAME); //snprintf(command,MAX_PATH + 1, "%s/jpgtn -f -pthumb. -s %d %s", current_dir, MAX_DIMENSION, BIO_ORIG_PIC_FNAME); run_thumbnailer(current_dir); //system(command); if(chdir(current_dir)) cs_critical_error(ERR_CHDIR_FAILED, ""); /* delete uploaded file */ unlink(path); } static void delete_photo(const char *bio_dir) { char path[MAX_PATH + 1]; snprintf(path, MAX_PATH + 1, "%s/%s", bio_dir, BIO_PIC_FNAME); unlink(path); } /** values of photo (passed from bio_edit_form program) *** 0 - leave untouched *** 1 - replace photo with file specified *** 2 - delete photo **/ static void handle_photo(int photo, const char *bio_dir) { switch(photo) { case 1: replace_photo(bio_dir); break; case 2: delete_photo(bio_dir); break; case 0: /* same as default - no changes */ default: break; } } static void delete_empty_bio (const char *bio_dir, const char *narrative_path) { char picture_path[MAX_PATH + 1]; unlink(narrative_path); snprintf(picture_path,MAX_PATH + 1, "%s/%s",bio_dir, BIO_PIC_FNAME); if(!file_exists(picture_path)) /* shared_file_util.c */ rmdir(bio_dir); } static void handle_narrative(const char *email, const char *website, const char *bio_dir) { FILE *fp; char path[MAX_PATH + 1]; char *str=0; int i; char label[BIO_MAX_CUSTOM_LABEL + 1]; char content[BIO_MAX_CUSTOM_CONTENT + 1]; char varname[20]; int content_found = 0; snprintf(path,MAX_PATH + 1, "%s/%s",bio_dir, BIO_FNAME); /* first line is email address */ fp = fopen(path, "w"); if(!fp) cs_critical_error(ERR_FOPEN_WRITE_FAILED, ""); get_exclusive_lock(fileno(fp), 1); /* shared_lock.c */ /* first line is email address */ fprintf(fp,"%s\n", email); content_found = strlen(email); /* second line is website */ if(*website && !strstr(website,"://")) fprintf(fp,"http://"); fprintf(fp, "%s\n",website); if(!content_found) content_found = strlen(website); /* get the optional custom entries */ for(i=1; i<=BIO_MAX_CUSTOM_ELEMENTS; i++) { snprintf(varname, 20, "label%d", i); cs_get_optional_parameter(varname, label, BIO_MAX_CUSTOM_LABEL); snprintf(varname, 20, "content%d", i); cs_get_optional_parameter(varname, content, BIO_MAX_CUSTOM_CONTENT); fprintf(fp,"%s\n%s\n", label, content); if(!content_found) content_found = strlen(label) || strlen(content); } hdf_get_copy(global_cgi->hdf, "Query.narrative", &str, ""); if(str && strlen(str)) { content_found = 1; if((strlen(str) < EDITOR_WIDTH) || USE_TEXTAREA_HARD_WRAP) /* custom.h */ fprintf(fp,"%s", str); else write_folded(fp, str, EDITOR_WIDTH); /* shared_fold_file.c */ free(str); } release_lock(fileno(fp)); fclose(fp); if(!content_found) delete_empty_bio(bio_dir, path); } static void create_bio_dir(const char *bio_dir) { if(!file_exists(bio_dir)) mkdir (bio_dir, 0770); } int main () { char course[MAX_PATH + 1]; /* from crs=? form value */ char key[MAX_KEY + 1]; /* from id=? form value */ char target_username[MAX_USERNAME + 1]; /* from user=? form value */ int is_admin; /* from admin=? form value */ char email[MAX_URL + 1]; /* from email=? form value */ char website[MAX_URL + 1]; /* from website=? form value */ int photo; /* from photo=? radio button form value */ SESSION user; CONFIG_STRUCT conf; /* the configuration read from config file */ char bio_dir[MAX_PATH + 1]; cs_cgi_init(); read_parameters (course, key, target_username,&is_admin, email, website, &photo); /* If a course was provided on the form value, read its configuration file. ** Set whether or not we're dealing with a standalone course **/ if(*course) read_configuration_file(course, &conf); /* validate the appropriate key */ if(is_admin) { if(!*course) validate_super_key(key, &user); /* shared_super_util.c */ else validate_key (key, &user, &conf); /* shared_util.c */ } else if(!*course) validate_server_key(key, &user); /* shared_util.c */ else validate_key (key, &user, &conf); /* shared_util.c */ if(!bio_edit_allowed(&user,target_username, course, &conf)) /* shared_bio.c */ cs_critical_error (ERR_REQUEST_DENIED, ""); /* bio info is either stored in ../users/x/username/bio or, for standalone courses in ** course_dir/people/username/bio */ get_bio_dir(course, &conf, target_username, bio_dir); /* shared_bio.c */ /** try to create the bio directory if it doesn't already exist **/ create_bio_dir(bio_dir); handle_photo(photo, bio_dir); handle_narrative(email, website,bio_dir); /* return to bio_view page */ printf("Location: %s?id=%s&user=%s", "bio_view",key,target_username); if(is_admin) printf("&admin=1"); if(*course) printf("&crs=%s",course); printf("&edit=1\n\n"); cs_cgi_destroy(); return 0; /* exit successfully */ }