static int pwm_backlight_ofdata_to_platdata(struct udevice *dev) { struct pwm_backlight_priv *priv = dev_get_priv(dev); struct ofnode_phandle_args args; int index, ret, count, len; const u32 *cell; log_debug("start\n"); ret = uclass_get_device_by_phandle(UCLASS_REGULATOR, dev, "power-supply", &priv->reg); if (ret) log_debug("Cannot get power supply: ret=%d\n", ret); ret = gpio_request_by_name(dev, "enable-gpios", 0, &priv->enable, GPIOD_IS_OUT); if (ret) { log_debug("Warning: cannot get enable GPIO: ret=%d\n", ret); if (ret != -ENOENT) return log_ret(ret); } ret = dev_read_phandle_with_args(dev, "pwms", "#pwm-cells", 0, 0, &args); if (ret) { log_debug("Cannot get PWM phandle: ret=%d\n", ret); return log_ret(ret); } ret = uclass_get_device_by_ofnode(UCLASS_PWM, args.node, &priv->pwm); if (ret) { log_debug("Cannot get PWM: ret=%d\n", ret); return log_ret(ret); } if (args.args_count < 2) return log_msg_ret("Not enough arguments to pwm\n", -EINVAL); priv->channel = args.args[0]; priv->period_ns = args.args[1]; if (args.args_count > 2) priv->polarity = args.args[2]; index = dev_read_u32_default(dev, "default-brightness-level", 255); cell = dev_read_prop(dev, "brightness-levels", &len); count = len / sizeof(u32); if (cell && count > index) { priv->levels = malloc(len); if (!priv->levels) return log_ret(-ENOMEM); dev_read_u32_array(dev, "brightness-levels", priv->levels, count); priv->num_levels = count; priv->default_level = priv->levels[index]; priv->max_level = priv->levels[count - 1]; } else { priv->default_level = index; priv->max_level = 255; } priv->cur_level = priv->default_level; log_debug("done\n"); return 0; }
static int simple_panel_ofdata_to_platdata(struct udevice *dev) { struct simple_panel_priv *priv = dev_get_priv(dev); int ret; if (IS_ENABLED(CONFIG_DM_REGULATOR)) { ret = uclass_get_device_by_phandle(UCLASS_REGULATOR, dev, "power-supply", &priv->reg); if (ret) { debug("%s: Warning: cannot get power supply: ret=%d\n", __func__, ret); if (ret != -ENOENT) return ret; } } ret = uclass_get_device_by_phandle(UCLASS_PANEL_BACKLIGHT, dev, "backlight", &priv->backlight); if (ret) { debug("%s: Cannot get backlight: ret=%d\n", __func__, ret); return log_ret(ret); } ret = gpio_request_by_name(dev, "enable-gpios", 0, &priv->enable, GPIOD_IS_OUT); if (ret) { debug("%s: Warning: cannot get enable GPIO: ret=%d\n", __func__, ret); if (ret != -ENOENT) return log_ret(ret); } return 0; }
static int pwm_backlight_set_brightness(struct udevice *dev, int percent) { struct pwm_backlight_priv *priv = dev_get_priv(dev); bool disable = false; int level; int ret; if (!priv->enabled) { ret = enable_sequence(dev, 0); if (ret) return log_ret(ret); } if (percent == BACKLIGHT_OFF) { disable = true; percent = 0; } if (percent == BACKLIGHT_DEFAULT) { level = priv->default_level; } else { if (priv->levels) { level = priv->levels[percent * (priv->num_levels - 1) / 100]; } else { level = priv->min_level + (priv->max_level - priv->min_level) * percent / 100; } } priv->cur_level = level; ret = set_pwm(priv); if (ret) return log_ret(ret); if (!priv->enabled) { ret = enable_sequence(dev, 1); if (ret) return log_ret(ret); priv->enabled = true; } if (disable) { dm_gpio_set_value(&priv->enable, 0); if (priv->reg) { ret = regulator_set_enable(priv->reg, false); if (ret) return log_ret(ret); } priv->enabled = false; } return 0; }
static int set_pwm(struct pwm_backlight_priv *priv) { uint duty_cycle; int ret; duty_cycle = priv->period_ns * (priv->cur_level - priv->min_level) / (priv->max_level - priv->min_level + 1); ret = pwm_set_config(priv->pwm, priv->channel, priv->period_ns, duty_cycle); if (ret) return log_ret(ret); ret = pwm_set_invert(priv->pwm, priv->channel, priv->polarity); return log_ret(ret); }
HRESULT WINAPI my_CreateDXGIFactory1( REFIID riid, void **ppFactory ) { log_frame( "dxgi", u::info ) << u::endh; HRESULT result = (*stub_CreateDXGIFactory1)(riid, ppFactory); frame << log_ret(result); return result; }
static int enable_sequence(struct udevice *dev, int seq) { struct pwm_backlight_priv *priv = dev_get_priv(dev); int ret; switch (seq) { case 0: if (priv->reg) { __maybe_unused struct dm_regulator_uclass_platdata *plat; plat = dev_get_uclass_platdata(priv->reg); log_debug("Enable '%s', regulator '%s'/'%s'\n", dev->name, priv->reg->name, plat->name); ret = regulator_set_enable(priv->reg, true); if (ret) { log_debug("Cannot enable regulator for PWM '%s'\n", dev->name); return log_ret(ret); } mdelay(120); } break; case 1: mdelay(10); dm_gpio_set_value(&priv->enable, 1); break; } return 0; }
static int spi_flash_std_read(struct udevice *dev, u32 offset, size_t len, void *buf) { struct spi_flash *flash = dev_get_uclass_priv(dev); return log_ret(spi_flash_cmd_read_ops(flash, offset, len, buf)); }
BOOL WINAPI my_UpdateLayeredWindow( HWND hwnd, HDC hdcDst, POINT *pptDst, SIZE *psize, HDC hdcSrc, POINT *pptSrc, COLORREF crKey, BLENDFUNCTION *pblend, DWORD dwFlags ) { log_frame( "gdi", u::info ) << log_var(hwnd) << u::endh; BOOL result = (*stub_UpdateLayeredWindow)( hwnd, hdcDst, pptDst, psize, hdcSrc, pptSrc, crKey, pblend, dwFlags ); frame << log_ret(result); return result; }
HRESULT STDMETHODCALLTYPE my_CreateSwapChain( IDXGIFactory* This, IUnknown* ifDevice, DXGI_SWAP_CHAIN_DESC* pdesc, IDXGISwapChain** ppSwapChain ) { log_frame( "dxgi", u::info ) << log_var(ifDevice) << log_var(pdesc->OutputWindow) << log_var(pdesc->BufferCount) << log_var(pdesc->BufferDesc.Width) << log_var(pdesc->BufferDesc.Height) << u::endh; HRESULT result = (*stub_CreateSwapChain)( This, ifDevice, pdesc, ppSwapChain ); frame << log_ret(result); return result; }
void handle_alrm(void) { log_ret("printer not responding"); sleep(60); /* it will take at least this long to warm up */ exit(EXIT_REPRINT); }
HDC WINAPI my_GetDC( HWND hwnd ) { log_frame( "user", u::info ) << log_var(hwnd) << u::endh; HDC hdc = (*stub_GetDC)( hwnd ); frame << log_ret(hdc); return hdc; }
int WINAPI my_ReleaseDC( HWND hwnd, HDC hdc ) { log_frame( "user", u::info ) << log_var(hwnd) << log_var(hdc) << u::endh; int result = (*stub_ReleaseDC)( hwnd, hdc ); frame << log_ret(result); return result; }
static int spi_flash_std_read(struct udevice *dev, u32 offset, size_t len, void *buf) { struct spi_flash *flash = dev_get_uclass_priv(dev); struct mtd_info *mtd = &flash->mtd; size_t retlen; return log_ret(mtd->_read(mtd, offset, len, &retlen, buf)); }
int WINAPI my_BitBlt( HDC hdc, int x, int y, int cx, int cy, HDC hdcSrc, int x1, int y1, DWORD rop ) { log_frame( "gdi", u::info ) << log_var(hdc) << log_var(x) << log_var(y) << log_var(cx) << log_var(cy) << log_var(rop) << u::endh; BOOL result = (*stub_BitBlt)( hdc, x, y, cx, cy, hdcSrc, x1, y1, rop ); frame << log_ret(result); return result; }
HRESULT STDMETHODCALLTYPE my_CreateSwapChainForHwnd( IDXGIFactory2* This, IUnknown* pDevice, HWND hWnd, const DXGI_SWAP_CHAIN_DESC1* pDesc, const DXGI_SWAP_CHAIN_FULLSCREEN_DESC* pFullscreenDesc, IDXGIOutput* pRestrictToOutput, IDXGISwapChain1** ppSwapChain ) { log_frame( "dxgi", u::info ) << log_var(pDevice) << log_var(hWnd) << log_var(pDesc->Width) << log_var(pDesc->Height) << log_var(pDesc->BufferCount) << u::endh; HRESULT result = (*stub_CreateSwapChainForHwnd)( This, pDevice, hWnd, pDesc, pFullscreenDesc, pRestrictToOutput, ppSwapChain ); frame << log_var(*ppSwapChain) << log_ret(result); return result; }
static int pwm_backlight_enable(struct udevice *dev) { struct pwm_backlight_priv *priv = dev_get_priv(dev); int ret; ret = enable_sequence(dev, 0); if (ret) return log_ret(ret); ret = set_pwm(priv); if (ret) return log_ret(ret); ret = pwm_set_enable(priv->pwm, priv->channel, true); if (ret) return log_ret(ret); ret = enable_sequence(dev, 1); if (ret) return log_ret(ret); priv->enabled = true; return 0; }
HRESULT STDMETHODCALLTYPE my_CreateBitmapFromWicBitmap( ID2D1RenderTarget* This, IWICBitmapSource* wicBitmapSource, const D2D1_BITMAP_PROPERTIES* bitmapProperties, ID2D1Bitmap** bitmap ) { log_frame( "d2d1", u::info ) << log_var(This) << log_var(wicBitmapSource); double dpix, dpiy; UINT width, height; wicBitmapSource->GetResolution( &dpix, &dpiy ); wicBitmapSource->GetSize( &width, &height ); frame << log_var(dpix) << log_var(dpiy) << log_var(width) << log_var(height) << u::endh; HRESULT result = (*stub_CreateBitmapFromWicBitmap)( This, wicBitmapSource, bitmapProperties, bitmap ); frame << log_var(*bitmap) << log_ret(result); return result; }
HRESULT STDMETHODCALLTYPE my_Present( IDXGISwapChain* This, UINT SyncInterval, UINT Flags ) { log_frame( "dxgi", u::info ) << log_var(This) << u::endh; HRESULT hr; DXGI_SWAP_CHAIN_DESC desc; hr = This->GetDesc( &desc ); frame << log_var(desc.BufferDesc.Width) << log_var(desc.BufferDesc.Height) << log_var(desc.OutputWindow); CComPtr<IDXGIDevice> dxgiDevice; hr = This->GetDevice( __uuidof(IDXGIDevice), (void**)&dxgiDevice ); frame << log_var(dxgiDevice); HRESULT result = stub_Present(This, SyncInterval, Flags ); frame << log_ret(result); return result; }
HRESULT STDMETHODCALLTYPE my_CreateWicBitmapRenderTarget( ID2D1Factory* This, IWICBitmap* target, const D2D1_RENDER_TARGET_PROPERTIES *renderTargetProperties, ID2D1RenderTarget** renderTarget ) { log_frame( "d2d1", u::info ) << log_var(This) << log_var(target) << u::endh; // Some data about the bitmap UINT width, height; double dpix, dpiy; target->GetSize( &width, &height ); target->GetResolution( &dpix, &dpiy ); frame << log_var(width) << log_var(height); frame << log_var(dpix) << log_var(dpiy); HRESULT result = (*stub_CreateWicBitmapRenderTarget)( This, target, renderTargetProperties, renderTarget ); frame << log_var(*renderTarget) << log_ret(result); return result; }
LRESULT WINAPI my_DispatchMessage( const MSG *pmsg ) { log_frame( "user", u::info ) << log_var(pmsg->hwnd) << log_var_f(pmsg->message, "%x") << u::endh; LRESULT result = (*stub_DispatchMessage)(pmsg); if( pmsg->message == 0x401 ) { CPlug* pplug = CPlug::inst(); if( pplug ) { CSubclsWnd* pwnd = pplug->getSubclsWnd(); if( pwnd ) { //CPlug::inst()->getSubclsWnd()->highlight(); } } } frame << log_ret(result); return result; }
/* * Add a worker to the list of worker threads. * * LOCKING: acquires and releases workerlock. */ void add_worker(pthread_t tid, int sockfd) { struct worker_thread *wtp; if ((wtp = malloc(sizeof(struct worker_thread))) == NULL) { log_ret("add_worker: can't malloc"); pthread_exit((void *)1); } wtp->tid = tid; wtp->sockfd = sockfd; pthread_mutex_lock(&workerlock); wtp->prev = NULL; wtp->next = workers; if (workers == NULL) workers = wtp; else workers->prev = wtp; pthread_mutex_unlock(&workerlock); }
HRESULT STDMETHODCALLTYPE my_Present1( IDXGISwapChain1* This, UINT SyncInterval, UINT PresentFlags, const DXGI_PRESENT_PARAMETERS *pPresentParameters ) { log_frame( "dxgi", u::info ) << log_var(This) << u::endh; HRESULT hr; DXGI_SWAP_CHAIN_DESC1 desc; hr = This->GetDesc1( &desc ); frame << log_var(desc.Width) << log_var(desc.Height); HWND hwnd; hr = This->GetHwnd( &hwnd ); frame << log_var(hwnd); CComPtr<IDXGIDevice> dxgiDevice; hr = This->GetDevice( __uuidof(IDXGIDevice), (void**)&dxgiDevice ); frame << log_var(dxgiDevice); HRESULT result = (*stub_Present1)(This, SyncInterval, PresentFlags, pPresentParameters ); frame << log_ret(result); return result; }
int ofnode_read_fmap_entry(ofnode node, struct fmap_entry *entry) { const char *prop; u32 reg[2]; if (ofnode_read_u32_array(node, "reg", reg, 2)) { debug("Node '%s' has bad/missing 'reg' property\n", ofnode_get_name(node)); return -log_ret(ENOENT); } entry->offset = reg[0]; entry->length = reg[1]; entry->used = ofnode_read_s32_default(node, "used", entry->length); prop = ofnode_read_string(node, "compress"); entry->compress_algo = prop && !strcmp(prop, "lzo") ? FMAP_COMPRESS_LZO : FMAP_COMPRESS_NONE; prop = ofnode_read_string(node, "hash"); if (prop) entry->hash_size = strlen(prop); entry->hash_algo = prop ? FMAP_HASH_SHA256 : FMAP_HASH_NONE; entry->hash = (uint8_t *)prop; return 0; }
/* * Main print server thread. Accepts connect requests from * clients and spawns additional threads to service requests. * * LOCKING: none. */ int main(int argc, char *argv[]) { pthread_t tid; struct addrinfo *ailist, *aip; int sockfd, err, i, n, maxfd; char *host; fd_set rendezvous, rset; struct sigaction sa; struct passwd *pwdp; if (argc != 1) err_quit("usage: printd"); daemonize("printd"); sigemptyset(&sa.sa_mask); sa.sa_flags = 0; sa.sa_handler = SIG_IGN; if (sigaction(SIGPIPE, &sa, NULL) < 0) log_sys("sigaction failed"); sigemptyset(&mask); sigaddset(&mask, SIGHUP); sigaddset(&mask, SIGTERM); if ((err = pthread_sigmask(SIG_BLOCK, &mask, NULL)) != 0) log_sys("pthread_sigmask failed"); n = sysconf(_SC_HOST_NAME_MAX); if (n < 0) /* best guess */ n = HOST_NAME_MAX; if ((host = malloc(n)) == NULL) log_sys("malloc error"); if (gethostname(host, n) < 0) log_sys("gethostname error"); if ((err = getaddrlist(host, "print", &ailist)) != 0) { log_quit("getaddrinfo error: %s", gai_strerror(err)); exit(1); } FD_ZERO(&rendezvous); maxfd = -1; for (aip = ailist; aip != NULL; aip = aip->ai_next) { if ((sockfd = initserver(SOCK_STREAM, aip->ai_addr, aip->ai_addrlen, QLEN)) >= 0) { FD_SET(sockfd, &rendezvous); if (sockfd > maxfd) maxfd = sockfd; } } if (maxfd == -1) log_quit("service not enabled"); pwdp = getpwnam(LPNAME); if (pwdp == NULL) log_sys("can't find user %s", LPNAME); if (pwdp->pw_uid == 0) log_quit("user %s is privileged", LPNAME); if (setgid(pwdp->pw_gid) < 0 || setuid(pwdp->pw_uid) < 0) log_sys("can't change IDs to user %s", LPNAME); init_request(); init_printer(); err = pthread_create(&tid, NULL, printer_thread, NULL); if (err == 0) err = pthread_create(&tid, NULL, signal_thread, NULL); if (err != 0) log_exit(err, "can't create thread"); build_qonstart(); log_msg("daemon initialized"); for (;;) { rset = rendezvous; if (select(maxfd+1, &rset, NULL, NULL, NULL) < 0) log_sys("select failed"); for (i = 0; i <= maxfd; i++) { if (FD_ISSET(i, &rset)) { /* * Accept the connection and handle the request. */ if ((sockfd = accept(i, NULL, NULL)) < 0) log_ret("accept failed"); pthread_create(&tid, NULL, client_thread, (void *)((long)sockfd)); } } } exit(1); }
/* * Single thread to communicate with the printer. * * LOCKING: acquires and releases joblock and configlock. */ void * printer_thread(void *arg) { struct job *jp; int hlen, ilen, sockfd, fd, nr, nw, extra; char *icp, *hcp, *p; struct ipp_hdr *hp; struct stat sbuf; struct iovec iov[2]; char name[FILENMSZ]; char hbuf[HBUFSZ]; char ibuf[IBUFSZ]; char buf[IOBUFSZ]; char str[64]; struct timespec ts = { 60, 0 }; /* 1 minute */ for (;;) { /* * Get a job to print. */ pthread_mutex_lock(&joblock); while (jobhead == NULL) { log_msg("printer_thread: waiting..."); pthread_cond_wait(&jobwait, &joblock); } remove_job(jp = jobhead); log_msg("printer_thread: picked up job %d", jp->jobid); pthread_mutex_unlock(&joblock); update_jobno(); /* * Check for a change in the config file. */ pthread_mutex_lock(&configlock); if (reread) { freeaddrinfo(printer); printer = NULL; printer_name = NULL; reread = 0; pthread_mutex_unlock(&configlock); init_printer(); } else { pthread_mutex_unlock(&configlock); } /* * Send job to printer. */ sprintf(name, "%s/%s/%d", SPOOLDIR, DATADIR, jp->jobid); if ((fd = open(name, O_RDONLY)) < 0) { log_msg("job %d canceled - can't open %s: %s", jp->jobid, name, strerror(errno)); free(jp); continue; } if (fstat(fd, &sbuf) < 0) { log_msg("job %d canceled - can't fstat %s: %s", jp->jobid, name, strerror(errno)); free(jp); close(fd); continue; } if ((sockfd = connect_retry(AF_INET, SOCK_STREAM, 0, printer->ai_addr, printer->ai_addrlen)) < 0) { log_msg("job %d deferred - can't contact printer: %s", jp->jobid, strerror(errno)); goto defer; } /* * Set up the IPP header. */ icp = ibuf; hp = (struct ipp_hdr *)icp; hp->major_version = 1; hp->minor_version = 1; hp->operation = htons(OP_PRINT_JOB); hp->request_id = htonl(jp->jobid); icp += offsetof(struct ipp_hdr, attr_group); *icp++ = TAG_OPERATION_ATTR; icp = add_option(icp, TAG_CHARSET, "attributes-charset", "utf-8"); icp = add_option(icp, TAG_NATULANG, "attributes-natural-language", "en-us"); sprintf(str, "http://%s/ipp", printer_name); icp = add_option(icp, TAG_URI, "printer-uri", str); icp = add_option(icp, TAG_NAMEWOLANG, "requesting-user-name", jp->req.usernm); icp = add_option(icp, TAG_NAMEWOLANG, "job-name", jp->req.jobnm); if (jp->req.flags & PR_TEXT) { p = "text/plain"; extra = 1; } else { p = "application/postscript"; extra = 0; } icp = add_option(icp, TAG_MIMETYPE, "document-format", p); *icp++ = TAG_END_OF_ATTR; ilen = icp - ibuf; /* * Set up the HTTP header. */ hcp = hbuf; sprintf(hcp, "POST /ipp HTTP/1.1\r\n"); hcp += strlen(hcp); sprintf(hcp, "Content-Length: %ld\r\n", (long)sbuf.st_size + ilen + extra); hcp += strlen(hcp); strcpy(hcp, "Content-Type: application/ipp\r\n"); hcp += strlen(hcp); sprintf(hcp, "Host: %s:%d\r\n", printer_name, IPP_PORT); hcp += strlen(hcp); *hcp++ = '\r'; *hcp++ = '\n'; hlen = hcp - hbuf; /* * Write the headers first. Then send the file. */ iov[0].iov_base = hbuf; iov[0].iov_len = hlen; iov[1].iov_base = ibuf; iov[1].iov_len = ilen; if (writev(sockfd, iov, 2) != hlen + ilen) { log_ret("can't write to printer"); goto defer; } if (jp->req.flags & PR_TEXT) { /* * Hack: allow PostScript to be printed as plain text. */ if (write(sockfd, "\b", 1) != 1) { log_ret("can't write to printer"); goto defer; } } while ((nr = read(fd, buf, IOBUFSZ)) > 0) { if ((nw = writen(sockfd, buf, nr)) != nr) { if (nw < 0) log_ret("can't write to printer"); else log_msg("short write (%d/%d) to printer", nw, nr); goto defer; } } if (nr < 0) { log_ret("can't read %s", name); goto defer; } /* * Read the response from the printer. */ if (printer_status(sockfd, jp)) { unlink(name); sprintf(name, "%s/%s/%d", SPOOLDIR, REQDIR, jp->jobid); unlink(name); free(jp); jp = NULL; } defer: close(fd); if (sockfd >= 0) close(sockfd); if (jp != NULL) { replace_job(jp); nanosleep(&ts, NULL); } } }
// download file from the slave server. void *download_thread(void *arg) { transmit_arg *down_arg = (transmit_arg*)arg; // open the download file to write. FILE *p_file; if((p_file = fopen(down_arg->file_name, "w")) == NULL) { close(down_arg->sockfd); SSL_free(down_arg->ssl); delete down_arg; printf("download_thread: open %s for write unsuccessfully", down_arg->file_name); return NULL; } SSL_write(down_arg->ssl, "OK", strlen("OK")); char str_buf[MAXBUF]; int nread; long long download_bytes = 0; int k = 0; while(true) { if((nread = SSL_read(down_arg->ssl, str_buf, MAXBUF)) < 0) { if(errno == EINTR) continue; else { log_ret("download_thread: SSL_read error"); fclose(p_file); SSL_shutdown(down_arg->ssl); close(down_arg->sockfd); SSL_free(down_arg->ssl); delete down_arg; } } if(nread == 0) //connection to the client was broken. break; fwrite(str_buf, sizeof(char), nread, p_file); download_bytes += nread; // every ten times writing to the file, record the bytes already downloaded in the download array. if( ++k == 20) { k = 0; pthread_mutex_lock(&download_mutex); down_arg->iter->second.current = download_bytes; pthread_mutex_unlock(&download_mutex); } } // last time updating the size downloaded. pthread_mutex_lock(&download_mutex); down_arg->iter->second.current = download_bytes; pthread_mutex_unlock(&download_mutex); // close the socket descriptor, the SSL, and free the memory. SSL_shutdown(down_arg->ssl); close(down_arg->sockfd); SSL_free(down_arg->ssl); // whether download successfully, or not. bool success; pthread_mutex_lock(&download_mutex); success = (down_arg->iter->second.current == down_arg->iter->second.sum); download_array.erase(down_arg->iter); pthread_mutex_unlock(&download_mutex); if(success) { if(!status_query) printf("%s download successfully.\n", down_arg->file_name); } else { if(!status_query) printf("%s download unsuccessfully.\n", down_arg->file_name); unlink(down_arg->file_name); } delete down_arg; return NULL; }
int spi_flash_erase_dm(struct udevice *dev, u32 offset, size_t len) { return log_ret(sf_get_ops(dev)->erase(dev, offset, len)); }
int spi_flash_write_dm(struct udevice *dev, u32 offset, size_t len, const void *buf) { return log_ret(sf_get_ops(dev)->write(dev, offset, len, buf)); }
int spi_flash_read_dm(struct udevice *dev, u32 offset, size_t len, void *buf) { return log_ret(sf_get_ops(dev)->read(dev, offset, len, buf)); }
void *backup_thread(void *arg) { // get the socket descriptor and free the allocated memory. int backupfd = *(int *)arg; free(arg); char command_line[MAXLINE + 1]; int n = read(backupfd, command_line, MAXLINE); if(n < 0) { close(backupfd); log_msg("backup_thread: read error"); return NULL; } command_line[n] = '\0'; // parse the command line char file_name[MAXLINE], user_name[MAXLINE]; long long upload_bytes; n = sscanf(command_line, "%s%s%lld", file_name, user_name, &upload_bytes); if(n != 2) { close(backupfd); log_msg("backup_thread: parse the command line error"); return NULL; } char file[MAXBUF]; // establish the directory to store files of the client. snprintf(file, MAXBUF, "%s/%s/", store_dir, user_name); log_msg("backup_thread: file directory %s", file); if(mkdir(file, DIR_MODE) < 0) { if(errno != EEXIST) { close(backupfd); log_ret("backup_thread: mkdir error"); return NULL; } } strcat(file, file_name); log_msg("upload_thread: file name %s", file); // open the backup file to write. FILE *p_file; if((p_file = fopen(file, "w")) == NULL) { close(backupfd); log_msg("upload_thread: open %s for write unsuccessfully", file); return NULL; } n = writen(backupfd, "OK", strlen("OK")); if(n != strlen("OK")) { close(backupfd); fclose(p_file); return NULL; } int nread; // in the process of backing up file // add the backup job to the backup array. pthread_mutex_lock(&backup_mutex); backup_array.insert((const char *)command_line); pthread_mutex_unlock(&backup_mutex); char str_buf[MAXBUF + 1]; // start backing up. while(true) { if((nread = read(backupfd, str_buf, MAXBUF)) < 0) { if(errno == EINTR) continue; else { log_ret("backup_thread: read error"); unlink(file); fclose(p_file); close(backupfd); } } else if(nread == 0) //connection to the client was broken. break; fwrite(str_buf, sizeof(char), nread, p_file); upload_bytes -= nread; } if(upload_bytes != 0) { unlink(file); fclose(p_file); close(backupfd); log_msg("backup_thread: file size not equal: upload_bytes %lld", upload_bytes); return NULL; } //erase the backup job from the backup array. pthread_mutex_lock(&backup_mutex); backup_array.erase((const char *)command_line); pthread_mutex_unlock(&backup_mutex); close(backupfd); fclose(p_file); log_msg("backup_thread: backup successfully"); return NULL; }